@@ -317,28 +317,50 @@ unsafe void SetDeviceCommandCallbackToReturnReportDescriptor(int deviceId, byte[
317317
318318 [ Test ]
319319 [ Category ( "HID Devices" ) ]
320- public void Devices_CanCreateGenericHID_WithSignedLogicalMinAndMaxSticks ( )
320+
321+ // These descriptor values were generated with the Microsoft HID Authoring descriptor tool in
322+ // https://github.com/microsoft/hidtools for the expexted values.
323+ // Logical min 0, logical max 65535
324+ [ TestCase ( 16 , new byte [ ] { 0x16 , 0x00 , 0x00 } , new byte [ ] { 0x27 , 0xFF , 0xFF , 0x00 , 0x00 } , 0 , 65535 , 0.01f ) ]
325+ // Logical min -32768, logical max 32767
326+ [ TestCase ( 16 , new byte [ ] { 0x16 , 0x00 , 0x80 } , new byte [ ] { 0x26 , 0xFF , 0x7F } , - 32768 , 32767 , 0.01f ) ]
327+ // Logical min 0, logical max 255
328+ [ TestCase ( 8 , new byte [ ] { 0x15 , 00 } , new byte [ ] { 0x26 , 0xFF , 0x00 } , 0 , 255 , 0.01f ) ]
329+ // Logical min -128, logical max 127
330+ [ TestCase ( 8 , new byte [ ] { 0x15 , 0x80 } , new byte [ ] { 0x25 , 0x7F } , - 128 , 127 , 0.01f ) ]
331+ // Logical min -16, logical max 15 (below 8 bit boundary)
332+ [ TestCase ( 5 , new byte [ ] { 0x15 , 0xF0 } , new byte [ ] { 0x25 , 0x0F } , - 16 , 15 , 0 ) ]
333+ // Logical min 0, logical max 31 (below 8 bit boundary)
334+ [ TestCase ( 5 , new byte [ ] { 0x15 , 0x00 } , new byte [ ] { 0x25 , 0x1F } , 0 , 31 , 0 ) ]
335+ public void Devices_CanParseHIDDescritpor_WithSignedLogicalMinAndMaxSticks ( byte reportSizeBits , byte [ ] logicalMinBytes , byte [ ] logicalMaxBytes , int logicalMinExpected , int logicalMaxExpected , float errorMargin )
321336 {
322- // This is a HID report descriptor for a simple device with two analog sticks;
323- // Similar to a user that reported an issue in Discussions:
324- // https://discussions.unity.com/t/input-system-reading-invalid-values-from-hall-effect-keyboards/1684840/3
325- var reportDescriptor = new byte [ ]
337+ // Dynamically create HID report descriptor for two analog sticks with parameterized logical min/max
338+
339+ var reportDescriptorStart = new byte [ ]
326340 {
327341 0x05 , 0x01 , // Usage Page (Generic Desktop Ctrls)
328342 0x09 , 0x05 , // Usage (Game Pad)
329343 0xA1 , 0x01 , // Collection (Application)
330344 0x85 , 0x01 , // Report ID (1)
331345 0x05 , 0x01 , // Usage Page (Generic Desktop Ctrls)
332346 0x09 , 0x30 , // Usage (X)
333- 0x09 , 0x31 , // Usage (Y)
334- 0x15 , 0x81 , // Logical Minimum (-127)
335- 0x25 , 0x7F , // Logical Maximum (127)
336- 0x75 , 0x08 , // Report Size (8)
337- 0x95 , 0x02 , // Report Count (2)
338- 0x81 , 0x02 , // Input (Data,Var,Abs)
339- 0xC0 , // End Collection
340347 } ;
341348
349+ var reportDescriptorEnd = new byte [ ]
350+ {
351+ 0x75 , reportSizeBits , // Report Size (8)
352+ 0x95 , 0x01 , // Report Count (1)
353+ 0x81 , 0x02 , // Input (Data,Var,Abs)
354+ 0xC0 , // End Collection
355+ } ;
356+
357+ // Concatenate to form final descriptor based on test parameters where logical min/max bytes
358+ // are inserted in the middle.
359+ var reportDescriptor = reportDescriptorStart . Concat ( logicalMinBytes ) .
360+ Concat ( logicalMaxBytes ) .
361+ Concat ( reportDescriptorEnd ) .
362+ ToArray ( ) ;
363+
342364 // The HID report descriptor is fetched from the device via an IOCTL.
343365 var deviceId = runtime . AllocateDeviceId ( ) ;
344366
@@ -350,7 +372,7 @@ public void Devices_CanCreateGenericHID_WithSignedLogicalMinAndMaxSticks()
350372 new InputDeviceDescription
351373 {
352374 interfaceName = HID . kHIDInterface ,
353- manufacturer = "TestVendor " ,
375+ manufacturer = "TestLogicalMinMaxParsing " ,
354376 product = "TestHID" ,
355377 capabilities = new HID . HIDDeviceDescriptor
356378 {
@@ -365,35 +387,22 @@ public void Devices_CanCreateGenericHID_WithSignedLogicalMinAndMaxSticks()
365387 Assert . That ( device , Is . Not . Null ) ;
366388 Assert . That ( device , Is . TypeOf < Joystick > ( ) ) ;
367389
368- // Stick vector 2 should be centered at (0,0).
369- Assert . That ( device . stick . ReadValue ( ) , Is . EqualTo ( new Vector2 ( 0f , 0f ) ) . Using ( Vector2EqualityComparer . Instance ) ) ;
370-
371- // Queue event with stick pushed to bottom. We assume Y axis is inverted by default in HID devices.
372- // See HID.HIDElementDescriptor.DetermineParameters()
373- InputSystem . QueueStateEvent ( device , new SimpleJoystickLayoutWithStickByte { reportId = 1 , x = 0 , y = 127 } ) ;
374- InputSystem . Update ( ) ;
375-
376- Assert . That ( device . stick . ReadValue ( ) , Is . EqualTo ( new Vector2 ( 0f , - 1f ) ) . Using ( Vector2EqualityComparer . Instance ) ) ;
377-
378- InputSystem . QueueStateEvent ( device , new SimpleJoystickLayoutWithStickByte { reportId = 1 , x = 0 , y = - 127 } ) ;
379- InputSystem . Update ( ) ;
390+ var parsedDescriptor = JsonUtility . FromJson < HID . HIDDeviceDescriptor > ( device . description . capabilities ) ;
380391
381- Assert . That ( device . stick . ReadValue ( ) , Is . EqualTo ( new Vector2 ( 0f , 1f ) ) . Using ( Vector2EqualityComparer . Instance ) ) ;
382-
383- InputSystem . QueueStateEvent ( device , new SimpleJoystickLayoutWithStickByte { reportId = 1 , x = 127 , y = 0 } ) ;
384- InputSystem . Update ( ) ;
385-
386- Assert . That ( device . stick . ReadValue ( ) , Is . EqualTo ( new Vector2 ( 1f , 0f ) ) . Using ( Vector2EqualityComparer . Instance ) ) ;
387-
388- InputSystem . QueueStateEvent ( device , new SimpleJoystickLayoutWithStickByte { reportId = 1 , x = - 127 , y = 0 } ) ;
389- InputSystem . Update ( ) ;
390-
391- Assert . That ( device . stick . ReadValue ( ) , Is . EqualTo ( new Vector2 ( - 1f , 0f ) ) . Using ( Vector2EqualityComparer . Instance ) ) ;
392-
393- InputSystem . QueueStateEvent ( device , new SimpleJoystickLayoutWithStickByte { reportId = 1 , x = 127 , y = 127 } ) ;
394- InputSystem . Update ( ) ;
392+ // Check we parsed the values as expected
393+ foreach ( var element in parsedDescriptor . elements )
394+ {
395+ if ( element . usage == ( int ) HID . GenericDesktop . X )
396+ {
397+ Assert . That ( element . logicalMin , Is . EqualTo ( logicalMinExpected ) ) ;
398+ Assert . That ( element . logicalMax , Is . EqualTo ( logicalMaxExpected ) ) ;
399+ }
400+ else
401+ Assert . Fail ( "Could not find X and Y elements in descriptor" ) ;
402+ }
395403
396- Assert . That ( device . stick . ReadValue ( ) , Is . EqualTo ( new Vector2 ( 0.7071f , - 0.7071f ) ) . Using ( Vector2EqualityComparer . Instance ) ) ;
404+ // Stick vector 2 should be centered at (0,0) when initialized
405+ Assert . That ( device . stick . ReadValue ( ) , Is . EqualTo ( new Vector2 ( 0f , 0f ) ) . Using ( Vector2EqualityComparer . Instance ) ) ;
397406 }
398407
399408 [ Test ]
0 commit comments