From 4c23a0e1dcec46a78785961b6e8b544cf3821ffd Mon Sep 17 00:00:00 2001 From: Ingo Ruhnke <grumbel@gmx.de> Date: Fri, 26 Dec 2008 00:06:02 +0100 Subject: [PATCH] Added timeout to ::read() --- xbox360_controller.cpp | 11 ++++++++--- xbox360_controller.hpp | 2 +- xbox360_wireless_controller.cpp | 12 ++++++++---- xbox360_wireless_controller.hpp | 2 +- xbox_controller.cpp | 13 +++++++++---- xbox_controller.hpp | 2 +- xbox_generic_controller.hpp | 4 +++- xboxdrv.cpp | 9 +++++++-- 8 files changed, 38 insertions(+), 17 deletions(-) diff --git a/xbox360_controller.cpp b/xbox360_controller.cpp index 6e0fbf8..d7cf8a1 100644 --- a/xbox360_controller.cpp +++ b/xbox360_controller.cpp @@ -16,6 +16,7 @@ ** along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <errno.h> #include <stdexcept> #include <sstream> #include <iostream> @@ -91,12 +92,16 @@ Xbox360Controller::set_led(uint8_t status) } bool -Xbox360Controller::read(XboxGenericMsg& msg, bool verbose) +Xbox360Controller::read(XboxGenericMsg& msg, bool verbose, int timeout) { uint8_t data[32]; - int ret = usb_interrupt_read(handle, 1 /*EndPoint*/, (char*)data, sizeof(data), 0 /*Timeout*/); + int ret = usb_interrupt_read(handle, 1 /*EndPoint*/, (char*)data, sizeof(data), timeout); - if (ret < 0) + if (ret == -ETIMEDOUT) + { + return false; + } + else if (ret < 0) { // Error std::ostringstream str; str << "USBError: " << ret << "\n" << usb_strerror(); diff --git a/xbox360_controller.hpp b/xbox360_controller.hpp index 9987fe6..048d5cb 100644 --- a/xbox360_controller.hpp +++ b/xbox360_controller.hpp @@ -40,7 +40,7 @@ public: void set_rumble(uint8_t left, uint8_t right); void set_led(uint8_t status); void send_raw(char* buffer, int len); - bool read(XboxGenericMsg& msg, bool verbose); + bool read(XboxGenericMsg& msg, bool verbose, int timeout); private: Xbox360Controller (const Xbox360Controller&); diff --git a/xbox360_wireless_controller.cpp b/xbox360_wireless_controller.cpp index 4d05532..6d4b326 100644 --- a/xbox360_wireless_controller.cpp +++ b/xbox360_wireless_controller.cpp @@ -76,12 +76,16 @@ Xbox360WirelessController::set_led(uint8_t status) } bool -Xbox360WirelessController::read(XboxGenericMsg& msg, bool verbose) +Xbox360WirelessController::read(XboxGenericMsg& msg, bool verbose, int timeout) { uint8_t data[32]; - int ret = usb_interrupt_read(handle, endpoint, (char*)data, sizeof(data), 0 /*Timeout*/); - - if (ret < 0) + int ret = usb_interrupt_read(handle, endpoint, (char*)data, sizeof(data), timeout); + + if (ret == -ETIMEDOUT) + { + return false; + } + else if (ret < 0) { // Error std::ostringstream str; str << "USBError: " << ret << "\n" << usb_strerror(); diff --git a/xbox360_wireless_controller.hpp b/xbox360_wireless_controller.hpp index e73e3aa..f74f2c7 100644 --- a/xbox360_wireless_controller.hpp +++ b/xbox360_wireless_controller.hpp @@ -41,7 +41,7 @@ public: void set_rumble(uint8_t left, uint8_t right); void set_led(uint8_t status); - bool read(XboxGenericMsg& msg, bool verbose); + bool read(XboxGenericMsg& msg, bool verbose, int timeout); uint8_t get_battery_status() const; private: Xbox360WirelessController (const Xbox360WirelessController&); diff --git a/xbox_controller.cpp b/xbox_controller.cpp index b1e6c50..ecd8ca5 100644 --- a/xbox_controller.cpp +++ b/xbox_controller.cpp @@ -16,6 +16,7 @@ ** along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <errno.h> #include <stdexcept> #include <sstream> #include "xboxmsg.hpp" @@ -58,13 +59,17 @@ XboxController::set_led(uint8_t status) } bool -XboxController::read(XboxGenericMsg& msg, bool verbose) +XboxController::read(XboxGenericMsg& msg, bool verbose, int timeout) { // FIXME: Add tracking for duplicate data packages (send by logitech controller) uint8_t data[32]; - int ret = usb_interrupt_read(handle, 1 /*EndPoint*/, (char*)data, sizeof(data), 0 /*Timeout*/); - - if (ret < 0) + int ret = usb_interrupt_read(handle, 1 /*EndPoint*/, (char*)data, sizeof(data), timeout); + + if (ret == -ETIMEDOUT) + { + return false; + } + else if (ret < 0) { // Error std::ostringstream str; str << "USBError: " << ret << "\n" << usb_strerror(); diff --git a/xbox_controller.hpp b/xbox_controller.hpp index ec5be6d..992829f 100644 --- a/xbox_controller.hpp +++ b/xbox_controller.hpp @@ -37,7 +37,7 @@ public: void set_rumble(uint8_t left, uint8_t right); void set_led(uint8_t status); - bool read(XboxGenericMsg& msg, bool verbose); + bool read(XboxGenericMsg& msg, bool verbose, int timeout); private: XboxController (const XboxController&); diff --git a/xbox_generic_controller.hpp b/xbox_generic_controller.hpp index 9772d68..5fc4772 100644 --- a/xbox_generic_controller.hpp +++ b/xbox_generic_controller.hpp @@ -30,7 +30,9 @@ public: virtual void set_rumble(uint8_t left, uint8_t right) =0; virtual void set_led(uint8_t status) =0; virtual void send_raw(char* buffer, int len) {} - virtual bool read(XboxGenericMsg& msg, bool verbose) =0; + + /** @param timeout timeout in msec, 0 means forever */ + virtual bool read(XboxGenericMsg& msg, bool verbose, int timeout) =0; private: XboxGenericController (const XboxGenericController&); diff --git a/xboxdrv.cpp b/xboxdrv.cpp index 76d44cc..270cd1e 100644 --- a/xboxdrv.cpp +++ b/xboxdrv.cpp @@ -851,15 +851,17 @@ void squarify_axis_(int16_t& x_inout, int16_t& y_inout) { if (x_inout != 0 || y_inout != 0) { + // Convert values to float float x = (x_inout < 0) ? x_inout / 32768.0f : x_inout / 32767.0f; float y = (y_inout < 0) ? y_inout / 32768.0f : y_inout / 32767.0f; + // Transform values to square range float l = sqrtf(x*x + y*y); float v = fabs((fabsf(x) > fabsf(y)) ? l/x : l/y); - x *= v; y *= v; + // Convert values to int16_t x_inout = static_cast<int16_t>(Math::clamp(-32768, static_cast<int>((x < 0) ? x * 32768 : x * 32767), 32767)); y_inout = static_cast<int16_t>(Math::clamp(-32768, static_cast<int>((y < 0) ? y * 32768 : y * 32767), 32767)); } @@ -934,13 +936,16 @@ void apply_deadzone(XboxGenericMsg& msg, int deadzone) void controller_loop(uInput* uinput, XboxGenericController* controller, CommandLineOptions& opts) { + int timeout = 0; // 0 == no timeout XboxGenericMsg oldmsg; + memset(&oldmsg, 0, sizeof(oldmsg)); + while(!global_exit_xboxdrv) { XboxGenericMsg msg; - if (controller->read(msg, opts.verbose)) + if (controller->read(msg, opts.verbose, timeout)) { apply_deadzone(msg, opts.deadzone);