From a823cef71a565b6df1ef21c7d0aa6b18b0d5fb70 Mon Sep 17 00:00:00 2001 From: Ingo Ruhnke <grumbel@gmx.de> Date: Thu, 18 Jun 2009 22:14:30 +0200 Subject: [PATCH] Added some code for 'Firestorm Dual Power 3 vs b' --- src/firestorm_dual_controller.cpp | 118 ++++++++++++++++++++++++++++++ src/firestorm_dual_controller.hpp | 2 + 2 files changed, 120 insertions(+) diff --git a/src/firestorm_dual_controller.cpp b/src/firestorm_dual_controller.cpp index d31d8bb..19582bf 100644 --- a/src/firestorm_dual_controller.cpp +++ b/src/firestorm_dual_controller.cpp @@ -21,8 +21,38 @@ #include <stdexcept> #include <sstream> #include <string.h> +#include <boost/format.hpp> + #include "firestorm_dual_controller.hpp" +// 044f:b312 +struct Firestorm_vsb_Msg +{ + unsigned int a :1; + unsigned int x :1; + unsigned int b :1; + unsigned int y :1; + + unsigned int lb :1; + unsigned int lt :1; + unsigned int rb :1; + unsigned int rt :1; + + unsigned int back :1; + unsigned int start :1; + + unsigned int thumb_l :1; + unsigned int thumb_r :1; + + unsigned int dpad :4; // 0xf == center, 0x00 == up, clockwise + 1 each + + int x1 :8; + int y1 :8; + int x2 :8; + unsigned int y2 :8; +}; + +// 044f:b304 struct FirestormMsg { unsigned int a :1; @@ -121,6 +151,94 @@ inline int16_t scale_8to16(int8_t a) bool FirestormDualController::read(XboxGenericMsg& msg, bool verbose, int timeout) +{ + //return read_vsb(msg, verbose, timeout); + return read_default(msg, verbose, timeout); +} + +bool +FirestormDualController::read_vsb(XboxGenericMsg& msg, bool verbose, int timeout) +{ + Firestorm_vsb_Msg data; + 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(); + throw std::runtime_error(str.str()); + } + else if (ret == sizeof(data)) + { + if (0) + { // debug output + for(size_t i = 0; i < sizeof(data); ++i) + { + uint8_t v = reinterpret_cast<char*>(&data)[i]; + std::cout << boost::format("0x%02x ") % (int)v; + } + std::cout << std::endl; + } + + memset(&msg, 0, sizeof(msg)); + msg.type = XBOX_MSG_XBOX360; + + msg.xbox360.a = data.a; + msg.xbox360.b = data.b; + msg.xbox360.x = data.x; + msg.xbox360.y = data.y; + + msg.xbox360.lb = data.lb; + msg.xbox360.rb = data.rb; + + msg.xbox360.lt = data.lt * 255; + msg.xbox360.rt = data.rt * 255; + + msg.xbox360.start = data.start; + msg.xbox360.back = data.back; + + msg.xbox360.thumb_l = data.thumb_l; + msg.xbox360.thumb_r = data.thumb_r; + + msg.xbox360.x1 = scale_8to16(data.x1); + msg.xbox360.y1 = scale_8to16(data.y1); + + msg.xbox360.x2 = scale_8to16(data.x2); + msg.xbox360.y2 = scale_8to16(data.y2 - 128); + + // Invert the axis + msg.xbox360.y1 = negate_16(msg.xbox360.y1); + msg.xbox360.y2 = negate_16(msg.xbox360.y2); + + // data.dpad == 0xf0 -> dpad centered + // data.dpad == 0xe0 -> dpad-only mode is enabled + + if (data.dpad == 0x0 || data.dpad == 0x7 || data.dpad == 0x1) + msg.xbox360.dpad_up = 1; + + if (data.dpad == 0x1 || data.dpad == 0x2 || data.dpad == 0x3) + msg.xbox360.dpad_right = 1; + + if (data.dpad == 0x3 || data.dpad == 0x4 || data.dpad == 0x5) + msg.xbox360.dpad_down = 1; + + if (data.dpad == 0x5 || data.dpad == 0x6 || data.dpad == 0x7) + msg.xbox360.dpad_left = 1; + + return true; + } + else + { + return false; + } +} + +bool +FirestormDualController::read_default(XboxGenericMsg& msg, bool verbose, int timeout) { FirestormMsg data; int ret = usb_interrupt_read(handle, 1 /*EndPoint*/, (char*)&data, sizeof(data), timeout); diff --git a/src/firestorm_dual_controller.hpp b/src/firestorm_dual_controller.hpp index db0a2e9..ad7e6d0 100644 --- a/src/firestorm_dual_controller.hpp +++ b/src/firestorm_dual_controller.hpp @@ -41,6 +41,8 @@ public: /** @param timeout timeout in msec, 0 means forever */ bool read(XboxGenericMsg& msg, bool verbose, int timeout); + bool read_default(XboxGenericMsg& msg, bool verbose, int timeout); + bool read_vsb(XboxGenericMsg& msg, bool verbose, int timeout); }; #endif