OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/gamepad/xbox_data_fetcher_mac.h" | 5 #include "content/browser/gamepad/xbox_data_fetcher_mac.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <limits> | 9 #include <limits> |
10 | 10 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 bool bumper_left : 1; | 62 bool bumper_left : 1; |
63 bool bumper_right : 1; | 63 bool bumper_right : 1; |
64 bool guide : 1; | 64 bool guide : 1; |
65 bool dummy1 : 1; // Always 0. | 65 bool dummy1 : 1; // Always 0. |
66 | 66 |
67 bool a : 1; | 67 bool a : 1; |
68 bool b : 1; | 68 bool b : 1; |
69 bool x : 1; | 69 bool x : 1; |
70 bool y : 1; | 70 bool y : 1; |
71 | 71 |
72 uint8 trigger_left; | 72 uint8_t trigger_left; |
73 uint8 trigger_right; | 73 uint8_t trigger_right; |
74 | 74 |
75 int16 stick_left_x; | 75 int16_t stick_left_x; |
76 int16 stick_left_y; | 76 int16_t stick_left_y; |
77 int16 stick_right_x; | 77 int16_t stick_right_x; |
78 int16 stick_right_y; | 78 int16_t stick_right_y; |
79 | 79 |
80 // Always 0. | 80 // Always 0. |
81 uint32 dummy2; | 81 uint32_t dummy2; |
82 uint16 dummy3; | 82 uint16_t dummy3; |
83 }; | 83 }; |
84 | 84 |
85 struct XboxOneButtonData { | 85 struct XboxOneButtonData { |
86 bool sync : 1; | 86 bool sync : 1; |
87 bool dummy1 : 1; // Always 0. | 87 bool dummy1 : 1; // Always 0. |
88 bool start : 1; | 88 bool start : 1; |
89 bool back : 1; | 89 bool back : 1; |
90 | 90 |
91 bool a : 1; | 91 bool a : 1; |
92 bool b : 1; | 92 bool b : 1; |
93 bool x : 1; | 93 bool x : 1; |
94 bool y : 1; | 94 bool y : 1; |
95 | 95 |
96 bool dpad_up : 1; | 96 bool dpad_up : 1; |
97 bool dpad_down : 1; | 97 bool dpad_down : 1; |
98 bool dpad_left : 1; | 98 bool dpad_left : 1; |
99 bool dpad_right : 1; | 99 bool dpad_right : 1; |
100 | 100 |
101 bool bumper_left : 1; | 101 bool bumper_left : 1; |
102 bool bumper_right : 1; | 102 bool bumper_right : 1; |
103 bool stick_left_click : 1; | 103 bool stick_left_click : 1; |
104 bool stick_right_click : 1; | 104 bool stick_right_click : 1; |
105 | 105 |
106 uint16 trigger_left; | 106 uint16_t trigger_left; |
107 uint16 trigger_right; | 107 uint16_t trigger_right; |
108 | 108 |
109 int16 stick_left_x; | 109 int16_t stick_left_x; |
110 int16 stick_left_y; | 110 int16_t stick_left_y; |
111 int16 stick_right_x; | 111 int16_t stick_right_x; |
112 int16 stick_right_y; | 112 int16_t stick_right_y; |
113 }; | 113 }; |
114 #pragma pack(pop) | 114 #pragma pack(pop) |
115 | 115 |
116 static_assert(sizeof(Xbox360ButtonData) == 18, "xbox button data wrong size"); | 116 static_assert(sizeof(Xbox360ButtonData) == 18, "xbox button data wrong size"); |
117 static_assert(sizeof(XboxOneButtonData) == 14, "xbox button data wrong size"); | 117 static_assert(sizeof(XboxOneButtonData) == 14, "xbox button data wrong size"); |
118 | 118 |
119 // From MSDN: | 119 // From MSDN: |
120 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee417001(v=vs.85).asp
x#dead_zone | 120 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee417001(v=vs.85).asp
x#dead_zone |
121 const int16 kLeftThumbDeadzone = 7849; | 121 const int16_t kLeftThumbDeadzone = 7849; |
122 const int16 kRightThumbDeadzone = 8689; | 122 const int16_t kRightThumbDeadzone = 8689; |
123 const uint8 kXbox360TriggerDeadzone = 30; | 123 const uint8_t kXbox360TriggerDeadzone = 30; |
124 const uint16 kXboxOneTriggerMax = 1023; | 124 const uint16_t kXboxOneTriggerMax = 1023; |
125 const uint16 kXboxOneTriggerDeadzone = 120; | 125 const uint16_t kXboxOneTriggerDeadzone = 120; |
126 | 126 |
127 void NormalizeAxis(int16 x, | 127 void NormalizeAxis(int16_t x, |
128 int16 y, | 128 int16_t y, |
129 int16 deadzone, | 129 int16_t deadzone, |
130 float* x_out, | 130 float* x_out, |
131 float* y_out) { | 131 float* y_out) { |
132 float x_val = x; | 132 float x_val = x; |
133 float y_val = y; | 133 float y_val = y; |
134 | 134 |
135 // Determine how far the stick is pushed. | 135 // Determine how far the stick is pushed. |
136 float real_magnitude = std::sqrt(x_val * x_val + y_val * y_val); | 136 float real_magnitude = std::sqrt(x_val * x_val + y_val * y_val); |
137 | 137 |
138 // Check if the controller is outside a circular dead zone. | 138 // Check if the controller is outside a circular dead zone. |
139 if (real_magnitude > deadzone) { | 139 if (real_magnitude > deadzone) { |
140 // Clip the magnitude at its expected maximum value. | 140 // Clip the magnitude at its expected maximum value. |
141 float magnitude = std::min(32767.0f, real_magnitude); | 141 float magnitude = std::min(32767.0f, real_magnitude); |
142 | 142 |
143 // Adjust magnitude relative to the end of the dead zone. | 143 // Adjust magnitude relative to the end of the dead zone. |
144 magnitude -= deadzone; | 144 magnitude -= deadzone; |
145 | 145 |
146 // Normalize the magnitude with respect to its expected range giving a | 146 // Normalize the magnitude with respect to its expected range giving a |
147 // magnitude value of 0.0 to 1.0 | 147 // magnitude value of 0.0 to 1.0 |
148 float ratio = (magnitude / (32767 - deadzone)) / real_magnitude; | 148 float ratio = (magnitude / (32767 - deadzone)) / real_magnitude; |
149 | 149 |
150 // Y is negated because xbox controllers have an opposite sign from | 150 // Y is negated because xbox controllers have an opposite sign from |
151 // the 'standard controller' recommendations. | 151 // the 'standard controller' recommendations. |
152 *x_out = x_val * ratio; | 152 *x_out = x_val * ratio; |
153 *y_out = -y_val * ratio; | 153 *y_out = -y_val * ratio; |
154 } else { | 154 } else { |
155 // If the controller is in the deadzone zero out the magnitude. | 155 // If the controller is in the deadzone zero out the magnitude. |
156 *x_out = *y_out = 0.0f; | 156 *x_out = *y_out = 0.0f; |
157 } | 157 } |
158 } | 158 } |
159 | 159 |
160 float NormalizeTrigger(uint8 value) { | 160 float NormalizeTrigger(uint8_t value) { |
161 return value < kXbox360TriggerDeadzone ? 0 : | 161 return value < kXbox360TriggerDeadzone |
162 static_cast<float>(value - kXbox360TriggerDeadzone) / | 162 ? 0 |
163 (std::numeric_limits<uint8>::max() - kXbox360TriggerDeadzone); | 163 : static_cast<float>(value - kXbox360TriggerDeadzone) / |
| 164 (std::numeric_limits<uint8_t>::max() - |
| 165 kXbox360TriggerDeadzone); |
164 } | 166 } |
165 | 167 |
166 float NormalizeXboxOneTrigger(uint16 value) { | 168 float NormalizeXboxOneTrigger(uint16_t value) { |
167 return value < kXboxOneTriggerDeadzone ? 0 : | 169 return value < kXboxOneTriggerDeadzone ? 0 : |
168 static_cast<float>(value - kXboxOneTriggerDeadzone) / | 170 static_cast<float>(value - kXboxOneTriggerDeadzone) / |
169 (kXboxOneTriggerMax - kXboxOneTriggerDeadzone); | 171 (kXboxOneTriggerMax - kXboxOneTriggerDeadzone); |
170 } | 172 } |
171 | 173 |
172 void NormalizeXbox360ButtonData(const Xbox360ButtonData& data, | 174 void NormalizeXbox360ButtonData(const Xbox360ButtonData& data, |
173 XboxController::Data* normalized_data) { | 175 XboxController::Data* normalized_data) { |
174 normalized_data->buttons[0] = data.a; | 176 normalized_data->buttons[0] = data.a; |
175 normalized_data->buttons[1] = data.b; | 177 normalized_data->buttons[1] = data.b; |
176 normalized_data->buttons[2] = data.x; | 178 normalized_data->buttons[2] = data.x; |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 | 393 |
392 CFRunLoopSourceRef source_ref; | 394 CFRunLoopSourceRef source_ref; |
393 kr = (*interface_)->CreateInterfaceAsyncEventSource(interface_, &source_ref); | 395 kr = (*interface_)->CreateInterfaceAsyncEventSource(interface_, &source_ref); |
394 if (kr != KERN_SUCCESS || !source_ref) | 396 if (kr != KERN_SUCCESS || !source_ref) |
395 return false; | 397 return false; |
396 source_.reset(source_ref); | 398 source_.reset(source_ref); |
397 CFRunLoopAddSource(CFRunLoopGetCurrent(), source_, kCFRunLoopDefaultMode); | 399 CFRunLoopAddSource(CFRunLoopGetCurrent(), source_, kCFRunLoopDefaultMode); |
398 | 400 |
399 // The interface should have two pipes. Pipe 1 with direction kUSBIn and pipe | 401 // The interface should have two pipes. Pipe 1 with direction kUSBIn and pipe |
400 // 2 with direction kUSBOut. Both pipes should have type kUSBInterrupt. | 402 // 2 with direction kUSBOut. Both pipes should have type kUSBInterrupt. |
401 uint8 num_endpoints; | 403 uint8_t num_endpoints; |
402 kr = (*interface_)->GetNumEndpoints(interface_, &num_endpoints); | 404 kr = (*interface_)->GetNumEndpoints(interface_, &num_endpoints); |
403 if (kr != KERN_SUCCESS || num_endpoints < 2) | 405 if (kr != KERN_SUCCESS || num_endpoints < 2) |
404 return false; | 406 return false; |
405 | 407 |
406 for (int i = 1; i <= 2; i++) { | 408 for (int i = 1; i <= 2; i++) { |
407 uint8 direction; | 409 uint8_t direction; |
408 uint8 number; | 410 uint8_t number; |
409 uint8 transfer_type; | 411 uint8_t transfer_type; |
410 uint16 max_packet_size; | 412 uint16_t max_packet_size; |
411 uint8 interval; | 413 uint8_t interval; |
412 | 414 |
413 kr = (*interface_)->GetPipeProperties(interface_, | 415 kr = (*interface_)->GetPipeProperties(interface_, |
414 i, | 416 i, |
415 &direction, | 417 &direction, |
416 &number, | 418 &number, |
417 &transfer_type, | 419 &transfer_type, |
418 &max_packet_size, | 420 &max_packet_size, |
419 &interval); | 421 &interval); |
420 if (kr != KERN_SUCCESS || transfer_type != kUSBInterrupt) { | 422 if (kr != KERN_SUCCESS || transfer_type != kUSBInterrupt) { |
421 return false; | 423 return false; |
422 } | 424 } |
423 if (i == read_endpoint_) { | 425 if (i == read_endpoint_) { |
424 if (direction != kUSBIn) | 426 if (direction != kUSBIn) |
425 return false; | 427 return false; |
426 read_buffer_.reset(new uint8[max_packet_size]); | 428 read_buffer_.reset(new uint8_t[max_packet_size]); |
427 read_buffer_size_ = max_packet_size; | 429 read_buffer_size_ = max_packet_size; |
428 QueueRead(); | 430 QueueRead(); |
429 } else if (i == control_endpoint_) { | 431 } else if (i == control_endpoint_) { |
430 if (direction != kUSBOut) | 432 if (direction != kUSBOut) |
431 return false; | 433 return false; |
432 if (controller_type_ == XBOX_ONE_CONTROLLER) | 434 if (controller_type_ == XBOX_ONE_CONTROLLER) |
433 WriteXboxOneInit(); | 435 WriteXboxOneInit(); |
434 } | 436 } |
435 } | 437 } |
436 | 438 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 } | 516 } |
515 | 517 |
516 void XboxController::ProcessXbox360Packet(size_t length) { | 518 void XboxController::ProcessXbox360Packet(size_t length) { |
517 if (length < 2) | 519 if (length < 2) |
518 return; | 520 return; |
519 DCHECK(length <= read_buffer_size_); | 521 DCHECK(length <= read_buffer_size_); |
520 if (length > read_buffer_size_) { | 522 if (length > read_buffer_size_) { |
521 IOError(); | 523 IOError(); |
522 return; | 524 return; |
523 } | 525 } |
524 uint8* buffer = read_buffer_.get(); | 526 uint8_t* buffer = read_buffer_.get(); |
525 | 527 |
526 if (buffer[1] != length) | 528 if (buffer[1] != length) |
527 // Length in packet doesn't match length reported by USB. | 529 // Length in packet doesn't match length reported by USB. |
528 return; | 530 return; |
529 | 531 |
530 uint8 type = buffer[0]; | 532 uint8_t type = buffer[0]; |
531 buffer += 2; | 533 buffer += 2; |
532 length -= 2; | 534 length -= 2; |
533 switch (type) { | 535 switch (type) { |
534 case STATUS_MESSAGE_BUTTONS: { | 536 case STATUS_MESSAGE_BUTTONS: { |
535 if (length != sizeof(Xbox360ButtonData)) | 537 if (length != sizeof(Xbox360ButtonData)) |
536 return; | 538 return; |
537 Xbox360ButtonData* data = reinterpret_cast<Xbox360ButtonData*>(buffer); | 539 Xbox360ButtonData* data = reinterpret_cast<Xbox360ButtonData*>(buffer); |
538 Data normalized_data; | 540 Data normalized_data; |
539 NormalizeXbox360ButtonData(*data, &normalized_data); | 541 NormalizeXbox360ButtonData(*data, &normalized_data); |
540 delegate_->XboxControllerGotData(this, normalized_data); | 542 delegate_->XboxControllerGotData(this, normalized_data); |
(...skipping 14 matching lines...) Expand all Loading... |
555 } | 557 } |
556 | 558 |
557 void XboxController::ProcessXboxOnePacket(size_t length) { | 559 void XboxController::ProcessXboxOnePacket(size_t length) { |
558 if (length < 2) | 560 if (length < 2) |
559 return; | 561 return; |
560 DCHECK(length <= read_buffer_size_); | 562 DCHECK(length <= read_buffer_size_); |
561 if (length > read_buffer_size_) { | 563 if (length > read_buffer_size_) { |
562 IOError(); | 564 IOError(); |
563 return; | 565 return; |
564 } | 566 } |
565 uint8* buffer = read_buffer_.get(); | 567 uint8_t* buffer = read_buffer_.get(); |
566 | 568 |
567 uint8 type = buffer[0]; | 569 uint8_t type = buffer[0]; |
568 buffer += 4; | 570 buffer += 4; |
569 length -= 4; | 571 length -= 4; |
570 switch (type) { | 572 switch (type) { |
571 case XBOX_ONE_STATUS_MESSAGE_BUTTONS: { | 573 case XBOX_ONE_STATUS_MESSAGE_BUTTONS: { |
572 if (length != sizeof(XboxOneButtonData)) | 574 if (length != sizeof(XboxOneButtonData)) |
573 return; | 575 return; |
574 XboxOneButtonData* data = reinterpret_cast<XboxOneButtonData*>(buffer); | 576 XboxOneButtonData* data = reinterpret_cast<XboxOneButtonData*>(buffer); |
575 Data normalized_data; | 577 Data normalized_data; |
576 NormalizeXboxOneButtonData(*data, &normalized_data); | 578 NormalizeXboxOneButtonData(*data, &normalized_data); |
577 delegate_->XboxControllerGotData(this, normalized_data); | 579 delegate_->XboxControllerGotData(this, normalized_data); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
776 controllers_.insert(controller); | 778 controllers_.insert(controller); |
777 delegate_->XboxDeviceAdd(controller); | 779 delegate_->XboxDeviceAdd(controller); |
778 } | 780 } |
779 | 781 |
780 void XboxDataFetcher::RemoveController(XboxController* controller) { | 782 void XboxDataFetcher::RemoveController(XboxController* controller) { |
781 delegate_->XboxDeviceRemove(controller); | 783 delegate_->XboxDeviceRemove(controller); |
782 controllers_.erase(controller); | 784 controllers_.erase(controller); |
783 delete controller; | 785 delete controller; |
784 } | 786 } |
785 | 787 |
786 void XboxDataFetcher::RemoveControllerByLocationID(uint32 location_id) { | 788 void XboxDataFetcher::RemoveControllerByLocationID(uint32_t location_id) { |
787 XboxController* controller = NULL; | 789 XboxController* controller = NULL; |
788 for (std::set<XboxController*>::iterator i = controllers_.begin(); | 790 for (std::set<XboxController*>::iterator i = controllers_.begin(); |
789 i != controllers_.end(); | 791 i != controllers_.end(); |
790 ++i) { | 792 ++i) { |
791 if ((*i)->location_id() == location_id) { | 793 if ((*i)->location_id() == location_id) { |
792 controller = *i; | 794 controller = *i; |
793 break; | 795 break; |
794 } | 796 } |
795 } | 797 } |
796 if (controller) | 798 if (controller) |
797 RemoveController(controller); | 799 RemoveController(controller); |
798 } | 800 } |
799 | 801 |
800 void XboxDataFetcher::XboxControllerGotData(XboxController* controller, | 802 void XboxDataFetcher::XboxControllerGotData(XboxController* controller, |
801 const XboxController::Data& data) { | 803 const XboxController::Data& data) { |
802 delegate_->XboxValueChanged(controller, data); | 804 delegate_->XboxValueChanged(controller, data); |
803 } | 805 } |
804 | 806 |
805 void XboxDataFetcher::XboxControllerError(XboxController* controller) { | 807 void XboxDataFetcher::XboxControllerError(XboxController* controller) { |
806 RemoveController(controller); | 808 RemoveController(controller); |
807 } | 809 } |
OLD | NEW |