|
@@ -0,0 +1,353 @@
|
|
|
+
|
|
|
+
|
|
|
+#include <QThread>
|
|
|
+
|
|
|
+#include <QFile>
|
|
|
+
|
|
|
+
|
|
|
+#ifndef Q_OS_WIN
|
|
|
+
|
|
|
+#include "joyreadthread.h"
|
|
|
+#include <assert.h>
|
|
|
+#include <math.h>
|
|
|
+#include <algorithm>
|
|
|
+#include <iostream>
|
|
|
+#include <stdexcept>
|
|
|
+#include <stdint.h>
|
|
|
+#include <string.h>
|
|
|
+#include <errno.h>
|
|
|
+#include <sys/types.h>
|
|
|
+#include <sys/stat.h>
|
|
|
+#include <fcntl.h>
|
|
|
+#include <string.h>
|
|
|
+#include <sstream>
|
|
|
+#include <unistd.h>
|
|
|
+#include <linux/joystick.h>
|
|
|
+
|
|
|
+#include <QFile>
|
|
|
+
|
|
|
+extern std::string gstrjoy_path;
|
|
|
+
|
|
|
+JoyReadThread::JoyReadThread()
|
|
|
+{
|
|
|
+
|
|
|
+ if ((fd = open(gstrjoy_path.data(), O_RDONLY)) < 0)
|
|
|
+ {
|
|
|
+ mbJoyOK = false;
|
|
|
+ std::ostringstream str;
|
|
|
+// str << filename << ": " << strerror(errno);
|
|
|
+// throw std::runtime_error(str.str());
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // ok
|
|
|
+ uint8_t num_axis = 0;
|
|
|
+ uint8_t num_button = 0;
|
|
|
+ ioctl(fd, JSIOCGAXES, &num_axis);
|
|
|
+ ioctl(fd, JSIOCGBUTTONS, &num_button);
|
|
|
+ axis_count = num_axis;
|
|
|
+ button_count = num_button;
|
|
|
+
|
|
|
+ // Get Name
|
|
|
+ char name_c_str[1024];
|
|
|
+ if (ioctl(fd, JSIOCGNAME(sizeof(name_c_str)), name_c_str) < 0)
|
|
|
+ {
|
|
|
+ mbJoyOK = false;
|
|
|
+ std::ostringstream str;
|
|
|
+ // str << filename << ": " << strerror(errno);
|
|
|
+ str << "joy:" << ": " << strerror(errno);
|
|
|
+ // throw std::runtime_error(str.str());
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ orig_name = name_c_str;
|
|
|
+// try {
|
|
|
+// name = Glib::convert_with_fallback(name_c_str, "UTF-8", "ISO-8859-1");
|
|
|
+// } catch(Glib::ConvertError& err) {
|
|
|
+// std::cout << err.what() << std::endl;
|
|
|
+// }
|
|
|
+ }
|
|
|
+
|
|
|
+// axis_state.resize(axis_count);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void JoyReadThread::run()
|
|
|
+{
|
|
|
+ if(mbJoyOK == false)return;
|
|
|
+ while(!QThread::isInterruptionRequested())
|
|
|
+ {
|
|
|
+ struct js_event event;
|
|
|
+
|
|
|
+ ssize_t len = read(fd, &event, sizeof(event));
|
|
|
+
|
|
|
+ if(len < 0)
|
|
|
+ {
|
|
|
+// qDebug("fail.");
|
|
|
+ mbJoyOK = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // if(len >0)qDebug("len = %d",len);
|
|
|
+
|
|
|
+ if(len == sizeof(js_event))
|
|
|
+ {
|
|
|
+ switch (event.number) {
|
|
|
+ case 0:
|
|
|
+ mfWheel = event.value;
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ mfAcc = event.value;
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ mfBrake = event.value;
|
|
|
+ break;
|
|
|
+ case 12:
|
|
|
+ if(event.value ==1 ) mnShift = 1;
|
|
|
+ else mnShift = 0;
|
|
|
+ break;
|
|
|
+ case 13:
|
|
|
+ if(event.value ==1 ) mnShift = 2;
|
|
|
+ else mnShift = 0;
|
|
|
+ break;
|
|
|
+ case 14:
|
|
|
+ if(event.value ==1 ) mnShift = 3;
|
|
|
+ else mnShift = 0;
|
|
|
+ break;
|
|
|
+ case 15:
|
|
|
+ if(event.value ==1 ) mnShift = 4;
|
|
|
+ else mnShift = 0;
|
|
|
+ break;
|
|
|
+ case 16:
|
|
|
+ if(event.value ==1 ) mnShift = 5;
|
|
|
+ else mnShift = 0;
|
|
|
+ break;
|
|
|
+ case 17:
|
|
|
+ if(event.value ==1 ) mnShift = 6;
|
|
|
+ else mnShift = 0;
|
|
|
+ break;
|
|
|
+ case 18:
|
|
|
+ if(event.value ==1 ) mnShift = -1;
|
|
|
+ else mnShift = 0;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ qDebug("shift = %d",mnShift);
|
|
|
+// qDebug("type = %d number = %d value = %d ",event.type,event.number,event.value);
|
|
|
+// qDebug("wheel:%g acc:%g brake:%g",mfWheel,mfAcc,mfBrake);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ close(fd);
|
|
|
+ mbJoyOK = false;
|
|
|
+}
|
|
|
+
|
|
|
+bool JoyReadThread::isOK()
|
|
|
+{
|
|
|
+ return mbJoyOK;
|
|
|
+}
|
|
|
+
|
|
|
+double JoyReadThread::GetAcc()
|
|
|
+{
|
|
|
+ return mfAcc;
|
|
|
+}
|
|
|
+
|
|
|
+double JoyReadThread::GetBrake()
|
|
|
+{
|
|
|
+ return mfBrake;
|
|
|
+}
|
|
|
+
|
|
|
+double JoyReadThread::GetWheel()
|
|
|
+{
|
|
|
+ return mfWheel;
|
|
|
+}
|
|
|
+
|
|
|
+int JoyReadThread::GetShift()
|
|
|
+{
|
|
|
+ return mnShift;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+#else
|
|
|
+
|
|
|
+#include <QFile>
|
|
|
+#include <QLibrary>
|
|
|
+#include <iostream>
|
|
|
+#include "dinput.h"
|
|
|
+#include "joyreadthread.h"
|
|
|
+
|
|
|
+#ifdef Q_OS_WIN
|
|
|
+extern HWND gwnd;
|
|
|
+#endif
|
|
|
+
|
|
|
+//void JoyReadThread::LoadAPI()
|
|
|
+//{
|
|
|
+// mbJoyOK = false;
|
|
|
+// std::cout<<"Load Logi g29 API"<<std::endl;
|
|
|
+// QLibrary xlib("./LogitechSteeringWheelEnginesWrapper.dll");
|
|
|
+// if(!xlib.load())
|
|
|
+// {
|
|
|
+// std::cout<<" load LogitechSteeringWheelEnginesWrapper fail."<<xlib.errorString().toStdString()<< std::endl;
|
|
|
+// return ;
|
|
|
+// }
|
|
|
+
|
|
|
+// LogiUpdate =(LogiUpdateFunction)xlib.resolve("LogiUpdate");
|
|
|
+
|
|
|
+// if(LogiUpdate == NULL)
|
|
|
+// {
|
|
|
+// std::cout<<" no this api."<<std::endl;
|
|
|
+// return;
|
|
|
+// }
|
|
|
+// else
|
|
|
+// {
|
|
|
+// std::cout<<" Load API Successfully. "<<std::endl;
|
|
|
+// }
|
|
|
+
|
|
|
+// LogiSteeringInitialize =(LogiSteeringInitializeFunction)xlib.resolve("LogiSteeringInitialize");
|
|
|
+// LogiSteeringInitializeWithWindow =(LogiSteeringInitializeWithWindowFunction)xlib.resolve("LogiSteeringInitializeWithWindow");
|
|
|
+// LogiIsConnected =(LogiIsConnectedFunction)xlib.resolve("LogiIsConnected");
|
|
|
+// LogiGetState =(LogiGetStateFunction)xlib.resolve("LogiGetState");
|
|
|
+// LogiSteeringShutdown =(LogiSteeringShutdownFunction)xlib.resolve("LogiSteeringShutdown");
|
|
|
+// LogiPlayConstantForce =(LogiPlayConstantForceFunction)xlib.resolve("LogiPlayConstantForce");
|
|
|
+// LogiStopConstantForce =(LogiStopConstantForceFunction)xlib.resolve("LogiStopConstantForce");
|
|
|
+
|
|
|
+// if((LogiSteeringInitialize == NULL)||(LogiIsConnected == NULL)||(LogiGetState == NULL)||(LogiSteeringShutdown == NULL)||(LogiSteeringInitializeWithWindow == NULL))
|
|
|
+// {
|
|
|
+// std::cout<<" no this apiS."<<std::endl;
|
|
|
+// return;
|
|
|
+// }
|
|
|
+// else
|
|
|
+// {
|
|
|
+// std::cout<<" Load All API Successfully. "<<std::endl;
|
|
|
+// }
|
|
|
+
|
|
|
+// mbJoyOK = true;
|
|
|
+//}
|
|
|
+
|
|
|
+JoyReadThread::JoyReadThread()
|
|
|
+{
|
|
|
+
|
|
|
+// LoadAPI();
|
|
|
+}
|
|
|
+
|
|
|
+void JoyReadThread::run()
|
|
|
+{
|
|
|
+ if(mbJoyOK == false)return;
|
|
|
+
|
|
|
+ return;
|
|
|
+
|
|
|
+ msleep(3000);
|
|
|
+// bool bStart = LogiSteeringInitialize(false);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ bool bStart = LogiSteeringInitializeWithWindow(false,gwnd);
|
|
|
+ std::cout<<" init. "<<bStart<<std::endl;
|
|
|
+
|
|
|
+ int nFail = 0;
|
|
|
+ while(!QThread::isInterruptionRequested())
|
|
|
+ {
|
|
|
+
|
|
|
+ double angle,acc,brake;
|
|
|
+ if((LogiUpdate())&&(LogiIsConnected(0)))
|
|
|
+ {
|
|
|
+ std::cout<<"get state."<<std::endl;
|
|
|
+ DIJOYSTATE2* wheel = LogiGetState(0);
|
|
|
+ angle = wheel->lX;
|
|
|
+ acc = wheel->lY;
|
|
|
+ brake = wheel->lRz;
|
|
|
+ if(angle>100)
|
|
|
+ {
|
|
|
+ int force;
|
|
|
+ if(angle>3000)force = 30;
|
|
|
+ else
|
|
|
+ {
|
|
|
+ force = angle*30/3000;
|
|
|
+ }
|
|
|
+ LogiPlayConstantForce(0,force);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(angle<-100)
|
|
|
+ {
|
|
|
+ int force;
|
|
|
+ if(angle<-3000)force = -30;
|
|
|
+ else
|
|
|
+ {
|
|
|
+ force = angle*30/3000;
|
|
|
+ }
|
|
|
+ LogiPlayConstantForce(0,force);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ LogiStopConstantForce(0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ mfWheel = angle;
|
|
|
+ mfAcc = acc;
|
|
|
+ mfBrake = brake;
|
|
|
+ nFail = 0;
|
|
|
+ mbJoyOK = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ nFail++;
|
|
|
+ }
|
|
|
+ if(nFail>10)
|
|
|
+ {
|
|
|
+ mbJoyOK = false;
|
|
|
+ }
|
|
|
+ msleep(20);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ LogiSteeringShutdown();
|
|
|
+ mbJoyOK = false;
|
|
|
+}
|
|
|
+
|
|
|
+bool JoyReadThread::isOK()
|
|
|
+{
|
|
|
+ return mbJoyOK;
|
|
|
+}
|
|
|
+
|
|
|
+double JoyReadThread::GetAcc()
|
|
|
+{
|
|
|
+ return mfAcc;
|
|
|
+}
|
|
|
+
|
|
|
+double JoyReadThread::GetBrake()
|
|
|
+{
|
|
|
+ return mfBrake;
|
|
|
+}
|
|
|
+
|
|
|
+double JoyReadThread::GetWheel()
|
|
|
+{
|
|
|
+ return mfWheel;
|
|
|
+}
|
|
|
+
|
|
|
+int JoyReadThread::GetShift()
|
|
|
+{
|
|
|
+ return mnShift;
|
|
|
+}
|
|
|
+
|
|
|
+void JoyReadThread::SetWheel(double fWheel)
|
|
|
+{
|
|
|
+ mfWheel = fWheel;
|
|
|
+}
|
|
|
+void JoyReadThread::SetAcc(double fAcc)
|
|
|
+{
|
|
|
+ mfAcc = fAcc;
|
|
|
+}
|
|
|
+
|
|
|
+void JoyReadThread::SetBrake(double fBrake)
|
|
|
+{
|
|
|
+ mfBrake = fBrake;
|
|
|
+}
|
|
|
+void JoyReadThread::SetJoyOK(bool bOk)
|
|
|
+{
|
|
|
+ mbJoyOK = bOk;
|
|
|
+}
|
|
|
+
|
|
|
+#endif
|