From dc9ddf1f61c2a80b90deffc6f3b1a5639b901fcb Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 6 Sep 2013 20:54:14 -0700 Subject: [PATCH] Fixed bug 2090 - Some joystick inputs are delayed on FreeBSD kikuchan Some joysticks with high sampling rate need to be read() more fast, otherwise it delay user inputs due to internal queue. Especially, an app that issues SDL_PollEvent() not so frequent --- src/joystick/bsd/SDL_sysjoystick.c | 164 ++++++++++++++--------------- 1 file changed, 80 insertions(+), 84 deletions(-) diff --git a/src/joystick/bsd/SDL_sysjoystick.c b/src/joystick/bsd/SDL_sysjoystick.c index c5816b6b7c6e4..41a8693d6ead4 100644 --- a/src/joystick/bsd/SDL_sysjoystick.c +++ b/src/joystick/bsd/SDL_sysjoystick.c @@ -446,48 +446,47 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joy) static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0; if (joy->hwdata->type == BSDJOY_JOY) { - if (read(joy->hwdata->fd, &gameport, sizeof gameport) != - sizeof gameport) - return; - if (abs(x - gameport.x) > 8) { - x = gameport.x; - if (x < xmin) { - xmin = x; - } - if (x > xmax) { - xmax = x; - } - if (xmin == xmax) { - xmin--; - xmax++; + while (read(joy->hwdata->fd, &gameport, sizeof gameport) == sizeof gameport) { + if (abs(x - gameport.x) > 8) { + x = gameport.x; + if (x < xmin) { + xmin = x; + } + if (x > xmax) { + xmax = x; + } + if (xmin == xmax) { + xmin--; + xmax++; + } + v = (Sint32) x; + v -= (xmax + xmin + 1) / 2; + v *= 32768 / ((xmax - xmin + 1) / 2); + SDL_PrivateJoystickAxis(joy, 0, v); } - v = (Sint32) x; - v -= (xmax + xmin + 1) / 2; - v *= 32768 / ((xmax - xmin + 1) / 2); - SDL_PrivateJoystickAxis(joy, 0, v); - } - if (abs(y - gameport.y) > 8) { - y = gameport.y; - if (y < ymin) { - ymin = y; + if (abs(y - gameport.y) > 8) { + y = gameport.y; + if (y < ymin) { + ymin = y; + } + if (y > ymax) { + ymax = y; + } + if (ymin == ymax) { + ymin--; + ymax++; + } + v = (Sint32) y; + v -= (ymax + ymin + 1) / 2; + v *= 32768 / ((ymax - ymin + 1) / 2); + SDL_PrivateJoystickAxis(joy, 1, v); } - if (y > ymax) { - ymax = y; + if (gameport.b1 != joy->buttons[0]) { + SDL_PrivateJoystickButton(joy, 0, gameport.b1); } - if (ymin == ymax) { - ymin--; - ymax++; + if (gameport.b2 != joy->buttons[1]) { + SDL_PrivateJoystickButton(joy, 1, gameport.b2); } - v = (Sint32) y; - v -= (ymax + ymin + 1) / 2; - v *= 32768 / ((ymax - ymin + 1) / 2); - SDL_PrivateJoystickAxis(joy, 1, v); - } - if (gameport.b1 != joy->buttons[0]) { - SDL_PrivateJoystickButton(joy, 0, gameport.b1); - } - if (gameport.b2 != joy->buttons[1]) { - SDL_PrivateJoystickButton(joy, 1, gameport.b2); } return; } @@ -495,65 +494,62 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joy) rep = &joy->hwdata->inreport; - if (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) != rep->size) { - return; - } + while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size) { #if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__) - hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid); + hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid); #else - hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input); + hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input); #endif - if (hdata == NULL) { - fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path); - return; - } + if (hdata == NULL) { + /*fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path);*/ + continue; + } - for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) { - switch (hitem.kind) { - case hid_input: - switch (HID_PAGE(hitem.usage)) { - case HUP_GENERIC_DESKTOP: - { - unsigned usage = HID_USAGE(hitem.usage); - int joyaxe = usage_to_joyaxe(usage); - if (joyaxe >= 0) { - naxe = joy->hwdata->axis_map[joyaxe]; - /* scaleaxe */ - v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem); - v -= (hitem.logical_maximum + - hitem.logical_minimum + 1) / 2; - v *= 32768 / - ((hitem.logical_maximum - - hitem.logical_minimum + 1) / 2); - if (v != joy->axes[naxe]) { - SDL_PrivateJoystickAxis(joy, naxe, v); + for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) { + switch (hitem.kind) { + case hid_input: + switch (HID_PAGE(hitem.usage)) { + case HUP_GENERIC_DESKTOP: + { + unsigned usage = HID_USAGE(hitem.usage); + int joyaxe = usage_to_joyaxe(usage); + if (joyaxe >= 0) { + naxe = joy->hwdata->axis_map[joyaxe]; + /* scaleaxe */ + v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem); + v -= (hitem.logical_maximum + + hitem.logical_minimum + 1) / 2; + v *= 32768 / + ((hitem.logical_maximum - + hitem.logical_minimum + 1) / 2); + if (v != joy->axes[naxe]) { + SDL_PrivateJoystickAxis(joy, naxe, v); + } + } else if (usage == HUG_HAT_SWITCH) { + v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem); + SDL_PrivateJoystickHat(joy, 0, + hatval_to_sdl(v) - + hitem.logical_minimum); } - } else if (usage == HUG_HAT_SWITCH) { - v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem); - SDL_PrivateJoystickHat(joy, 0, - hatval_to_sdl(v) - - hitem.logical_minimum); + break; + } + case HUP_BUTTON: + v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem); + if (joy->buttons[nbutton] != v) { + SDL_PrivateJoystickButton(joy, nbutton, v); } + nbutton++; break; + default: + continue; } - case HUP_BUTTON: - v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem); - if (joy->buttons[nbutton] != v) { - SDL_PrivateJoystickButton(joy, nbutton, v); - } - nbutton++; break; default: - continue; + break; } - break; - default: - break; } + hid_end_parse(hdata); } - hid_end_parse(hdata); - - return; } /* Function to close a joystick after use */