Skip to content

Commit da6c573

Browse files
committed
xid: NAK USB packet if no changes occured
1 parent 4fabcf1 commit da6c573

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

hw/xbox/xid.c

+14-1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ typedef struct USBXIDState {
107107
XIDGamepadOutputReport out_state;
108108
XIDGamepadOutputReport out_state_capabilities;
109109
uint8_t device_index;
110+
uint8_t in_state_dirty;
110111
} USBXIDState;
111112

112113
static const USBDescIface desc_iface_xbox_gamepad = {
@@ -236,6 +237,9 @@ static void update_input(USBXIDState *s)
236237
{ GAMEPAD_DPAD_RIGHT, CONTROLLER_BUTTON_DPAD_RIGHT },
237238
};
238239

240+
XIDGamepadReport old_state;
241+
memcpy(&old_state, &s->in_state, sizeof(old_state));
242+
239243
for (int i = 0; i < 6; i++) {
240244
int pressed = state->buttons & button_map_analog[i][1];
241245
s->in_state.bAnalogButtons[button_map_analog[i][0]] = pressed ? 0xff : 0;
@@ -254,6 +258,10 @@ static void update_input(USBXIDState *s)
254258
s->in_state.sThumbLY = state->axis[CONTROLLER_AXIS_LSTICK_Y];
255259
s->in_state.sThumbRX = state->axis[CONTROLLER_AXIS_RSTICK_X];
256260
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+
}
257265
}
258266

259267
static void usb_xid_handle_reset(USBDevice *dev)
@@ -378,7 +386,12 @@ static void usb_xid_handle_data(USBDevice *dev, USBPacket *p)
378386
case USB_TOKEN_IN:
379387
if (p->ep->nr == 2) {
380388
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+
}
382395
} else {
383396
assert(false);
384397
}

0 commit comments

Comments
 (0)