early-access version 1255
This commit is contained in:
30
src/core/hle/service/hid/controllers/controller_base.cpp
Executable file
30
src/core/hle/service/hid/controllers/controller_base.cpp
Executable file
@@ -0,0 +1,30 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
ControllerBase::ControllerBase(Core::System& system) : system(system) {}
|
||||
ControllerBase::~ControllerBase() = default;
|
||||
|
||||
void ControllerBase::ActivateController() {
|
||||
if (is_activated) {
|
||||
OnRelease();
|
||||
}
|
||||
is_activated = true;
|
||||
OnInit();
|
||||
}
|
||||
|
||||
void ControllerBase::DeactivateController() {
|
||||
if (is_activated) {
|
||||
OnRelease();
|
||||
}
|
||||
is_activated = false;
|
||||
}
|
||||
|
||||
bool ControllerBase::IsControllerActivated() const {
|
||||
return is_activated;
|
||||
}
|
||||
} // namespace Service::HID
|
60
src/core/hle/service/hid/controllers/controller_base.h
Executable file
60
src/core/hle/service/hid/controllers/controller_base.h
Executable file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/swap.h"
|
||||
|
||||
namespace Core::Timing {
|
||||
class CoreTiming;
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::HID {
|
||||
class ControllerBase {
|
||||
public:
|
||||
explicit ControllerBase(Core::System& system);
|
||||
virtual ~ControllerBase();
|
||||
|
||||
// Called when the controller is initialized
|
||||
virtual void OnInit() = 0;
|
||||
|
||||
// When the controller is released
|
||||
virtual void OnRelease() = 0;
|
||||
|
||||
// When the controller is requesting an update for the shared memory
|
||||
virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
||||
std::size_t size) = 0;
|
||||
|
||||
// When the controller is requesting a motion update for the shared memory
|
||||
virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
||||
std::size_t size) {}
|
||||
|
||||
// Called when input devices should be loaded
|
||||
virtual void OnLoadInputDevices() = 0;
|
||||
|
||||
void ActivateController();
|
||||
|
||||
void DeactivateController();
|
||||
|
||||
bool IsControllerActivated() const;
|
||||
|
||||
protected:
|
||||
bool is_activated{false};
|
||||
|
||||
struct CommonHeader {
|
||||
s64_le timestamp;
|
||||
s64_le total_entry_count;
|
||||
s64_le last_entry_index;
|
||||
s64_le entry_count;
|
||||
};
|
||||
static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
|
||||
|
||||
Core::System& system;
|
||||
};
|
||||
} // namespace Service::HID
|
85
src/core/hle/service/hid/controllers/debug_pad.cpp
Executable file
85
src/core/hle/service/hid/controllers/debug_pad.cpp
Executable file
@@ -0,0 +1,85 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cstring>
|
||||
#include "common/common_types.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hle/service/hid/controllers/debug_pad.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
|
||||
[[maybe_unused]] constexpr s32 HID_JOYSTICK_MIN = -0x7fff;
|
||||
enum class JoystickId : std::size_t { Joystick_Left, Joystick_Right };
|
||||
|
||||
Controller_DebugPad::Controller_DebugPad(Core::System& system) : ControllerBase(system) {}
|
||||
Controller_DebugPad::~Controller_DebugPad() = default;
|
||||
|
||||
void Controller_DebugPad::OnInit() {}
|
||||
|
||||
void Controller_DebugPad::OnRelease() {}
|
||||
|
||||
void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
||||
std::size_t size) {
|
||||
shared_memory.header.timestamp = core_timing.GetCPUTicks();
|
||||
shared_memory.header.total_entry_count = 17;
|
||||
|
||||
if (!IsControllerActivated()) {
|
||||
shared_memory.header.entry_count = 0;
|
||||
shared_memory.header.last_entry_index = 0;
|
||||
return;
|
||||
}
|
||||
shared_memory.header.entry_count = 16;
|
||||
|
||||
const auto& last_entry = shared_memory.pad_states[shared_memory.header.last_entry_index];
|
||||
shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17;
|
||||
auto& cur_entry = shared_memory.pad_states[shared_memory.header.last_entry_index];
|
||||
|
||||
cur_entry.sampling_number = last_entry.sampling_number + 1;
|
||||
cur_entry.sampling_number2 = cur_entry.sampling_number;
|
||||
|
||||
if (Settings::values.debug_pad_enabled) {
|
||||
cur_entry.attribute.connected.Assign(1);
|
||||
auto& pad = cur_entry.pad_state;
|
||||
|
||||
using namespace Settings::NativeButton;
|
||||
pad.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus());
|
||||
pad.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus());
|
||||
pad.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus());
|
||||
pad.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus());
|
||||
pad.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus());
|
||||
pad.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus());
|
||||
pad.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus());
|
||||
pad.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus());
|
||||
pad.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus());
|
||||
pad.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus());
|
||||
pad.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus());
|
||||
pad.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus());
|
||||
pad.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus());
|
||||
pad.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus());
|
||||
|
||||
const auto [stick_l_x_f, stick_l_y_f] =
|
||||
analogs[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetStatus();
|
||||
const auto [stick_r_x_f, stick_r_y_f] =
|
||||
analogs[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus();
|
||||
cur_entry.l_stick.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX);
|
||||
cur_entry.l_stick.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX);
|
||||
cur_entry.r_stick.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX);
|
||||
cur_entry.r_stick.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX);
|
||||
}
|
||||
|
||||
std::memcpy(data, &shared_memory, sizeof(SharedMemory));
|
||||
}
|
||||
|
||||
void Controller_DebugPad::OnLoadInputDevices() {
|
||||
std::transform(Settings::values.debug_pad_buttons.begin(),
|
||||
Settings::values.debug_pad_buttons.begin() +
|
||||
Settings::NativeButton::NUM_BUTTONS_HID,
|
||||
buttons.begin(), Input::CreateDevice<Input::ButtonDevice>);
|
||||
std::transform(Settings::values.debug_pad_analogs.begin(),
|
||||
Settings::values.debug_pad_analogs.end(), analogs.begin(),
|
||||
Input::CreateDevice<Input::AnalogDevice>);
|
||||
}
|
||||
} // namespace Service::HID
|
93
src/core/hle/service/hid/controllers/debug_pad.h
Executable file
93
src/core/hle/service/hid/controllers/debug_pad.h
Executable file
@@ -0,0 +1,93 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/frontend/input.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
namespace Service::HID {
|
||||
class Controller_DebugPad final : public ControllerBase {
|
||||
public:
|
||||
explicit Controller_DebugPad(Core::System& system);
|
||||
~Controller_DebugPad() 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, u8* data, std::size_t size) override;
|
||||
|
||||
// Called when input devices should be loaded
|
||||
void OnLoadInputDevices() override;
|
||||
|
||||
private:
|
||||
struct AnalogStick {
|
||||
s32_le x;
|
||||
s32_le y;
|
||||
};
|
||||
static_assert(sizeof(AnalogStick) == 0x8);
|
||||
|
||||
struct PadState {
|
||||
union {
|
||||
u32_le raw{};
|
||||
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;
|
||||
BitField<5, 1, u32> r;
|
||||
BitField<6, 1, u32> zl;
|
||||
BitField<7, 1, u32> zr;
|
||||
BitField<8, 1, u32> plus;
|
||||
BitField<9, 1, u32> minus;
|
||||
BitField<10, 1, u32> d_left;
|
||||
BitField<11, 1, u32> d_up;
|
||||
BitField<12, 1, u32> d_right;
|
||||
BitField<13, 1, u32> d_down;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(PadState) == 0x4, "PadState is an invalid size");
|
||||
|
||||
struct Attributes {
|
||||
union {
|
||||
u32_le raw{};
|
||||
BitField<0, 1, u32> connected;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size");
|
||||
|
||||
struct PadStates {
|
||||
s64_le sampling_number;
|
||||
s64_le sampling_number2;
|
||||
Attributes attribute;
|
||||
PadState pad_state;
|
||||
AnalogStick r_stick;
|
||||
AnalogStick l_stick;
|
||||
};
|
||||
static_assert(sizeof(PadStates) == 0x28, "PadStates is an invalid state");
|
||||
|
||||
struct SharedMemory {
|
||||
CommonHeader header;
|
||||
std::array<PadStates, 17> pad_states;
|
||||
INSERT_PADDING_BYTES(0x138);
|
||||
};
|
||||
static_assert(sizeof(SharedMemory) == 0x400, "SharedMemory is an invalid size");
|
||||
SharedMemory shared_memory{};
|
||||
|
||||
std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>
|
||||
buttons;
|
||||
std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID>
|
||||
analogs;
|
||||
};
|
||||
} // namespace Service::HID
|
44
src/core/hle/service/hid/controllers/gesture.cpp
Executable file
44
src/core/hle/service/hid/controllers/gesture.cpp
Executable file
@@ -0,0 +1,44 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cstring>
|
||||
#include "common/common_types.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hle/service/hid/controllers/gesture.h"
|
||||
|
||||
namespace Service::HID {
|
||||
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3BA00;
|
||||
|
||||
Controller_Gesture::Controller_Gesture(Core::System& system) : ControllerBase(system) {}
|
||||
Controller_Gesture::~Controller_Gesture() = default;
|
||||
|
||||
void Controller_Gesture::OnInit() {}
|
||||
|
||||
void Controller_Gesture::OnRelease() {}
|
||||
|
||||
void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
||||
std::size_t size) {
|
||||
shared_memory.header.timestamp = core_timing.GetCPUTicks();
|
||||
shared_memory.header.total_entry_count = 17;
|
||||
|
||||
if (!IsControllerActivated()) {
|
||||
shared_memory.header.entry_count = 0;
|
||||
shared_memory.header.last_entry_index = 0;
|
||||
return;
|
||||
}
|
||||
shared_memory.header.entry_count = 16;
|
||||
|
||||
const auto& last_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
|
||||
shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17;
|
||||
auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
|
||||
|
||||
cur_entry.sampling_number = last_entry.sampling_number + 1;
|
||||
cur_entry.sampling_number2 = cur_entry.sampling_number;
|
||||
// TODO(ogniK): Update gesture states
|
||||
|
||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
|
||||
}
|
||||
|
||||
void Controller_Gesture::OnLoadInputDevices() {}
|
||||
} // namespace Service::HID
|
63
src/core/hle/service/hid/controllers/gesture.h
Executable file
63
src/core/hle/service/hid/controllers/gesture.h
Executable file
@@ -0,0 +1,63 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include "common/common_types.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
|
||||
namespace Service::HID {
|
||||
class Controller_Gesture final : public ControllerBase {
|
||||
public:
|
||||
explicit Controller_Gesture(Core::System& system);
|
||||
~Controller_Gesture() 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, u8* data, size_t size) override;
|
||||
|
||||
// Called when input devices should be loaded
|
||||
void OnLoadInputDevices() override;
|
||||
|
||||
private:
|
||||
struct Locations {
|
||||
s32_le x;
|
||||
s32_le y;
|
||||
};
|
||||
|
||||
struct GestureState {
|
||||
s64_le sampling_number;
|
||||
s64_le sampling_number2;
|
||||
|
||||
s64_le detection_count;
|
||||
s32_le type;
|
||||
s32_le dir;
|
||||
s32_le x;
|
||||
s32_le y;
|
||||
s32_le delta_x;
|
||||
s32_le delta_y;
|
||||
f32 vel_x;
|
||||
f32 vel_y;
|
||||
s32_le attributes;
|
||||
f32 scale;
|
||||
f32 rotation;
|
||||
s32_le location_count;
|
||||
std::array<Locations, 4> locations;
|
||||
};
|
||||
static_assert(sizeof(GestureState) == 0x68, "GestureState is an invalid size");
|
||||
|
||||
struct SharedMemory {
|
||||
CommonHeader header;
|
||||
std::array<GestureState, 17> gesture_states;
|
||||
};
|
||||
SharedMemory shared_memory{};
|
||||
};
|
||||
} // namespace Service::HID
|
62
src/core/hle/service/hid/controllers/keyboard.cpp
Executable file
62
src/core/hle/service/hid/controllers/keyboard.cpp
Executable file
@@ -0,0 +1,62 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cstring>
|
||||
#include "common/common_types.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hle/service/hid/controllers/keyboard.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
namespace Service::HID {
|
||||
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800;
|
||||
constexpr u8 KEYS_PER_BYTE = 8;
|
||||
|
||||
Controller_Keyboard::Controller_Keyboard(Core::System& system) : ControllerBase(system) {}
|
||||
Controller_Keyboard::~Controller_Keyboard() = default;
|
||||
|
||||
void Controller_Keyboard::OnInit() {}
|
||||
|
||||
void Controller_Keyboard::OnRelease() {}
|
||||
|
||||
void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
||||
std::size_t size) {
|
||||
shared_memory.header.timestamp = core_timing.GetCPUTicks();
|
||||
shared_memory.header.total_entry_count = 17;
|
||||
|
||||
if (!IsControllerActivated()) {
|
||||
shared_memory.header.entry_count = 0;
|
||||
shared_memory.header.last_entry_index = 0;
|
||||
return;
|
||||
}
|
||||
shared_memory.header.entry_count = 16;
|
||||
|
||||
const auto& last_entry = shared_memory.pad_states[shared_memory.header.last_entry_index];
|
||||
shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17;
|
||||
auto& cur_entry = shared_memory.pad_states[shared_memory.header.last_entry_index];
|
||||
|
||||
cur_entry.sampling_number = last_entry.sampling_number + 1;
|
||||
cur_entry.sampling_number2 = cur_entry.sampling_number;
|
||||
|
||||
cur_entry.key.fill(0);
|
||||
cur_entry.modifier = 0;
|
||||
if (Settings::values.keyboard_enabled) {
|
||||
for (std::size_t i = 0; i < keyboard_keys.size(); ++i) {
|
||||
auto& entry = cur_entry.key[i / KEYS_PER_BYTE];
|
||||
entry = static_cast<u8>(entry | (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE)));
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < keyboard_mods.size(); ++i) {
|
||||
cur_entry.modifier |= (keyboard_mods[i]->GetStatus() << i);
|
||||
}
|
||||
}
|
||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
|
||||
}
|
||||
|
||||
void Controller_Keyboard::OnLoadInputDevices() {
|
||||
std::transform(Settings::values.keyboard_keys.begin(), Settings::values.keyboard_keys.end(),
|
||||
keyboard_keys.begin(), Input::CreateDevice<Input::ButtonDevice>);
|
||||
std::transform(Settings::values.keyboard_mods.begin(), Settings::values.keyboard_mods.end(),
|
||||
keyboard_mods.begin(), Input::CreateDevice<Input::ButtonDevice>);
|
||||
}
|
||||
} // namespace Service::HID
|
57
src/core/hle/service/hid/controllers/keyboard.h
Executable file
57
src/core/hle/service/hid/controllers/keyboard.h
Executable file
@@ -0,0 +1,57 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/frontend/input.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
namespace Service::HID {
|
||||
class Controller_Keyboard final : public ControllerBase {
|
||||
public:
|
||||
explicit Controller_Keyboard(Core::System& system);
|
||||
~Controller_Keyboard() 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, u8* data, std::size_t size) override;
|
||||
|
||||
// Called when input devices should be loaded
|
||||
void OnLoadInputDevices() override;
|
||||
|
||||
private:
|
||||
struct KeyboardState {
|
||||
s64_le sampling_number;
|
||||
s64_le sampling_number2;
|
||||
|
||||
s32_le modifier;
|
||||
s32_le attribute;
|
||||
std::array<u8, 32> key;
|
||||
};
|
||||
static_assert(sizeof(KeyboardState) == 0x38, "KeyboardState is an invalid size");
|
||||
|
||||
struct SharedMemory {
|
||||
CommonHeader header;
|
||||
std::array<KeyboardState, 17> pad_states;
|
||||
INSERT_PADDING_BYTES(0x28);
|
||||
};
|
||||
static_assert(sizeof(SharedMemory) == 0x400, "SharedMemory is an invalid size");
|
||||
SharedMemory shared_memory{};
|
||||
|
||||
std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeKeyboard::NumKeyboardKeys>
|
||||
keyboard_keys;
|
||||
std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeKeyboard::NumKeyboardMods>
|
||||
keyboard_mods;
|
||||
};
|
||||
} // namespace Service::HID
|
63
src/core/hle/service/hid/controllers/mouse.cpp
Executable file
63
src/core/hle/service/hid/controllers/mouse.cpp
Executable file
@@ -0,0 +1,63 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cstring>
|
||||
#include "common/common_types.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "core/hle/service/hid/controllers/mouse.h"
|
||||
|
||||
namespace Service::HID {
|
||||
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400;
|
||||
|
||||
Controller_Mouse::Controller_Mouse(Core::System& system) : ControllerBase(system) {}
|
||||
Controller_Mouse::~Controller_Mouse() = default;
|
||||
|
||||
void Controller_Mouse::OnInit() {}
|
||||
void Controller_Mouse::OnRelease() {}
|
||||
|
||||
void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
||||
std::size_t size) {
|
||||
shared_memory.header.timestamp = core_timing.GetCPUTicks();
|
||||
shared_memory.header.total_entry_count = 17;
|
||||
|
||||
if (!IsControllerActivated()) {
|
||||
shared_memory.header.entry_count = 0;
|
||||
shared_memory.header.last_entry_index = 0;
|
||||
return;
|
||||
}
|
||||
shared_memory.header.entry_count = 16;
|
||||
|
||||
auto& last_entry = shared_memory.mouse_states[shared_memory.header.last_entry_index];
|
||||
shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17;
|
||||
auto& cur_entry = shared_memory.mouse_states[shared_memory.header.last_entry_index];
|
||||
|
||||
cur_entry.sampling_number = last_entry.sampling_number + 1;
|
||||
cur_entry.sampling_number2 = cur_entry.sampling_number;
|
||||
|
||||
if (Settings::values.mouse_enabled) {
|
||||
const auto [px, py, sx, sy] = mouse_device->GetStatus();
|
||||
const auto x = static_cast<s32>(px * Layout::ScreenUndocked::Width);
|
||||
const auto y = static_cast<s32>(py * Layout::ScreenUndocked::Height);
|
||||
cur_entry.x = x;
|
||||
cur_entry.y = y;
|
||||
cur_entry.delta_x = x - last_entry.x;
|
||||
cur_entry.delta_y = y - last_entry.y;
|
||||
cur_entry.mouse_wheel_x = sx;
|
||||
cur_entry.mouse_wheel_y = sy;
|
||||
|
||||
for (std::size_t i = 0; i < mouse_button_devices.size(); ++i) {
|
||||
cur_entry.button |= (mouse_button_devices[i]->GetStatus() << i);
|
||||
}
|
||||
}
|
||||
|
||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
|
||||
}
|
||||
|
||||
void Controller_Mouse::OnLoadInputDevices() {
|
||||
mouse_device = Input::CreateDevice<Input::MouseDevice>(Settings::values.mouse_device);
|
||||
std::transform(Settings::values.mouse_buttons.begin(), Settings::values.mouse_buttons.end(),
|
||||
mouse_button_devices.begin(), Input::CreateDevice<Input::ButtonDevice>);
|
||||
}
|
||||
} // namespace Service::HID
|
57
src/core/hle/service/hid/controllers/mouse.h
Executable file
57
src/core/hle/service/hid/controllers/mouse.h
Executable file
@@ -0,0 +1,57 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include "common/common_types.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/frontend/input.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
namespace Service::HID {
|
||||
class Controller_Mouse final : public ControllerBase {
|
||||
public:
|
||||
explicit Controller_Mouse(Core::System& system);
|
||||
~Controller_Mouse() 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, u8* data, std::size_t size) override;
|
||||
|
||||
// Called when input devices should be loaded
|
||||
void OnLoadInputDevices() override;
|
||||
|
||||
private:
|
||||
struct MouseState {
|
||||
s64_le sampling_number;
|
||||
s64_le sampling_number2;
|
||||
s32_le x;
|
||||
s32_le y;
|
||||
s32_le delta_x;
|
||||
s32_le delta_y;
|
||||
s32_le mouse_wheel_x;
|
||||
s32_le mouse_wheel_y;
|
||||
s32_le button;
|
||||
s32_le attribute;
|
||||
};
|
||||
static_assert(sizeof(MouseState) == 0x30, "MouseState is an invalid size");
|
||||
|
||||
struct SharedMemory {
|
||||
CommonHeader header;
|
||||
std::array<MouseState, 17> mouse_states;
|
||||
};
|
||||
SharedMemory shared_memory{};
|
||||
|
||||
std::unique_ptr<Input::MouseDevice> mouse_device;
|
||||
std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeMouseButton::NumMouseButtons>
|
||||
mouse_button_devices;
|
||||
};
|
||||
} // namespace Service::HID
|
1102
src/core/hle/service/hid/controllers/npad.cpp
Executable file
1102
src/core/hle/service/hid/controllers/npad.cpp
Executable file
File diff suppressed because it is too large
Load Diff
459
src/core/hle/service/hid/controllers/npad.h
Executable file
459
src/core/hle/service/hid/controllers/npad.h
Executable file
@@ -0,0 +1,459 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/frontend/input.h"
|
||||
#include "core/hle/kernel/object.h"
|
||||
#include "core/hle/kernel/writable_event.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
constexpr u32 NPAD_HANDHELD = 32;
|
||||
constexpr u32 NPAD_UNKNOWN = 16; // TODO(ogniK): What is this?
|
||||
|
||||
class Controller_NPad final : public ControllerBase {
|
||||
public:
|
||||
explicit Controller_NPad(Core::System& system);
|
||||
~Controller_NPad() 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, u8* data, std::size_t size) override;
|
||||
|
||||
// When the controller is requesting a motion update for the shared memory
|
||||
void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
||||
std::size_t size) override;
|
||||
|
||||
// Called when input devices should be loaded
|
||||
void OnLoadInputDevices() override;
|
||||
|
||||
enum class NPadControllerType {
|
||||
None,
|
||||
ProController,
|
||||
Handheld,
|
||||
JoyDual,
|
||||
JoyLeft,
|
||||
JoyRight,
|
||||
Pokeball,
|
||||
};
|
||||
|
||||
enum class NpadType : u8 {
|
||||
ProController = 3,
|
||||
Handheld = 4,
|
||||
JoyconDual = 5,
|
||||
JoyconLeft = 6,
|
||||
JoyconRight = 7,
|
||||
Pokeball = 9,
|
||||
MaxNpadType = 10,
|
||||
};
|
||||
|
||||
enum class DeviceIndex : u8 {
|
||||
Left = 0,
|
||||
Right = 1,
|
||||
None = 2,
|
||||
MaxDeviceIndex = 3,
|
||||
};
|
||||
|
||||
enum class GyroscopeZeroDriftMode : u32 {
|
||||
Loose = 0,
|
||||
Standard = 1,
|
||||
Tight = 2,
|
||||
};
|
||||
|
||||
enum class NpadHoldType : u64 {
|
||||
Vertical = 0,
|
||||
Horizontal = 1,
|
||||
};
|
||||
|
||||
enum class NpadAssignments : u32 {
|
||||
Dual = 0,
|
||||
Single = 1,
|
||||
};
|
||||
|
||||
enum class NpadHandheldActivationMode : u64 {
|
||||
Dual = 0,
|
||||
Single = 1,
|
||||
None = 2,
|
||||
};
|
||||
|
||||
enum class NpadCommunicationMode : u64 {
|
||||
Unknown0 = 0,
|
||||
Unknown1 = 1,
|
||||
Unknown2 = 2,
|
||||
Unknown3 = 3,
|
||||
};
|
||||
|
||||
struct DeviceHandle {
|
||||
NpadType npad_type{};
|
||||
u8 npad_id{};
|
||||
DeviceIndex device_index{};
|
||||
INSERT_PADDING_BYTES(1);
|
||||
};
|
||||
static_assert(sizeof(DeviceHandle) == 4, "DeviceHandle is an invalid size");
|
||||
|
||||
struct NpadStyleSet {
|
||||
union {
|
||||
u32_le raw{};
|
||||
|
||||
BitField<0, 1, u32> pro_controller;
|
||||
BitField<1, 1, u32> handheld;
|
||||
BitField<2, 1, u32> joycon_dual;
|
||||
BitField<3, 1, u32> joycon_left;
|
||||
BitField<4, 1, u32> joycon_right;
|
||||
|
||||
BitField<6, 1, u32> pokeball; // TODO(ogniK): Confirm when possible
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size");
|
||||
|
||||
struct VibrationValue {
|
||||
f32 amp_low{0.0f};
|
||||
f32 freq_low{160.0f};
|
||||
f32 amp_high{0.0f};
|
||||
f32 freq_high{320.0f};
|
||||
};
|
||||
static_assert(sizeof(VibrationValue) == 0x10, "Vibration is an invalid size");
|
||||
|
||||
struct LedPattern {
|
||||
explicit LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) {
|
||||
position1.Assign(light1);
|
||||
position2.Assign(light2);
|
||||
position3.Assign(light3);
|
||||
position4.Assign(light4);
|
||||
}
|
||||
union {
|
||||
u64 raw{};
|
||||
BitField<0, 1, u64> position1;
|
||||
BitField<1, 1, u64> position2;
|
||||
BitField<2, 1, u64> position3;
|
||||
BitField<3, 1, u64> position4;
|
||||
};
|
||||
};
|
||||
|
||||
void SetSupportedStyleSet(NpadStyleSet style_set);
|
||||
NpadStyleSet GetSupportedStyleSet() const;
|
||||
|
||||
void SetSupportedNpadIdTypes(u8* data, std::size_t length);
|
||||
void GetSupportedNpadIdTypes(u32* data, std::size_t max_length);
|
||||
std::size_t GetSupportedNpadIdTypesSize() const;
|
||||
|
||||
void SetHoldType(NpadHoldType joy_hold_type);
|
||||
NpadHoldType GetHoldType() const;
|
||||
|
||||
void SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode);
|
||||
NpadHandheldActivationMode GetNpadHandheldActivationMode() const;
|
||||
|
||||
void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_);
|
||||
NpadCommunicationMode GetNpadCommunicationMode() const;
|
||||
|
||||
void SetNpadMode(u32 npad_id, NpadAssignments assignment_mode);
|
||||
|
||||
bool VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index,
|
||||
const VibrationValue& vibration_value);
|
||||
|
||||
void VibrateController(const DeviceHandle& vibration_device_handle,
|
||||
const VibrationValue& vibration_value);
|
||||
|
||||
void VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles,
|
||||
const std::vector<VibrationValue>& vibration_values);
|
||||
|
||||
VibrationValue GetLastVibration(const DeviceHandle& vibration_device_handle) const;
|
||||
|
||||
void InitializeVibrationDevice(const DeviceHandle& vibration_device_handle);
|
||||
|
||||
void InitializeVibrationDeviceAtIndex(std::size_t npad_index, std::size_t device_index);
|
||||
|
||||
void SetPermitVibrationSession(bool permit_vibration_session);
|
||||
|
||||
bool IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const;
|
||||
|
||||
std::shared_ptr<Kernel::ReadableEvent> GetStyleSetChangedEvent(u32 npad_id) const;
|
||||
void SignalStyleSetChangedEvent(u32 npad_id) const;
|
||||
|
||||
// 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 DisconnectNpad(u32 npad_id);
|
||||
void DisconnectNpadAtIndex(std::size_t index);
|
||||
|
||||
void SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode drift_mode);
|
||||
GyroscopeZeroDriftMode GetGyroscopeZeroDriftMode() const;
|
||||
bool IsSixAxisSensorAtRest() const;
|
||||
void SetSixAxisEnabled(bool six_axis_status);
|
||||
LedPattern GetLedPattern(u32 npad_id);
|
||||
bool IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const;
|
||||
void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, u32 npad_id);
|
||||
void ClearAllConnectedControllers();
|
||||
void DisconnectAllConnectedControllers();
|
||||
void ConnectAllDisconnectedControllers();
|
||||
void ClearAllControllers();
|
||||
|
||||
void MergeSingleJoyAsDualJoy(u32 npad_id_1, u32 npad_id_2);
|
||||
void StartLRAssignmentMode();
|
||||
void StopLRAssignmentMode();
|
||||
bool SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2);
|
||||
|
||||
// Logical OR for all buttons presses on all controllers
|
||||
// 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);
|
||||
static bool IsNpadIdValid(u32 npad_id);
|
||||
static bool IsDeviceHandleValid(const DeviceHandle& device_handle);
|
||||
|
||||
private:
|
||||
struct CommonHeader {
|
||||
s64_le timestamp;
|
||||
s64_le total_entry_count;
|
||||
s64_le last_entry_index;
|
||||
s64_le entry_count;
|
||||
};
|
||||
static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
|
||||
|
||||
struct ControllerColor {
|
||||
u32_le body_color;
|
||||
u32_le button_color;
|
||||
};
|
||||
static_assert(sizeof(ControllerColor) == 8, "ControllerColor is an invalid size");
|
||||
|
||||
struct ControllerPadState {
|
||||
union {
|
||||
u64_le raw{};
|
||||
// Button states
|
||||
BitField<0, 1, u64> a;
|
||||
BitField<1, 1, u64> b;
|
||||
BitField<2, 1, u64> x;
|
||||
BitField<3, 1, u64> y;
|
||||
BitField<4, 1, u64> l_stick;
|
||||
BitField<5, 1, u64> r_stick;
|
||||
BitField<6, 1, u64> l;
|
||||
BitField<7, 1, u64> r;
|
||||
BitField<8, 1, u64> zl;
|
||||
BitField<9, 1, u64> zr;
|
||||
BitField<10, 1, u64> plus;
|
||||
BitField<11, 1, u64> minus;
|
||||
|
||||
// D-Pad
|
||||
BitField<12, 1, u64> d_left;
|
||||
BitField<13, 1, u64> d_up;
|
||||
BitField<14, 1, u64> d_right;
|
||||
BitField<15, 1, u64> d_down;
|
||||
|
||||
// Left JoyStick
|
||||
BitField<16, 1, u64> l_stick_left;
|
||||
BitField<17, 1, u64> l_stick_up;
|
||||
BitField<18, 1, u64> l_stick_right;
|
||||
BitField<19, 1, u64> l_stick_down;
|
||||
|
||||
// Right JoyStick
|
||||
BitField<20, 1, u64> r_stick_left;
|
||||
BitField<21, 1, u64> r_stick_up;
|
||||
BitField<22, 1, u64> r_stick_right;
|
||||
BitField<23, 1, u64> r_stick_down;
|
||||
|
||||
// Not always active?
|
||||
BitField<24, 1, u64> left_sl;
|
||||
BitField<25, 1, u64> left_sr;
|
||||
|
||||
BitField<26, 1, u64> right_sl;
|
||||
BitField<27, 1, u64> right_sr;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(ControllerPadState) == 8, "ControllerPadState is an invalid size");
|
||||
|
||||
struct AnalogPosition {
|
||||
s32_le x;
|
||||
s32_le y;
|
||||
};
|
||||
static_assert(sizeof(AnalogPosition) == 8, "AnalogPosition is an invalid size");
|
||||
|
||||
struct ConnectionState {
|
||||
union {
|
||||
u32_le raw{};
|
||||
BitField<0, 1, u32> IsConnected;
|
||||
BitField<1, 1, u32> IsWired;
|
||||
BitField<2, 1, u32> IsLeftJoyConnected;
|
||||
BitField<3, 1, u32> IsLeftJoyWired;
|
||||
BitField<4, 1, u32> IsRightJoyConnected;
|
||||
BitField<5, 1, u32> IsRightJoyWired;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size");
|
||||
|
||||
struct ControllerPad {
|
||||
ControllerPadState pad_states;
|
||||
AnalogPosition l_stick;
|
||||
AnalogPosition r_stick;
|
||||
};
|
||||
static_assert(sizeof(ControllerPad) == 0x18, "ControllerPad is an invalid size");
|
||||
|
||||
struct GenericStates {
|
||||
s64_le timestamp;
|
||||
s64_le timestamp2;
|
||||
ControllerPad pad;
|
||||
ConnectionState connection_status;
|
||||
};
|
||||
static_assert(sizeof(GenericStates) == 0x30, "NPadGenericStates is an invalid size");
|
||||
|
||||
struct NPadGeneric {
|
||||
CommonHeader common;
|
||||
std::array<GenericStates, 17> npad;
|
||||
};
|
||||
static_assert(sizeof(NPadGeneric) == 0x350, "NPadGeneric is an invalid size");
|
||||
|
||||
struct SixAxisStates {
|
||||
s64_le timestamp{};
|
||||
INSERT_PADDING_WORDS(2);
|
||||
s64_le timestamp2{};
|
||||
Common::Vec3f accel{};
|
||||
Common::Vec3f gyro{};
|
||||
Common::Vec3f rotation{};
|
||||
std::array<Common::Vec3f, 3> orientation{};
|
||||
s64_le always_one{1};
|
||||
};
|
||||
static_assert(sizeof(SixAxisStates) == 0x68, "SixAxisStates is an invalid size");
|
||||
|
||||
struct SixAxisGeneric {
|
||||
CommonHeader common{};
|
||||
std::array<SixAxisStates, 17> sixaxis{};
|
||||
};
|
||||
static_assert(sizeof(SixAxisGeneric) == 0x708, "SixAxisGeneric is an invalid size");
|
||||
|
||||
enum class ColorReadError : u32_le {
|
||||
ReadOk = 0,
|
||||
ColorDoesntExist = 1,
|
||||
NoController = 2,
|
||||
};
|
||||
|
||||
struct NPadProperties {
|
||||
union {
|
||||
s64_le raw{};
|
||||
BitField<11, 1, s64> is_vertical;
|
||||
BitField<12, 1, s64> is_horizontal;
|
||||
BitField<13, 1, s64> use_plus;
|
||||
BitField<14, 1, s64> use_minus;
|
||||
};
|
||||
};
|
||||
|
||||
struct NPadDevice {
|
||||
union {
|
||||
u32_le raw{};
|
||||
BitField<0, 1, s32> pro_controller;
|
||||
BitField<1, 1, s32> handheld;
|
||||
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> pokeball;
|
||||
};
|
||||
};
|
||||
|
||||
struct MotionDevice {
|
||||
Common::Vec3f accel;
|
||||
Common::Vec3f gyro;
|
||||
Common::Vec3f rotation;
|
||||
std::array<Common::Vec3f, 3> orientation;
|
||||
};
|
||||
|
||||
struct NPadEntry {
|
||||
NpadStyleSet joy_styles;
|
||||
NpadAssignments pad_assignment;
|
||||
|
||||
ColorReadError single_color_error;
|
||||
ControllerColor single_color;
|
||||
|
||||
ColorReadError dual_color_error;
|
||||
ControllerColor left_color;
|
||||
ControllerColor right_color;
|
||||
|
||||
NPadGeneric main_controller_states;
|
||||
NPadGeneric handheld_states;
|
||||
NPadGeneric dual_states;
|
||||
NPadGeneric left_joy_states;
|
||||
NPadGeneric right_joy_states;
|
||||
NPadGeneric pokeball_states;
|
||||
NPadGeneric libnx; // TODO(ogniK): Find out what this actually is, libnx seems to only be
|
||||
// relying on this for the time being
|
||||
SixAxisGeneric sixaxis_full;
|
||||
SixAxisGeneric sixaxis_handheld;
|
||||
SixAxisGeneric sixaxis_dual_left;
|
||||
SixAxisGeneric sixaxis_dual_right;
|
||||
SixAxisGeneric sixaxis_left;
|
||||
SixAxisGeneric sixaxis_right;
|
||||
NPadDevice device_type;
|
||||
NPadProperties properties;
|
||||
INSERT_PADDING_WORDS(1);
|
||||
std::array<u32, 3> battery_level;
|
||||
INSERT_PADDING_BYTES(0x5c);
|
||||
INSERT_PADDING_BYTES(0xdf8);
|
||||
};
|
||||
static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size");
|
||||
|
||||
struct ControllerHolder {
|
||||
NPadControllerType type;
|
||||
bool is_connected;
|
||||
};
|
||||
|
||||
void InitNewlyAddedController(std::size_t controller_idx);
|
||||
bool IsControllerSupported(NPadControllerType controller) const;
|
||||
void RequestPadStateUpdate(u32 npad_id);
|
||||
|
||||
std::atomic<u32> press_state{};
|
||||
|
||||
NpadStyleSet style{};
|
||||
std::array<NPadEntry, 10> shared_memory_entries{};
|
||||
using ButtonArray = std::array<
|
||||
std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>,
|
||||
10>;
|
||||
using StickArray = std::array<
|
||||
std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID>,
|
||||
10>;
|
||||
using VibrationArray = std::array<std::array<std::unique_ptr<Input::VibrationDevice>,
|
||||
Settings::NativeVibration::NUM_VIBRATIONS_HID>,
|
||||
10>;
|
||||
using MotionArray = std::array<
|
||||
std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTIONS_HID>,
|
||||
10>;
|
||||
ButtonArray buttons;
|
||||
StickArray sticks;
|
||||
VibrationArray vibrations;
|
||||
MotionArray motions;
|
||||
std::vector<u32> supported_npad_id_types{};
|
||||
NpadHoldType hold_type{NpadHoldType::Vertical};
|
||||
NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
|
||||
// NpadCommunicationMode is unknown, default value is 1
|
||||
NpadCommunicationMode communication_mode{NpadCommunicationMode::Unknown1};
|
||||
// Each controller should have their own styleset changed event
|
||||
std::array<Kernel::EventPair, 10> styleset_changed_events;
|
||||
std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> last_vibration_timepoints;
|
||||
std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{};
|
||||
bool permit_vibration_session_enabled{false};
|
||||
std::array<std::array<bool, 2>, 10> vibration_devices_mounted{};
|
||||
std::array<ControllerHolder, 10> connected_controllers{};
|
||||
std::array<bool, 10> unintended_home_button_input_protection{};
|
||||
GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard};
|
||||
bool sixaxis_sensors_enabled{true};
|
||||
bool sixaxis_at_rest{true};
|
||||
std::array<ControllerPad, 10> npad_pad_states{};
|
||||
bool is_in_lr_assignment_mode{false};
|
||||
Core::System& system;
|
||||
};
|
||||
} // namespace Service::HID
|
40
src/core/hle/service/hid/controllers/stubbed.cpp
Executable file
40
src/core/hle/service/hid/controllers/stubbed.cpp
Executable file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cstring>
|
||||
#include "common/common_types.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hle/service/hid/controllers/stubbed.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
Controller_Stubbed::Controller_Stubbed(Core::System& system) : ControllerBase(system) {}
|
||||
Controller_Stubbed::~Controller_Stubbed() = default;
|
||||
|
||||
void Controller_Stubbed::OnInit() {}
|
||||
|
||||
void Controller_Stubbed::OnRelease() {}
|
||||
|
||||
void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
||||
std::size_t size) {
|
||||
if (!smart_update) {
|
||||
return;
|
||||
}
|
||||
|
||||
CommonHeader header{};
|
||||
header.timestamp = core_timing.GetCPUTicks();
|
||||
header.total_entry_count = 17;
|
||||
header.entry_count = 0;
|
||||
header.last_entry_index = 0;
|
||||
|
||||
std::memcpy(data + common_offset, &header, sizeof(CommonHeader));
|
||||
}
|
||||
|
||||
void Controller_Stubbed::OnLoadInputDevices() {}
|
||||
|
||||
void Controller_Stubbed::SetCommonHeaderOffset(std::size_t off) {
|
||||
common_offset = off;
|
||||
smart_update = true;
|
||||
}
|
||||
} // namespace Service::HID
|
34
src/core/hle/service/hid/controllers/stubbed.h
Executable file
34
src/core/hle/service/hid/controllers/stubbed.h
Executable file
@@ -0,0 +1,34 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
|
||||
namespace Service::HID {
|
||||
class Controller_Stubbed final : public ControllerBase {
|
||||
public:
|
||||
explicit Controller_Stubbed(Core::System& system);
|
||||
~Controller_Stubbed() 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, u8* data, std::size_t size) override;
|
||||
|
||||
// Called when input devices should be loaded
|
||||
void OnLoadInputDevices() override;
|
||||
|
||||
void SetCommonHeaderOffset(std::size_t off);
|
||||
|
||||
private:
|
||||
bool smart_update{};
|
||||
std::size_t common_offset{};
|
||||
};
|
||||
} // namespace Service::HID
|
77
src/core/hle/service/hid/controllers/touchscreen.cpp
Executable file
77
src/core/hle/service/hid/controllers/touchscreen.cpp
Executable file
@@ -0,0 +1,77 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cstring>
|
||||
#include "common/common_types.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "core/frontend/input.h"
|
||||
#include "core/hle/service/hid/controllers/touchscreen.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
namespace Service::HID {
|
||||
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400;
|
||||
|
||||
Controller_Touchscreen::Controller_Touchscreen(Core::System& system) : ControllerBase(system) {}
|
||||
Controller_Touchscreen::~Controller_Touchscreen() = default;
|
||||
|
||||
void Controller_Touchscreen::OnInit() {}
|
||||
|
||||
void Controller_Touchscreen::OnRelease() {}
|
||||
|
||||
void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
||||
std::size_t size) {
|
||||
shared_memory.header.timestamp = core_timing.GetCPUTicks();
|
||||
shared_memory.header.total_entry_count = 17;
|
||||
|
||||
if (!IsControllerActivated()) {
|
||||
shared_memory.header.entry_count = 0;
|
||||
shared_memory.header.last_entry_index = 0;
|
||||
return;
|
||||
}
|
||||
shared_memory.header.entry_count = 16;
|
||||
|
||||
const auto& last_entry =
|
||||
shared_memory.shared_memory_entries[shared_memory.header.last_entry_index];
|
||||
shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17;
|
||||
auto& cur_entry = shared_memory.shared_memory_entries[shared_memory.header.last_entry_index];
|
||||
|
||||
cur_entry.sampling_number = last_entry.sampling_number + 1;
|
||||
cur_entry.sampling_number2 = cur_entry.sampling_number;
|
||||
|
||||
bool pressed = false;
|
||||
float x, y;
|
||||
std::tie(x, y, pressed) = touch_device->GetStatus();
|
||||
auto& touch_entry = cur_entry.states[0];
|
||||
touch_entry.attribute.raw = 0;
|
||||
if (!pressed && touch_btn_device) {
|
||||
std::tie(x, y, pressed) = touch_btn_device->GetStatus();
|
||||
}
|
||||
if (pressed && Settings::values.touchscreen.enabled) {
|
||||
touch_entry.x = static_cast<u16>(x * Layout::ScreenUndocked::Width);
|
||||
touch_entry.y = static_cast<u16>(y * Layout::ScreenUndocked::Height);
|
||||
touch_entry.diameter_x = Settings::values.touchscreen.diameter_x;
|
||||
touch_entry.diameter_y = Settings::values.touchscreen.diameter_y;
|
||||
touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle;
|
||||
const u64 tick = core_timing.GetCPUTicks();
|
||||
touch_entry.delta_time = tick - last_touch;
|
||||
last_touch = tick;
|
||||
touch_entry.finger = Settings::values.touchscreen.finger;
|
||||
cur_entry.entry_count = 1;
|
||||
} else {
|
||||
cur_entry.entry_count = 0;
|
||||
}
|
||||
|
||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(TouchScreenSharedMemory));
|
||||
}
|
||||
|
||||
void Controller_Touchscreen::OnLoadInputDevices() {
|
||||
touch_device = Input::CreateDevice<Input::TouchDevice>(Settings::values.touchscreen.device);
|
||||
if (Settings::values.use_touch_from_button) {
|
||||
touch_btn_device = Input::CreateDevice<Input::TouchDevice>("engine:touch_from_button");
|
||||
} else {
|
||||
touch_btn_device.reset();
|
||||
}
|
||||
}
|
||||
} // namespace Service::HID
|
74
src/core/hle/service/hid/controllers/touchscreen.h
Executable file
74
src/core/hle/service/hid/controllers/touchscreen.h
Executable file
@@ -0,0 +1,74 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/frontend/input.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
|
||||
namespace Service::HID {
|
||||
class Controller_Touchscreen final : public ControllerBase {
|
||||
public:
|
||||
explicit Controller_Touchscreen(Core::System& system);
|
||||
~Controller_Touchscreen() 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, u8* data, std::size_t size) override;
|
||||
|
||||
// Called when input devices should be loaded
|
||||
void OnLoadInputDevices() override;
|
||||
|
||||
private:
|
||||
struct Attributes {
|
||||
union {
|
||||
u32 raw{};
|
||||
BitField<0, 1, u32> start_touch;
|
||||
BitField<1, 1, u32> end_touch;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size");
|
||||
|
||||
struct TouchState {
|
||||
u64_le delta_time;
|
||||
Attributes attribute;
|
||||
u32_le finger;
|
||||
u32_le x;
|
||||
u32_le y;
|
||||
u32_le diameter_x;
|
||||
u32_le diameter_y;
|
||||
u32_le rotation_angle;
|
||||
};
|
||||
static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size");
|
||||
|
||||
struct TouchScreenEntry {
|
||||
s64_le sampling_number;
|
||||
s64_le sampling_number2;
|
||||
s32_le entry_count;
|
||||
std::array<TouchState, 16> states;
|
||||
};
|
||||
static_assert(sizeof(TouchScreenEntry) == 0x298, "TouchScreenEntry is an invalid size");
|
||||
|
||||
struct TouchScreenSharedMemory {
|
||||
CommonHeader header;
|
||||
std::array<TouchScreenEntry, 17> shared_memory_entries{};
|
||||
INSERT_PADDING_BYTES(0x3c8);
|
||||
};
|
||||
static_assert(sizeof(TouchScreenSharedMemory) == 0x3000,
|
||||
"TouchScreenSharedMemory is an invalid size");
|
||||
TouchScreenSharedMemory shared_memory{};
|
||||
std::unique_ptr<Input::TouchDevice> touch_device;
|
||||
std::unique_ptr<Input::TouchDevice> touch_btn_device;
|
||||
s64_le last_touch{};
|
||||
};
|
||||
} // namespace Service::HID
|
46
src/core/hle/service/hid/controllers/xpad.cpp
Executable file
46
src/core/hle/service/hid/controllers/xpad.cpp
Executable file
@@ -0,0 +1,46 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cstring>
|
||||
#include "common/common_types.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hle/service/hid/controllers/xpad.h"
|
||||
|
||||
namespace Service::HID {
|
||||
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00;
|
||||
|
||||
Controller_XPad::Controller_XPad(Core::System& system) : ControllerBase(system) {}
|
||||
Controller_XPad::~Controller_XPad() = default;
|
||||
|
||||
void Controller_XPad::OnInit() {}
|
||||
|
||||
void Controller_XPad::OnRelease() {}
|
||||
|
||||
void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
|
||||
std::size_t size) {
|
||||
for (auto& xpad_entry : shared_memory.shared_memory_entries) {
|
||||
xpad_entry.header.timestamp = core_timing.GetCPUTicks();
|
||||
xpad_entry.header.total_entry_count = 17;
|
||||
|
||||
if (!IsControllerActivated()) {
|
||||
xpad_entry.header.entry_count = 0;
|
||||
xpad_entry.header.last_entry_index = 0;
|
||||
return;
|
||||
}
|
||||
xpad_entry.header.entry_count = 16;
|
||||
|
||||
const auto& last_entry = xpad_entry.pad_states[xpad_entry.header.last_entry_index];
|
||||
xpad_entry.header.last_entry_index = (xpad_entry.header.last_entry_index + 1) % 17;
|
||||
auto& cur_entry = xpad_entry.pad_states[xpad_entry.header.last_entry_index];
|
||||
|
||||
cur_entry.sampling_number = last_entry.sampling_number + 1;
|
||||
cur_entry.sampling_number2 = cur_entry.sampling_number;
|
||||
}
|
||||
// TODO(ogniK): Update xpad states
|
||||
|
||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
|
||||
}
|
||||
|
||||
void Controller_XPad::OnLoadInputDevices() {}
|
||||
} // namespace Service::HID
|
60
src/core/hle/service/hid/controllers/xpad.h
Executable file
60
src/core/hle/service/hid/controllers/xpad.h
Executable file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
|
||||
namespace Service::HID {
|
||||
class Controller_XPad final : public ControllerBase {
|
||||
public:
|
||||
explicit Controller_XPad(Core::System& system);
|
||||
~Controller_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, u8* data, std::size_t size) override;
|
||||
|
||||
// Called when input devices should be loaded
|
||||
void OnLoadInputDevices() override;
|
||||
|
||||
private:
|
||||
struct AnalogStick {
|
||||
s32_le x;
|
||||
s32_le y;
|
||||
};
|
||||
static_assert(sizeof(AnalogStick) == 0x8, "AnalogStick is an invalid size");
|
||||
|
||||
struct XPadState {
|
||||
s64_le sampling_number;
|
||||
s64_le sampling_number2;
|
||||
s32_le attributes;
|
||||
u32_le pad_states;
|
||||
AnalogStick x_stick;
|
||||
AnalogStick y_stick;
|
||||
};
|
||||
static_assert(sizeof(XPadState) == 0x28, "XPadState is an invalid size");
|
||||
|
||||
struct XPadEntry {
|
||||
CommonHeader header;
|
||||
std::array<XPadState, 17> pad_states{};
|
||||
INSERT_PADDING_BYTES(0x138);
|
||||
};
|
||||
static_assert(sizeof(XPadEntry) == 0x400, "XPadEntry is an invalid size");
|
||||
|
||||
struct SharedMemory {
|
||||
std::array<XPadEntry, 4> shared_memory_entries{};
|
||||
};
|
||||
static_assert(sizeof(SharedMemory) == 0x1000, "SharedMemory is an invalid size");
|
||||
SharedMemory shared_memory{};
|
||||
};
|
||||
} // namespace Service::HID
|
13
src/core/hle/service/hid/errors.h
Executable file
13
src/core/hle/service/hid/errors.h
Executable file
@@ -0,0 +1,13 @@
|
||||
// Copyright 2019 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/result.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
constexpr ResultCode ERR_NPAD_NOT_CONNECTED{ErrorModule::HID, 710};
|
||||
|
||||
} // namespace Service::HID
|
1648
src/core/hle/service/hid/hid.cpp
Executable file
1648
src/core/hle/service/hid/hid.cpp
Executable file
File diff suppressed because it is too large
Load Diff
176
src/core/hle/service/hid/hid.h
Executable file
176
src/core/hle/service/hid/hid.h
Executable file
@@ -0,0 +1,176 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core::Timing {
|
||||
struct EventType;
|
||||
}
|
||||
|
||||
namespace Kernel {
|
||||
class SharedMemory;
|
||||
}
|
||||
|
||||
namespace Service::SM {
|
||||
class ServiceManager;
|
||||
}
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
enum class HidController : std::size_t {
|
||||
DebugPad,
|
||||
Touchscreen,
|
||||
Mouse,
|
||||
Keyboard,
|
||||
XPad,
|
||||
Unknown1,
|
||||
Unknown2,
|
||||
Unknown3,
|
||||
SixAxisSensor,
|
||||
NPad,
|
||||
Gesture,
|
||||
|
||||
MaxControllers,
|
||||
};
|
||||
|
||||
class IAppletResource final : public ServiceFramework<IAppletResource> {
|
||||
public:
|
||||
explicit IAppletResource(Core::System& system_);
|
||||
~IAppletResource() override;
|
||||
|
||||
void ActivateController(HidController controller);
|
||||
void DeactivateController(HidController controller);
|
||||
|
||||
template <typename T>
|
||||
T& GetController(HidController controller) {
|
||||
return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& GetController(HidController controller) const {
|
||||
return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
void MakeController(HidController controller) {
|
||||
controllers[static_cast<std::size_t>(controller)] = std::make_unique<T>(system);
|
||||
}
|
||||
|
||||
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
|
||||
void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
|
||||
void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
|
||||
|
||||
std::shared_ptr<Kernel::SharedMemory> shared_mem;
|
||||
|
||||
std::shared_ptr<Core::Timing::EventType> pad_update_event;
|
||||
std::shared_ptr<Core::Timing::EventType> motion_update_event;
|
||||
|
||||
std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
|
||||
controllers{};
|
||||
};
|
||||
|
||||
class Hid final : public ServiceFramework<Hid> {
|
||||
public:
|
||||
explicit Hid(Core::System& system_);
|
||||
~Hid() override;
|
||||
|
||||
std::shared_ptr<IAppletResource> GetAppletResource();
|
||||
|
||||
private:
|
||||
void CreateAppletResource(Kernel::HLERequestContext& ctx);
|
||||
void ActivateDebugPad(Kernel::HLERequestContext& ctx);
|
||||
void ActivateTouchScreen(Kernel::HLERequestContext& ctx);
|
||||
void ActivateMouse(Kernel::HLERequestContext& ctx);
|
||||
void ActivateKeyboard(Kernel::HLERequestContext& ctx);
|
||||
void SendKeyboardLockKeyEvent(Kernel::HLERequestContext& ctx);
|
||||
void ActivateXpad(Kernel::HLERequestContext& ctx);
|
||||
void GetXpadIDs(Kernel::HLERequestContext& ctx);
|
||||
void ActivateSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void DeactivateSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void StartSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void StopSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx);
|
||||
void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
|
||||
void GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
|
||||
void ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
|
||||
void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx);
|
||||
void ActivateGesture(Kernel::HLERequestContext& ctx);
|
||||
void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx);
|
||||
void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx);
|
||||
void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx);
|
||||
void ActivateNpad(Kernel::HLERequestContext& ctx);
|
||||
void DeactivateNpad(Kernel::HLERequestContext& ctx);
|
||||
void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx);
|
||||
void DisconnectNpad(Kernel::HLERequestContext& ctx);
|
||||
void GetPlayerLedPattern(Kernel::HLERequestContext& ctx);
|
||||
void ActivateNpadWithRevision(Kernel::HLERequestContext& ctx);
|
||||
void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx);
|
||||
void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx);
|
||||
void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx);
|
||||
void SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx);
|
||||
void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx);
|
||||
void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx);
|
||||
void StartLrAssignmentMode(Kernel::HLERequestContext& ctx);
|
||||
void StopLrAssignmentMode(Kernel::HLERequestContext& ctx);
|
||||
void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
|
||||
void GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
|
||||
void SwapNpadAssignment(Kernel::HLERequestContext& ctx);
|
||||
void IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx);
|
||||
void EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx);
|
||||
void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx);
|
||||
void SendVibrationValue(Kernel::HLERequestContext& ctx);
|
||||
void GetActualVibrationValue(Kernel::HLERequestContext& ctx);
|
||||
void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx);
|
||||
void PermitVibration(Kernel::HLERequestContext& ctx);
|
||||
void IsVibrationPermitted(Kernel::HLERequestContext& ctx);
|
||||
void SendVibrationValues(Kernel::HLERequestContext& ctx);
|
||||
void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx);
|
||||
void EndPermitVibrationSession(Kernel::HLERequestContext& ctx);
|
||||
void IsVibrationDeviceMounted(Kernel::HLERequestContext& ctx);
|
||||
void ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void StopConsoleSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void ActivateSevenSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void StartSevenSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void StopSevenSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void FinalizeSevenSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void ResetSevenSixAxisSensorTimestamp(Kernel::HLERequestContext& ctx);
|
||||
void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx);
|
||||
void SetPalmaBoostMode(Kernel::HLERequestContext& ctx);
|
||||
void SetNpadCommunicationMode(Kernel::HLERequestContext& ctx);
|
||||
void GetNpadCommunicationMode(Kernel::HLERequestContext& ctx);
|
||||
|
||||
enum class VibrationDeviceType : u32 {
|
||||
LinearResonantActuator = 1,
|
||||
};
|
||||
|
||||
enum class VibrationDevicePosition : u32 {
|
||||
None = 0,
|
||||
Left = 1,
|
||||
Right = 2,
|
||||
};
|
||||
|
||||
struct VibrationDeviceInfo {
|
||||
VibrationDeviceType type{};
|
||||
VibrationDevicePosition position{};
|
||||
};
|
||||
static_assert(sizeof(VibrationDeviceInfo) == 0x8, "VibrationDeviceInfo has incorrect size.");
|
||||
|
||||
std::shared_ptr<IAppletResource> applet_resource;
|
||||
};
|
||||
|
||||
/// Reload input devices. Used when input configuration changed
|
||||
void ReloadInputDevices();
|
||||
|
||||
/// Registers all HID services with the specified service manager.
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
|
||||
|
||||
} // namespace Service::HID
|
193
src/core/hle/service/hid/irs.cpp
Executable file
193
src/core/hle/service/hid/irs.cpp
Executable file
@@ -0,0 +1,193 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/swap.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/shared_memory.h"
|
||||
#include "core/hle/service/hid/irs.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{302, &IRS::ActivateIrsensor, "ActivateIrsensor"},
|
||||
{303, &IRS::DeactivateIrsensor, "DeactivateIrsensor"},
|
||||
{304, &IRS::GetIrsensorSharedMemoryHandle, "GetIrsensorSharedMemoryHandle"},
|
||||
{305, &IRS::StopImageProcessor, "StopImageProcessor"},
|
||||
{306, &IRS::RunMomentProcessor, "RunMomentProcessor"},
|
||||
{307, &IRS::RunClusteringProcessor, "RunClusteringProcessor"},
|
||||
{308, &IRS::RunImageTransferProcessor, "RunImageTransferProcessor"},
|
||||
{309, &IRS::GetImageTransferProcessorState, "GetImageTransferProcessorState"},
|
||||
{310, &IRS::RunTeraPluginProcessor, "RunTeraPluginProcessor"},
|
||||
{311, &IRS::GetNpadIrCameraHandle, "GetNpadIrCameraHandle"},
|
||||
{312, &IRS::RunPointingProcessor, "RunPointingProcessor"},
|
||||
{313, &IRS::SuspendImageProcessor, "SuspendImageProcessor"},
|
||||
{314, &IRS::CheckFirmwareVersion, "CheckFirmwareVersion"},
|
||||
{315, &IRS::SetFunctionLevel, "SetFunctionLevel"},
|
||||
{316, &IRS::RunImageTransferExProcessor, "RunImageTransferExProcessor"},
|
||||
{317, &IRS::RunIrLedProcessor, "RunIrLedProcessor"},
|
||||
{318, &IRS::StopImageProcessorAsync, "StopImageProcessorAsync"},
|
||||
{319, &IRS::ActivateIrsensorWithFunctionLevel, "ActivateIrsensorWithFunctionLevel"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
|
||||
shared_mem = SharedFrom(&kernel.GetIrsSharedMem());
|
||||
}
|
||||
|
||||
void IRS::ActivateIrsensor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IRS::DeactivateIrsensor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IRS::GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_IRS, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(shared_mem);
|
||||
}
|
||||
|
||||
void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IRS::RunMomentProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IRS::RunClusteringProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 5};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw<u64>(system.CoreTiming().GetCPUTicks());
|
||||
rb.PushRaw<u32>(0);
|
||||
}
|
||||
|
||||
void IRS::RunTeraPluginProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IRS::GetNpadIrCameraHandle(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw<u32>(device_handle);
|
||||
}
|
||||
|
||||
void IRS::RunPointingProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IRS::SuspendImageProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IRS::CheckFirmwareVersion(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IRS::SetFunctionLevel(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IRS::RunIrLedProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IRS::StopImageProcessorAsync(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IRS::ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
IRS::~IRS() = default;
|
||||
|
||||
IRS_SYS::IRS_SYS(Core::System& system_) : ServiceFramework{system_, "irs:sys"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{500, nullptr, "SetAppletResourceUserId"},
|
||||
{501, nullptr, "RegisterAppletResourceUserId"},
|
||||
{502, nullptr, "UnregisterAppletResourceUserId"},
|
||||
{503, nullptr, "EnableAppletToGetInput"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
IRS_SYS::~IRS_SYS() = default;
|
||||
|
||||
} // namespace Service::HID
|
55
src/core/hle/service/hid/irs.h
Executable file
55
src/core/hle/service/hid/irs.h
Executable file
@@ -0,0 +1,55 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/kernel/object.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Kernel {
|
||||
class SharedMemory;
|
||||
}
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
class IRS final : public ServiceFramework<IRS> {
|
||||
public:
|
||||
explicit IRS(Core::System& system_);
|
||||
~IRS() override;
|
||||
|
||||
private:
|
||||
void ActivateIrsensor(Kernel::HLERequestContext& ctx);
|
||||
void DeactivateIrsensor(Kernel::HLERequestContext& ctx);
|
||||
void GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx);
|
||||
void StopImageProcessor(Kernel::HLERequestContext& ctx);
|
||||
void RunMomentProcessor(Kernel::HLERequestContext& ctx);
|
||||
void RunClusteringProcessor(Kernel::HLERequestContext& ctx);
|
||||
void RunImageTransferProcessor(Kernel::HLERequestContext& ctx);
|
||||
void GetImageTransferProcessorState(Kernel::HLERequestContext& ctx);
|
||||
void RunTeraPluginProcessor(Kernel::HLERequestContext& ctx);
|
||||
void GetNpadIrCameraHandle(Kernel::HLERequestContext& ctx);
|
||||
void RunPointingProcessor(Kernel::HLERequestContext& ctx);
|
||||
void SuspendImageProcessor(Kernel::HLERequestContext& ctx);
|
||||
void CheckFirmwareVersion(Kernel::HLERequestContext& ctx);
|
||||
void SetFunctionLevel(Kernel::HLERequestContext& ctx);
|
||||
void RunImageTransferExProcessor(Kernel::HLERequestContext& ctx);
|
||||
void RunIrLedProcessor(Kernel::HLERequestContext& ctx);
|
||||
void StopImageProcessorAsync(Kernel::HLERequestContext& ctx);
|
||||
void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx);
|
||||
|
||||
std::shared_ptr<Kernel::SharedMemory> shared_mem;
|
||||
const u32 device_handle{0xABCD};
|
||||
};
|
||||
|
||||
class IRS_SYS final : public ServiceFramework<IRS_SYS> {
|
||||
public:
|
||||
explicit IRS_SYS(Core::System& system);
|
||||
~IRS_SYS() override;
|
||||
};
|
||||
|
||||
} // namespace Service::HID
|
39
src/core/hle/service/hid/xcd.cpp
Executable file
39
src/core/hle/service/hid/xcd.cpp
Executable file
@@ -0,0 +1,39 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/service/hid/xcd.h"
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
XCD_SYS::XCD_SYS(Core::System& system_) : ServiceFramework{system_, "xcd:sys"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetDataFormat"},
|
||||
{1, nullptr, "SetDataFormat"},
|
||||
{2, nullptr, "GetMcuState"},
|
||||
{3, nullptr, "SetMcuState"},
|
||||
{4, nullptr, "GetMcuVersionForNfc"},
|
||||
{5, nullptr, "CheckNfcDevicePower"},
|
||||
{10, nullptr, "SetNfcEvent"},
|
||||
{11, nullptr, "GetNfcInfo"},
|
||||
{12, nullptr, "StartNfcDiscovery"},
|
||||
{13, nullptr, "StopNfcDiscovery"},
|
||||
{14, nullptr, "StartNtagRead"},
|
||||
{15, nullptr, "StartNtagWrite"},
|
||||
{16, nullptr, "SendNfcRawData"},
|
||||
{17, nullptr, "RegisterMifareKey"},
|
||||
{18, nullptr, "ClearMifareKey"},
|
||||
{19, nullptr, "StartMifareRead"},
|
||||
{20, nullptr, "StartMifareWrite"},
|
||||
{101, nullptr, "GetAwakeTriggerReasonForLeftRail"},
|
||||
{102, nullptr, "GetAwakeTriggerReasonForRightRail"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
XCD_SYS::~XCD_SYS() = default;
|
||||
|
||||
} // namespace Service::HID
|
21
src/core/hle/service/hid/xcd.h
Executable file
21
src/core/hle/service/hid/xcd.h
Executable file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
class XCD_SYS final : public ServiceFramework<XCD_SYS> {
|
||||
public:
|
||||
explicit XCD_SYS(Core::System& system_);
|
||||
~XCD_SYS() override;
|
||||
};
|
||||
|
||||
} // namespace Service::HID
|
Reference in New Issue
Block a user