mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 00:32:57 -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
|
||||
// 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
|
||||
// the four players was the lucky one.
|
||||
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;
|
||||
}
|
||||
|
||||
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?
|
||||
static const ButtonHandle gamepad_buttons_common[] = {
|
||||
ButtonHandle::none(),
|
||||
@ -374,8 +382,11 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
|
||||
_axes.clear();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
for (USHORT i = 0; i < num_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()) {
|
||||
device_cat.debug()
|
||||
<< "Found button: DataIndex=" << dec << cap.NotRange.DataIndex
|
||||
<< ", ReportID=" << dec << (int)cap.ReportID
|
||||
<< ", UsagePage=0x" << cap.UsagePage
|
||||
<< ", ReportID=" << (int)cap.ReportID
|
||||
<< ", UsagePage=0x" << hex << cap.UsagePage
|
||||
<< ", Usage=0x" << cap.NotRange.Usage
|
||||
<< dec << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
nassertd(cap.Range.DataIndexMin + upper < _indices.size()) continue;
|
||||
|
||||
// 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
|
||||
// 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);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
_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()) {
|
||||
device_cat.debug()
|
||||
<< "Found value: DataIndex=" << dec << cap.NotRange.DataIndex
|
||||
<< ", ReportID=" << dec << (int)cap.ReportID
|
||||
<< ", ReportID=" << (int)cap.ReportID
|
||||
<< ", UsagePage=0x" << hex << cap.UsagePage
|
||||
<< ", Usage=0x" << cap.NotRange.Usage
|
||||
<< 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) {
|
||||
USAGE usage = j + cap.Range.UsageMin;
|
||||
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);
|
||||
|
||||
nassertr_always(_max_data_count >= 0, false);
|
||||
|
||||
_handle = handle;
|
||||
_is_connected = true;
|
||||
return true;
|
||||
@ -619,6 +642,10 @@ on_input(PRAWINPUT input) {
|
||||
nassertv(input != nullptr);
|
||||
nassertv(_preparsed != nullptr);
|
||||
|
||||
if (_max_data_count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
BYTE *ptr = input->data.hid.bRawData;
|
||||
if (input->data.hid.dwSizeHid == 0) {
|
||||
return;
|
||||
@ -626,6 +653,12 @@ on_input(PRAWINPUT input) {
|
||||
|
||||
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) {
|
||||
process_report((PCHAR)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) {
|
||||
for (ULONG di = 0; di < count; ++di) {
|
||||
if (data[di].DataIndex != _hat_data_index) {
|
||||
nassertd(data[di].DataIndex < _indices.size()) continue;
|
||||
const Index &idx = _indices[data[di].DataIndex];
|
||||
if (idx._axis >= 0) {
|
||||
if (idx._signed) {
|
||||
|
@ -249,6 +249,10 @@ detect(InputDeviceManager *mgr) {
|
||||
*/
|
||||
bool XInputDevice::
|
||||
init_xinput() {
|
||||
if (_initialized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (device_cat.is_debug()) {
|
||||
device_cat.debug() << "Initializing XInput library.\n";
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user