@@ -107,6 +107,7 @@ typedef struct USBXIDState {
107
107
XIDGamepadOutputReport out_state ;
108
108
XIDGamepadOutputReport out_state_capabilities ;
109
109
uint8_t device_index ;
110
+ uint8_t in_state_dirty ;
110
111
} USBXIDState ;
111
112
112
113
static const USBDescIface desc_iface_xbox_gamepad = {
@@ -236,6 +237,9 @@ static void update_input(USBXIDState *s)
236
237
{ GAMEPAD_DPAD_RIGHT , CONTROLLER_BUTTON_DPAD_RIGHT },
237
238
};
238
239
240
+ XIDGamepadReport old_state ;
241
+ memcpy (& old_state , & s -> in_state , sizeof (old_state ));
242
+
239
243
for (int i = 0 ; i < 6 ; i ++ ) {
240
244
int pressed = state -> buttons & button_map_analog [i ][1 ];
241
245
s -> in_state .bAnalogButtons [button_map_analog [i ][0 ]] = pressed ? 0xff : 0 ;
@@ -254,6 +258,10 @@ static void update_input(USBXIDState *s)
254
258
s -> in_state .sThumbLY = state -> axis [CONTROLLER_AXIS_LSTICK_Y ];
255
259
s -> in_state .sThumbRX = state -> axis [CONTROLLER_AXIS_RSTICK_X ];
256
260
s -> in_state .sThumbRY = state -> axis [CONTROLLER_AXIS_RSTICK_Y ];
261
+
262
+ if (memcmp (& old_state , & s -> in_state , sizeof (old_state ))) {
263
+ s -> in_state_dirty = 1 ;
264
+ }
257
265
}
258
266
259
267
static void usb_xid_handle_reset (USBDevice * dev )
@@ -378,7 +386,12 @@ static void usb_xid_handle_data(USBDevice *dev, USBPacket *p)
378
386
case USB_TOKEN_IN :
379
387
if (p -> ep -> nr == 2 ) {
380
388
update_input (s );
381
- usb_packet_copy (p , & s -> in_state , s -> in_state .bLength );
389
+ if (s -> in_state_dirty ) {
390
+ usb_packet_copy (p , & s -> in_state , s -> in_state .bLength );
391
+ s -> in_state_dirty = 0 ;
392
+ } else {
393
+ p -> status = USB_RET_NAK ;
394
+ }
382
395
} else {
383
396
assert (false);
384
397
}
0 commit comments