summaryrefslogtreecommitdiff
path: root/src/core
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
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')
-rw-r--r--src/core/hle/service/hid/hid.cpp86
-rw-r--r--src/core/hle/service/hid/hid.h312
-rw-r--r--src/core/settings.h69
3 files changed, 450 insertions, 17 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
diff --git a/src/core/settings.h b/src/core/settings.h
index f2c88e5d4..bd9a3d9fe 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -16,52 +16,87 @@ enum Values {
16 B, 16 B,
17 X, 17 X,
18 Y, 18 Y,
19 Up, 19 LStick,
20 Down, 20 RStick,
21 Left,
22 Right,
23 L, 21 L,
24 R, 22 R,
25 Start,
26 Select,
27
28 ZL, 23 ZL,
29 ZR, 24 ZR,
25 Plus,
26 Minus,
27
28 DLeft,
29 DUp,
30 DRight,
31 DDown,
32
33 LStick_Left,
34 LStick_Up,
35 LStick_Right,
36 LStick_Down,
37
38 RStick_Left,
39 RStick_Up,
40 RStick_Right,
41 RStick_Down,
42
43 SL,
44 SR,
30 45
31 Home, 46 Home,
47 Screenshot,
32 48
33 NumButtons, 49 NumButtons,
34}; 50};
35 51
36constexpr int BUTTON_HID_BEGIN = A; 52constexpr int BUTTON_HID_BEGIN = A;
37constexpr int BUTTON_IR_BEGIN = ZL;
38constexpr int BUTTON_NS_BEGIN = Home; 53constexpr int BUTTON_NS_BEGIN = Home;
39 54
40constexpr int BUTTON_HID_END = BUTTON_IR_BEGIN; 55constexpr int BUTTON_HID_END = BUTTON_NS_BEGIN;
41constexpr int BUTTON_IR_END = BUTTON_NS_BEGIN;
42constexpr int BUTTON_NS_END = NumButtons; 56constexpr int BUTTON_NS_END = NumButtons;
43 57
44constexpr int NUM_BUTTONS_HID = BUTTON_HID_END - BUTTON_HID_BEGIN; 58constexpr int NUM_BUTTONS_HID = BUTTON_HID_END - BUTTON_HID_BEGIN;
45constexpr int NUM_BUTTONS_IR = BUTTON_IR_END - BUTTON_IR_BEGIN;
46constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN; 59constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN;
47 60
48static const std::array<const char*, NumButtons> mapping = {{ 61static const std::array<const char*, NumButtons> mapping = {{
49 "button_a", "button_b", "button_x", "button_y", "button_up", "button_down", "button_left", 62 "button_a",
50 "button_right", "button_l", "button_r", "button_start", "button_select", "button_zl", 63 "button_b",
51 "button_zr", "button_home", 64 "button_x",
65 "button_y",
66 "button_lstick",
67 "button_rstick",
68 "button_l",
69 "button_r",
70 "button_zl",
71 "button_zr",
72 "button_plus",
73 "button_minus",
74 "button_dleft",
75 "button_dup",
76 "button_dright",
77 "button_ddown",
78 "button_lstick_left",
79 "button_lstick_up",
80 "button_lstick_right",
81 "button_lstick_down",
82 "button_sl",
83 "button_sr",
84 "button_home",
85 "button_screenshot",
52}}; 86}};
53} // namespace NativeButton 87} // namespace NativeButton
54 88
55namespace NativeAnalog { 89namespace NativeAnalog {
56enum Values { 90enum Values {
57 CirclePad, 91 LStick,
58 CStick, 92 RStick,
59 93
60 NumAnalogs, 94 NumAnalogs,
61}; 95};
62 96
63static const std::array<const char*, NumAnalogs> mapping = {{ 97static const std::array<const char*, NumAnalogs> mapping = {{
64 "circle_pad", "c_stick", 98 "lstick",
99 "rstick",
65}}; 100}};
66} // namespace NativeAnalog 101} // namespace NativeAnalog
67 102