OLD | NEW |
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "device/gamepad/gamepad_data_fetcher.h" | 5 #include "device/gamepad/gamepad_pad_state_provider.h" |
6 | |
7 #include <stddef.h> | |
8 #include <string.h> | |
9 | 6 |
10 #include <cmath> | 7 #include <cmath> |
11 | 8 |
12 #include "base/logging.h" | 9 #include "device/gamepad/gamepad_data_fetcher.h" |
13 #include "build/build_config.h" | 10 #include "third_party/WebKit/public/platform/WebGamepads.h" |
14 | |
15 namespace { | |
16 | |
17 #if !defined(OS_ANDROID) | |
18 const float kMinAxisResetValue = 0.1f; | |
19 #endif | |
20 | |
21 } // namespace | |
22 | |
23 namespace device { | |
24 | 11 |
25 using blink::WebGamepad; | 12 using blink::WebGamepad; |
26 using blink::WebGamepads; | 13 using blink::WebGamepads; |
27 | 14 |
28 #if !defined(OS_ANDROID) | 15 namespace device { |
29 void GamepadDataFetcher::MapAndSanitizeGamepadData(PadState* pad_state, | 16 |
30 WebGamepad* pad) { | 17 namespace { |
| 18 |
| 19 const float kMinAxisResetValue = 0.1f; |
| 20 |
| 21 } // namespace |
| 22 |
| 23 GamepadPadStateProvider::GamepadPadStateProvider() { |
| 24 pad_states_.reset(new PadState[WebGamepads::itemsLengthCap]); |
| 25 |
| 26 for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) |
| 27 ClearPadState(pad_states_.get()[i]); |
| 28 } |
| 29 |
| 30 GamepadPadStateProvider::~GamepadPadStateProvider() {} |
| 31 |
| 32 PadState* GamepadPadStateProvider::GetPadState(GamepadSource source, |
| 33 int source_id) { |
| 34 // Check to see if the device already has a reserved slot |
| 35 PadState* empty_slot = nullptr; |
| 36 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { |
| 37 PadState& state = pad_states_.get()[i]; |
| 38 if (state.source == source && state.source_id == source_id) { |
| 39 // Retrieving the pad state marks this gamepad as active. |
| 40 state.active_state = GAMEPAD_ACTIVE; |
| 41 return &state; |
| 42 } |
| 43 if (!empty_slot && state.source == GAMEPAD_SOURCE_NONE) |
| 44 empty_slot = &state; |
| 45 } |
| 46 if (empty_slot) { |
| 47 empty_slot->source = source; |
| 48 empty_slot->source_id = source_id; |
| 49 empty_slot->active_state = GAMEPAD_NEWLY_ACTIVE; |
| 50 } |
| 51 return empty_slot; |
| 52 } |
| 53 |
| 54 void GamepadPadStateProvider::ClearPadState(PadState& state) { |
| 55 memset(&state, 0, sizeof(PadState)); |
| 56 } |
| 57 |
| 58 void GamepadPadStateProvider::InitializeDataFetcher( |
| 59 GamepadDataFetcher* fetcher) { |
| 60 fetcher->InitializeProvider(this); |
| 61 } |
| 62 |
| 63 void GamepadPadStateProvider::MapAndSanitizeGamepadData(PadState* pad_state, |
| 64 WebGamepad* pad, |
| 65 bool sanitize) { |
31 DCHECK(pad_state); | 66 DCHECK(pad_state); |
32 DCHECK(pad); | 67 DCHECK(pad); |
33 | 68 |
34 if (!pad_state->data.connected) { | 69 if (!pad_state->data.connected) { |
35 memset(pad, 0, sizeof(WebGamepad)); | 70 memset(pad, 0, sizeof(WebGamepad)); |
36 return; | 71 return; |
37 } | 72 } |
38 | 73 |
39 // Copy the current state to the output buffer, using the mapping | 74 // Copy the current state to the output buffer, using the mapping |
40 // function, if there is one available. | 75 // function, if there is one available. |
41 if (pad_state->mapper) | 76 if (pad_state->mapper) |
42 pad_state->mapper(pad_state->data, pad); | 77 pad_state->mapper(pad_state->data, pad); |
43 else | 78 else |
44 *pad = pad_state->data; | 79 *pad = pad_state->data; |
45 | 80 |
| 81 pad->connected = true; |
| 82 |
| 83 if (!sanitize) |
| 84 return; |
| 85 |
46 // About sanitization: Gamepads may report input event if the user is not | 86 // About sanitization: Gamepads may report input event if the user is not |
47 // interacting with it, due to hardware problems or environmental ones (pad | 87 // interacting with it, due to hardware problems or environmental ones (pad |
48 // has something heavy leaning against an axis.) This may cause user gestures | 88 // has something heavy leaning against an axis.) This may cause user gestures |
49 // to be detected erroniously, exposing gamepad information when the user had | 89 // to be detected erroniously, exposing gamepad information when the user had |
50 // no intention of doing so. To avoid this we require that each button or axis | 90 // no intention of doing so. To avoid this we require that each button or axis |
51 // report being at rest (zero) at least once before exposing its value to the | 91 // report being at rest (zero) at least once before exposing its value to the |
52 // Gamepad API. This state is tracked by the axis_mask and button_mask | 92 // Gamepad API. This state is tracked by the axis_mask and button_mask |
53 // bitfields. If the bit for an axis or button is 0 it means the axis has | 93 // bitfields. If the bit for an axis or button is 0 it means the axis has |
54 // never reported being at rest, and the value will be forced to zero. | 94 // never reported being at rest, and the value will be forced to zero. |
55 | 95 |
(...skipping 19 matching lines...) Expand all Loading... |
75 if (!pad->buttons[button].pressed) { | 115 if (!pad->buttons[button].pressed) { |
76 pad_state->button_mask |= 1 << button; | 116 pad_state->button_mask |= 1 << button; |
77 } else { | 117 } else { |
78 pad->buttons[button].pressed = false; | 118 pad->buttons[button].pressed = false; |
79 pad->buttons[button].value = 0.0f; | 119 pad->buttons[button].value = 0.0f; |
80 } | 120 } |
81 } | 121 } |
82 } | 122 } |
83 } | 123 } |
84 } | 124 } |
85 #endif | |
86 | 125 |
87 } // namespace device | 126 } // namespace device |
OLD | NEW |