summaryrefslogtreecommitdiff
path: root/src/core/hle
diff options
context:
space:
mode:
authorGravatar bunnei2018-01-15 12:54:54 -0500
committerGravatar GitHub2018-01-15 12:54:54 -0500
commit325f72acebd9ab7dd246f77ce7fbc2584104d00d (patch)
tree8c45a330a0e7d4208b68aae58dd3341a1921c51c /src/core/hle
parentMerge pull request #15 from bsaleil/master (diff)
parentyuzu_cmd: Fix default ini, add screenshot button (diff)
downloadyuzu-325f72acebd9ab7dd246f77ce7fbc2584104d00d.tar.gz
yuzu-325f72acebd9ab7dd246f77ce7fbc2584104d00d.tar.xz
yuzu-325f72acebd9ab7dd246f77ce7fbc2584104d00d.zip
Merge pull request #16 from shinyquagsire23/hid-sharedmem-impl-start
HID Sharedmem Impl Start
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/service/hid/hid.cpp86
-rw-r--r--src/core/hle/service/hid/hid.h312
2 files changed, 398 insertions, 0 deletions
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 3f74aed06..3c4259d27 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -2,7 +2,10 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <atomic>
5#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/core_timing.h"
8#include "core/frontend/input.h"
6#include "core/hle/ipc_helpers.h" 9#include "core/hle/ipc_helpers.h"
7#include "core/hle/kernel/client_port.h" 10#include "core/hle/kernel/client_port.h"
8#include "core/hle/kernel/client_session.h" 11#include "core/hle/kernel/client_session.h"
@@ -13,6 +16,12 @@
13namespace Service { 16namespace Service {
14namespace HID { 17namespace HID {
15 18
19// Updating period for each HID device.
20// TODO(shinyquagsire23): These need better values.
21constexpr u64 pad_update_ticks = BASE_CLOCK_RATE / 234;
22constexpr u64 accelerometer_update_ticks = BASE_CLOCK_RATE / 104;
23constexpr u64 gyroscope_update_ticks = BASE_CLOCK_RATE / 101;
24
16class IAppletResource final : public ServiceFramework<IAppletResource> { 25class IAppletResource final : public ServiceFramework<IAppletResource> {
17public: 26public:
18 IAppletResource() : ServiceFramework("IAppletResource") { 27 IAppletResource() : ServiceFramework("IAppletResource") {
@@ -24,6 +33,15 @@ public:
24 shared_mem = Kernel::SharedMemory::Create( 33 shared_mem = Kernel::SharedMemory::Create(
25 nullptr, 0x40000, Kernel::MemoryPermission::ReadWrite, Kernel::MemoryPermission::Read, 34 nullptr, 0x40000, Kernel::MemoryPermission::ReadWrite, Kernel::MemoryPermission::Read,
26 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory"); 35 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory");
36
37 // Register update callbacks
38 pad_update_event = CoreTiming::RegisterEvent(
39 "HID::UpdatePadCallback",
40 [this](u64 userdata, int cycles_late) { UpdatePadCallback(userdata, cycles_late); });
41
42 // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
43
44 CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event);
27 } 45 }
28 46
29private: 47private:
@@ -34,8 +52,76 @@ private:
34 LOG_DEBUG(Service, "called"); 52 LOG_DEBUG(Service, "called");
35 } 53 }
36 54
55 void LoadInputDevices() {
56 std::transform(Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN,
57 Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_END,
58 buttons.begin(), Input::CreateDevice<Input::ButtonDevice>);
59 // TODO(shinyquagsire23): sticks, gyro, touch, mouse, keyboard
60 }
61
62 void UpdatePadCallback(u64 userdata, int cycles_late) {
63 SharedMemory* mem = reinterpret_cast<SharedMemory*>(shared_mem->GetPointer());
64
65 if (is_device_reload_pending.exchange(false))
66 LoadInputDevices();
67
68 // TODO(shinyquagsire23): This is a hack!
69 ControllerPadState& state =
70 mem->controllers[Controller_Handheld].layouts[Layout_Default].entries[0].buttons;
71 using namespace Settings::NativeButton;
72 state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus());
73 state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus());
74 state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus());
75 state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus());
76 state.lstick.Assign(buttons[LStick - BUTTON_HID_BEGIN]->GetStatus());
77 state.rstick.Assign(buttons[RStick - BUTTON_HID_BEGIN]->GetStatus());
78 state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus());
79 state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus());
80 state.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus());
81 state.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus());
82 state.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus());
83 state.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus());
84
85 state.dleft.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus());
86 state.dup.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus());
87 state.dright.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus());
88 state.ddown.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus());
89
90 state.lstick_left.Assign(buttons[LStick_Left - BUTTON_HID_BEGIN]->GetStatus());
91 state.lstick_up.Assign(buttons[LStick_Up - BUTTON_HID_BEGIN]->GetStatus());
92 state.lstick_right.Assign(buttons[LStick_Right - BUTTON_HID_BEGIN]->GetStatus());
93 state.lstick_down.Assign(buttons[LStick_Down - BUTTON_HID_BEGIN]->GetStatus());
94
95 state.rstick_left.Assign(buttons[RStick_Left - BUTTON_HID_BEGIN]->GetStatus());
96 state.rstick_up.Assign(buttons[RStick_Up - BUTTON_HID_BEGIN]->GetStatus());
97 state.rstick_right.Assign(buttons[RStick_Right - BUTTON_HID_BEGIN]->GetStatus());
98 state.rstick_down.Assign(buttons[RStick_Down - BUTTON_HID_BEGIN]->GetStatus());
99
100 state.sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus());
101 state.sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus());
102
103 // TODO(shinyquagsire23): Analog stick vals
104
105 // TODO(shinyquagsire23): Update pad info proper, (circular buffers, timestamps, layouts)
106
107 // TODO(shinyquagsire23): Update touch info
108
109 // TODO(shinyquagsire23): Signal events
110
111 // Reschedule recurrent event
112 CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event);
113 }
114
37 // Handle to shared memory region designated to HID service 115 // Handle to shared memory region designated to HID service
38 Kernel::SharedPtr<Kernel::SharedMemory> shared_mem; 116 Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
117
118 // CoreTiming update events
119 CoreTiming::EventType* pad_update_event;
120
121 // Stored input state info
122 std::atomic<bool> is_device_reload_pending{true};
123 std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>
124 buttons;
39}; 125};
40 126
41class Hid final : public ServiceFramework<Hid> { 127class Hid final : public ServiceFramework<Hid> {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index f7621f62d..486e64800 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -5,10 +5,322 @@
5#pragma once 5#pragma once
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8#include "core/settings.h"
8 9
9namespace Service { 10namespace Service {
10namespace HID { 11namespace HID {
11 12
13// Begin enums and output structs
14
15enum ControllerType : u32 {
16 ControllerType_ProController = 1 << 0,
17 ControllerType_Handheld = 1 << 1,
18 ControllerType_JoyconPair = 1 << 2,
19 ControllerType_JoyconLeft = 1 << 3,
20 ControllerType_JoyconRight = 1 << 4,
21};
22
23enum ControllerLayoutType : u32 {
24 Layout_ProController = 0, // Pro Controller or HID gamepad
25 Layout_Handheld = 1, // Two Joy-Con docked to rails
26 Layout_Single = 2, // Horizontal single Joy-Con or pair of Joy-Con, adjusted for orientation
27 Layout_Left = 3, // Only raw left Joy-Con state, no orientation adjustment
28 Layout_Right = 4, // Only raw right Joy-Con state, no orientation adjustment
29 Layout_DefaultDigital = 5, // Same as next, but sticks have 8-direction values only
30 Layout_Default = 6, // Safe default, single Joy-Con have buttons/sticks rotated for orientation
31};
32
33enum ControllerColorDescription {
34 ColorDesc_ColorsNonexistent = 1 << 1,
35};
36
37enum ControllerConnectionState {
38 ConnectionState_Connected = 1 << 0,
39 ConnectionState_Wired = 1 << 1,
40};
41
42enum ControllerID {
43 Controller_Player1 = 0,
44 Controller_Player2 = 1,
45 Controller_Player3 = 2,
46 Controller_Player4 = 3,
47 Controller_Player5 = 4,
48 Controller_Player6 = 5,
49 Controller_Player7 = 6,
50 Controller_Player8 = 7,
51 Controller_Handheld = 8,
52 Controller_Unknown = 9,
53};
54
55// End enums and output structs
56
57// Begin TouchScreen
58
59struct TouchScreenHeader {
60 u64 timestampTicks;
61 u64 numEntries;
62 u64 latestEntry;
63 u64 maxEntryIndex;
64 u64 timestamp;
65};
66static_assert(sizeof(TouchScreenHeader) == 0x28,
67 "HID touch screen header structure has incorrect size");
68
69struct TouchScreenEntryHeader {
70 u64 timestamp;
71 u64 numTouches;
72};
73static_assert(sizeof(TouchScreenEntryHeader) == 0x10,
74 "HID touch screen entry header structure has incorrect size");
75
76struct TouchScreenEntryTouch {
77 u64 timestamp;
78 u32 padding;
79 u32 touchIndex;
80 u32 x;
81 u32 y;
82 u32 diameterX;
83 u32 diameterY;
84 u32 angle;
85 u32 padding_2;
86};
87static_assert(sizeof(TouchScreenEntryTouch) == 0x28,
88 "HID touch screen touch structure has incorrect size");
89
90struct TouchScreenEntry {
91 TouchScreenEntryHeader header;
92 std::array<TouchScreenEntryTouch, 16> touches;
93 u64 unk;
94};
95static_assert(sizeof(TouchScreenEntry) == 0x298,
96 "HID touch screen entry structure has incorrect size");
97
98struct TouchScreen {
99 TouchScreenHeader header;
100 std::array<TouchScreenEntry, 17> entries;
101 std::array<u8, 0x3c0> padding;
102};
103static_assert(sizeof(TouchScreen) == 0x3000, "HID touch screen structure has incorrect size");
104
105// End TouchScreen
106
107// Begin Mouse
108
109struct MouseHeader {
110 u64 timestampTicks;
111 u64 numEntries;
112 u64 latestEntry;
113 u64 maxEntryIndex;
114};
115static_assert(sizeof(MouseHeader) == 0x20, "HID mouse header structure has incorrect size");
116
117struct MouseButtonState {
118 union {
119 u64 hex{};
120
121 // Buttons
122 BitField<0, 1, u64> left;
123 BitField<1, 1, u64> right;
124 BitField<2, 1, u64> middle;
125 BitField<3, 1, u64> forward;
126 BitField<4, 1, u64> back;
127 };
128};
129
130struct MouseEntry {
131 u64 timestamp;
132 u64 timestamp_2;
133 u32 x;
134 u32 y;
135 u32 velocityX;
136 u32 velocityY;
137 u32 scrollVelocityX;
138 u32 scrollVelocityY;
139 MouseButtonState buttons;
140};
141static_assert(sizeof(MouseEntry) == 0x30, "HID mouse entry structure has incorrect size");
142
143struct Mouse {
144 MouseHeader header;
145 std::array<MouseEntry, 17> entries;
146 std::array<u8, 0xB0> padding;
147};
148static_assert(sizeof(Mouse) == 0x400, "HID mouse structure has incorrect size");
149
150// End Mouse
151
152// Begin Keyboard
153
154struct KeyboardHeader {
155 u64 timestampTicks;
156 u64 numEntries;
157 u64 latestEntry;
158 u64 maxEntryIndex;
159};
160static_assert(sizeof(KeyboardHeader) == 0x20, "HID keyboard header structure has incorrect size");
161
162struct KeyboardModifierKeyState {
163 union {
164 u64 hex{};
165
166 // Buttons
167 BitField<0, 1, u64> lctrl;
168 BitField<1, 1, u64> lshift;
169 BitField<2, 1, u64> lalt;
170 BitField<3, 1, u64> lmeta;
171 BitField<4, 1, u64> rctrl;
172 BitField<5, 1, u64> rshift;
173 BitField<6, 1, u64> ralt;
174 BitField<7, 1, u64> rmeta;
175 BitField<8, 1, u64> capslock;
176 BitField<9, 1, u64> scrolllock;
177 BitField<10, 1, u64> numlock;
178 };
179};
180
181struct KeyboardEntry {
182 u64 timestamp;
183 u64 timestamp_2;
184 KeyboardModifierKeyState modifier;
185 u32 keys[8];
186};
187static_assert(sizeof(KeyboardEntry) == 0x38, "HID keyboard entry structure has incorrect size");
188
189struct Keyboard {
190 KeyboardHeader header;
191 std::array<KeyboardEntry, 17> entries;
192 std::array<u8, 0x28> padding;
193};
194static_assert(sizeof(Keyboard) == 0x400, "HID keyboard structure has incorrect size");
195
196// End Keyboard
197
198// Begin Controller
199
200struct ControllerMAC {
201 u64 timestamp;
202 std::array<u8, 0x8> mac;
203 u64 unk;
204 u64 timestamp_2;
205};
206static_assert(sizeof(ControllerMAC) == 0x20, "HID controller MAC structure has incorrect size");
207
208struct ControllerHeader {
209 u32 type;
210 u32 isHalf;
211 u32 singleColorsDescriptor;
212 u32 singleColorBody;
213 u32 singleColorButtons;
214 u32 splitColorsDescriptor;
215 u32 leftColorBody;
216 u32 leftColorButtons;
217 u32 rightColorBody;
218 u32 rightColorbuttons;
219};
220static_assert(sizeof(ControllerHeader) == 0x28,
221 "HID controller header structure has incorrect size");
222
223struct ControllerLayoutHeader {
224 u64 timestampTicks;
225 u64 numEntries;
226 u64 latestEntry;
227 u64 maxEntryIndex;
228};
229static_assert(sizeof(ControllerLayoutHeader) == 0x20,
230 "HID controller layout header structure has incorrect size");
231
232struct ControllerPadState {
233 union {
234 u64 hex{};
235
236 // Buttons
237 BitField<0, 1, u64> a;
238 BitField<1, 1, u64> b;
239 BitField<2, 1, u64> x;
240 BitField<3, 1, u64> y;
241 BitField<4, 1, u64> lstick;
242 BitField<5, 1, u64> rstick;
243 BitField<6, 1, u64> l;
244 BitField<7, 1, u64> r;
245 BitField<8, 1, u64> zl;
246 BitField<9, 1, u64> zr;
247 BitField<10, 1, u64> plus;
248 BitField<11, 1, u64> minus;
249
250 // D-pad buttons
251 BitField<12, 1, u64> dleft;
252 BitField<13, 1, u64> dup;
253 BitField<14, 1, u64> dright;
254 BitField<15, 1, u64> ddown;
255
256 // Left stick directions
257 BitField<16, 1, u64> lstick_left;
258 BitField<17, 1, u64> lstick_up;
259 BitField<18, 1, u64> lstick_right;
260 BitField<19, 1, u64> lstick_down;
261
262 // Right stick directions
263 BitField<20, 1, u64> rstick_left;
264 BitField<21, 1, u64> rstick_up;
265 BitField<22, 1, u64> rstick_right;
266 BitField<23, 1, u64> rstick_down;
267
268 BitField<24, 1, u64> sl;
269 BitField<25, 1, u64> sr;
270 };
271};
272
273struct ControllerInputEntry {
274 u64 timestamp;
275 u64 timestamp_2;
276 ControllerPadState buttons;
277 u32 joystickLeftX;
278 u32 joystickLeftY;
279 u32 joystickRightX;
280 u32 joystickRightY;
281 u64 connectionState;
282};
283static_assert(sizeof(ControllerInputEntry) == 0x30,
284 "HID controller input entry structure has incorrect size");
285
286struct ControllerLayout {
287 ControllerLayoutHeader header;
288 std::array<ControllerInputEntry, 17> entries;
289};
290static_assert(sizeof(ControllerLayout) == 0x350,
291 "HID controller layout structure has incorrect size");
292
293struct Controller {
294 ControllerHeader header;
295 std::array<ControllerLayout, 7> layouts;
296 std::array<u8, 0x2a70> unk_1;
297 ControllerMAC macLeft;
298 ControllerMAC macRight;
299 std::array<u8, 0xdf8> unk_2;
300};
301static_assert(sizeof(Controller) == 0x5000, "HID controller structure has incorrect size");
302
303// End Controller
304
305struct SharedMemory {
306 std::array<u8, 0x400> header;
307 TouchScreen touchscreen;
308 Mouse mouse;
309 Keyboard keyboard;
310 std::array<u8, 0x400> unkSection1;
311 std::array<u8, 0x400> unkSection2;
312 std::array<u8, 0x400> unkSection3;
313 std::array<u8, 0x400> unkSection4;
314 std::array<u8, 0x200> unkSection5;
315 std::array<u8, 0x200> unkSection6;
316 std::array<u8, 0x200> unkSection7;
317 std::array<u8, 0x800> unkSection8;
318 std::array<u8, 0x4000> controllerSerials;
319 std::array<Controller, 10> controllers;
320 std::array<u8, 0x4600> unkSection9;
321};
322static_assert(sizeof(SharedMemory) == 0x40000, "HID Shared Memory structure has incorrect size");
323
12/// Reload input devices. Used when input configuration changed 324/// Reload input devices. Used when input configuration changed
13void ReloadInputDevices(); 325void ReloadInputDevices();
14 326