mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 08:44:19 -04:00
device: added checks, robustness, debug output for Windows raw input
This commit is contained in:
parent
0d5d6466f1
commit
d106fd6a3a
@ -315,7 +315,8 @@ on_input_device_arrival(HANDLE handle) {
|
|||||||
|
|
||||||
// Is this an XInput device? If so, handle it via XInput, which allows us
|
// Is this an XInput device? If so, handle it via XInput, which allows us
|
||||||
// to handle independent left/right triggers as well as vibration output.
|
// to handle independent left/right triggers as well as vibration output.
|
||||||
if (info.dwType == RIM_TYPEHID && strstr(path, "&IG_") != nullptr) {
|
if (info.dwType == RIM_TYPEHID && strstr(path, "&IG_") != nullptr &&
|
||||||
|
XInputDevice::init_xinput()) {
|
||||||
// This is a device we should handle via the XInput API. Check which of
|
// This is a device we should handle via the XInput API. Check which of
|
||||||
// the four players was the lucky one.
|
// the four players was the lucky one.
|
||||||
if (_xinput_device0.check_arrival(info, inst, name, manufacturer)) {
|
if (_xinput_device0.check_arrival(info, inst, name, manufacturer)) {
|
||||||
|
@ -334,6 +334,14 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (device_cat.is_debug()) {
|
||||||
|
device_cat.debug()
|
||||||
|
<< "Found " << _device_class << " device \"" << _name << "\" with "
|
||||||
|
<< caps.NumberInputDataIndices << " data indices, "
|
||||||
|
<< caps.NumberInputButtonCaps << " button caps, "
|
||||||
|
<< caps.NumberInputValueCaps << " value caps\n";
|
||||||
|
}
|
||||||
|
|
||||||
// Do we have a button mapping?
|
// Do we have a button mapping?
|
||||||
static const ButtonHandle gamepad_buttons_common[] = {
|
static const ButtonHandle gamepad_buttons_common[] = {
|
||||||
ButtonHandle::none(),
|
ButtonHandle::none(),
|
||||||
@ -374,8 +382,11 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
|
|||||||
_axes.clear();
|
_axes.clear();
|
||||||
|
|
||||||
USHORT num_button_caps = caps.NumberInputButtonCaps;
|
USHORT num_button_caps = caps.NumberInputButtonCaps;
|
||||||
PHIDP_BUTTON_CAPS button_caps = (PHIDP_BUTTON_CAPS)alloca(num_button_caps * sizeof(HIDP_BUTTON_CAPS));
|
PHIDP_BUTTON_CAPS button_caps;
|
||||||
|
if (num_button_caps > 0u) {
|
||||||
|
button_caps = (PHIDP_BUTTON_CAPS)alloca(num_button_caps * sizeof(HIDP_BUTTON_CAPS));
|
||||||
_HidP_GetButtonCaps(HidP_Input, button_caps, &num_button_caps, buffer);
|
_HidP_GetButtonCaps(HidP_Input, button_caps, &num_button_caps, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
for (USHORT i = 0; i < num_button_caps; ++i) {
|
for (USHORT i = 0; i < num_button_caps; ++i) {
|
||||||
HIDP_BUTTON_CAPS &cap = button_caps[i];
|
HIDP_BUTTON_CAPS &cap = button_caps[i];
|
||||||
@ -396,13 +407,15 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
|
|||||||
if (device_cat.is_debug()) {
|
if (device_cat.is_debug()) {
|
||||||
device_cat.debug()
|
device_cat.debug()
|
||||||
<< "Found button: DataIndex=" << dec << cap.NotRange.DataIndex
|
<< "Found button: DataIndex=" << dec << cap.NotRange.DataIndex
|
||||||
<< ", ReportID=" << dec << (int)cap.ReportID
|
<< ", ReportID=" << (int)cap.ReportID
|
||||||
<< ", UsagePage=0x" << cap.UsagePage
|
<< ", UsagePage=0x" << hex << cap.UsagePage
|
||||||
<< ", Usage=0x" << cap.NotRange.Usage
|
<< ", Usage=0x" << cap.NotRange.Usage
|
||||||
<< dec << "\n";
|
<< dec << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nassertd(cap.Range.DataIndexMin + upper < _indices.size()) continue;
|
||||||
|
|
||||||
// Windows will only tell us which buttons in a report are "on", so we
|
// Windows will only tell us which buttons in a report are "on", so we
|
||||||
// need to keep track of which buttons exist in which report so that we
|
// need to keep track of which buttons exist in which report so that we
|
||||||
// can figure out which ones are off.
|
// can figure out which ones are off.
|
||||||
@ -429,6 +442,9 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
|
|||||||
handle = MouseButton::button(button);
|
handle = MouseButton::button(button);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int button_index = _buttons.size();
|
int button_index = _buttons.size();
|
||||||
@ -439,8 +455,11 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
USHORT num_value_caps = caps.NumberInputValueCaps;
|
USHORT num_value_caps = caps.NumberInputValueCaps;
|
||||||
PHIDP_VALUE_CAPS value_caps = (PHIDP_VALUE_CAPS)alloca(num_value_caps * sizeof(HIDP_VALUE_CAPS));
|
PHIDP_VALUE_CAPS value_caps;
|
||||||
|
if (num_value_caps > 0u) {
|
||||||
|
value_caps = (PHIDP_VALUE_CAPS)alloca(num_value_caps * sizeof(HIDP_VALUE_CAPS));
|
||||||
_HidP_GetValueCaps(HidP_Input, value_caps, &num_value_caps, buffer);
|
_HidP_GetValueCaps(HidP_Input, value_caps, &num_value_caps, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
_hat_data_index = -1;
|
_hat_data_index = -1;
|
||||||
|
|
||||||
@ -464,7 +483,7 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
|
|||||||
if (device_cat.is_debug()) {
|
if (device_cat.is_debug()) {
|
||||||
device_cat.debug()
|
device_cat.debug()
|
||||||
<< "Found value: DataIndex=" << dec << cap.NotRange.DataIndex
|
<< "Found value: DataIndex=" << dec << cap.NotRange.DataIndex
|
||||||
<< ", ReportID=" << dec << (int)cap.ReportID
|
<< ", ReportID=" << (int)cap.ReportID
|
||||||
<< ", UsagePage=0x" << hex << cap.UsagePage
|
<< ", UsagePage=0x" << hex << cap.UsagePage
|
||||||
<< ", Usage=0x" << cap.NotRange.Usage
|
<< ", Usage=0x" << cap.NotRange.Usage
|
||||||
<< dec << ", LogicalMin=" << cap.LogicalMin
|
<< dec << ", LogicalMin=" << cap.LogicalMin
|
||||||
@ -472,6 +491,8 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nassertd(cap.Range.DataIndexMin + upper < _indices.size()) continue;
|
||||||
|
|
||||||
for (int j = 0; j <= upper; ++j) {
|
for (int j = 0; j <= upper; ++j) {
|
||||||
USAGE usage = j + cap.Range.UsageMin;
|
USAGE usage = j + cap.Range.UsageMin;
|
||||||
USHORT data_index = j + cap.Range.DataIndexMin;
|
USHORT data_index = j + cap.Range.DataIndexMin;
|
||||||
@ -590,6 +611,8 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
|
|||||||
|
|
||||||
_max_data_count = _HidP_MaxDataListLength(HidP_Input, buffer);
|
_max_data_count = _HidP_MaxDataListLength(HidP_Input, buffer);
|
||||||
|
|
||||||
|
nassertr_always(_max_data_count >= 0, false);
|
||||||
|
|
||||||
_handle = handle;
|
_handle = handle;
|
||||||
_is_connected = true;
|
_is_connected = true;
|
||||||
return true;
|
return true;
|
||||||
@ -619,6 +642,10 @@ on_input(PRAWINPUT input) {
|
|||||||
nassertv(input != nullptr);
|
nassertv(input != nullptr);
|
||||||
nassertv(_preparsed != nullptr);
|
nassertv(_preparsed != nullptr);
|
||||||
|
|
||||||
|
if (_max_data_count == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BYTE *ptr = input->data.hid.bRawData;
|
BYTE *ptr = input->data.hid.bRawData;
|
||||||
if (input->data.hid.dwSizeHid == 0) {
|
if (input->data.hid.dwSizeHid == 0) {
|
||||||
return;
|
return;
|
||||||
@ -626,6 +653,12 @@ on_input(PRAWINPUT input) {
|
|||||||
|
|
||||||
LightMutexHolder holder(_lock);
|
LightMutexHolder holder(_lock);
|
||||||
|
|
||||||
|
if (device_cat.is_spam()) {
|
||||||
|
device_cat.spam()
|
||||||
|
<< _name << " received " << input->data.hid.dwCount << " reports of size "
|
||||||
|
<< input->data.hid.dwSizeHid << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
for (DWORD i = 0; i < input->data.hid.dwCount; ++i) {
|
for (DWORD i = 0; i < input->data.hid.dwCount; ++i) {
|
||||||
process_report((PCHAR)ptr, input->data.hid.dwSizeHid);
|
process_report((PCHAR)ptr, input->data.hid.dwSizeHid);
|
||||||
ptr += input->data.hid.dwSizeHid;
|
ptr += input->data.hid.dwSizeHid;
|
||||||
@ -654,6 +687,7 @@ process_report(PCHAR ptr, size_t size) {
|
|||||||
if (status == HIDP_STATUS_SUCCESS) {
|
if (status == HIDP_STATUS_SUCCESS) {
|
||||||
for (ULONG di = 0; di < count; ++di) {
|
for (ULONG di = 0; di < count; ++di) {
|
||||||
if (data[di].DataIndex != _hat_data_index) {
|
if (data[di].DataIndex != _hat_data_index) {
|
||||||
|
nassertd(data[di].DataIndex < _indices.size()) continue;
|
||||||
const Index &idx = _indices[data[di].DataIndex];
|
const Index &idx = _indices[data[di].DataIndex];
|
||||||
if (idx._axis >= 0) {
|
if (idx._axis >= 0) {
|
||||||
if (idx._signed) {
|
if (idx._signed) {
|
||||||
|
@ -249,6 +249,10 @@ detect(InputDeviceManager *mgr) {
|
|||||||
*/
|
*/
|
||||||
bool XInputDevice::
|
bool XInputDevice::
|
||||||
init_xinput() {
|
init_xinput() {
|
||||||
|
if (_initialized) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (device_cat.is_debug()) {
|
if (device_cat.is_debug()) {
|
||||||
device_cat.debug() << "Initializing XInput library.\n";
|
device_cat.debug() << "Initializing XInput library.\n";
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user