diff --git a/joystick_xl/hid.py b/joystick_xl/hid.py index 8d3805f..de15163 100644 --- a/joystick_xl/hid.py +++ b/joystick_xl/hid.py @@ -73,13 +73,15 @@ def create_joystick( _descriptor.extend(bytes(( 0x15, 0x00, # : LOGICAL_MINIMUM (0) - 0x26, 0xFF, 0x00, # : LOGICAL_MAXIMUM (255) - 0x75, 0x08, # : REPORT_SIZE (8) + 0x27, 0xFF, 0xFF, 0x00, 0x00, # : LOGICAL_MAXIMUM (1 << 16) + 0x35, 0x00, # : PHYSICAL_MINIMUM (0) + 0x47, 0xFF, 0xFF, 0x00, 0x00, # : PHYSICAL_MAXIMUM (1 << 16) + 0x75, 0x10, # : REPORT_SIZE (16) 0x95, _num_axes, # : REPORT_COUNT (num_axes) 0x81, 0x02, # : INPUT (Data,Var,Abs) ))) - _report_length = _num_axes + _report_length = _num_axes * 2 if _num_hats: for i in range(_num_hats): diff --git a/joystick_xl/inputs.py b/joystick_xl/inputs.py index 151d08c..7e71f93 100644 --- a/joystick_xl/inputs.py +++ b/joystick_xl/inputs.py @@ -37,10 +37,10 @@ class Axis: MIN = 0 """Lowest possible axis value for USB HID reports.""" - MAX = 255 + MAX = (1 << 16) - 1 """Highest possible axis value for USB HID reports.""" - IDLE = 128 + IDLE = 1 << 15 """Idle/Center axis value for USB HID reports.""" X = 0 @@ -236,16 +236,11 @@ def _update(self) -> int: new_value = min(max(self._source.value, self._min), self._max) # account for deadband - if new_value < (self._raw_midpoint - self._deadband): - new_value -= self._min - elif new_value > (self._raw_midpoint + self._deadband): - new_value = new_value - self._min - (self._deadband * 2) - else: - new_value = self._db_range // 2 - - # calculate scaled joystick-compatible value and clamp to 0-255 - self._value = min(new_value * 256 // self._db_range, 255) + if new_value >= self._raw_midpoint - self._deadband and \ + new_value <= self._raw_midpoint + self._deadband: + new_value = self._raw_midpoint + self._value = new_value return self._value diff --git a/joystick_xl/joystick.py b/joystick_xl/joystick.py index 2a4d649..b38a2f0 100644 --- a/joystick_xl/joystick.py +++ b/joystick_xl/joystick.py @@ -91,7 +91,7 @@ def __init__(self) -> None: self._axis_states = list() for _ in range(self.num_axes): self._axis_states.append(Axis.IDLE) - self._format += "B" + self._format += "H" self.hat = list() """List of hat inputs associated with this joystick through ``add_input``.""" @@ -136,7 +136,7 @@ def _validate_axis_value(axis: int, value: int) -> bool: if axis + 1 > Joystick._num_axes: raise ValueError("Specified axis is out of range.") if not Axis.MIN <= value <= Axis.MAX: - raise ValueError("Axis value must be in range 0 to 255") + raise ValueError(f"Axis value must be in range {Axis.MIN} to {Axis.MAX}") return True @staticmethod @@ -241,7 +241,6 @@ def update(self, always: bool = False) -> None: # Generate a USB HID report. report_data = list() - report_data.extend(self._axis_states) if self.num_hats: @@ -256,8 +255,13 @@ def update(self, always: bool = False) -> None: # Send the USB HID report if required. if always or self._last_report != self._report: - self._device.send_report(self._report) - self._last_report[:] = self._report + try: + self._device.send_report(self._report) + self._last_report[:] = self._report + except OSError as e: + # This can occur if the USB is busy, or the host never properly connected to the + # USB device, drop the update and try later. + pass def reset_all(self) -> None: """Reset all inputs to their idle states."""