From 6bb2a053be7a77d26914daee7cd9a13e05454528 Mon Sep 17 00:00:00 2001
From: Stanislaw Halik <sthalik@misaki.pl>
Date: Sun, 26 Oct 2014 07:03:37 +0100
Subject: joy tracker allow for input axis remap

---
 .../ftnoir_tracker_joystick.cpp                    |  89 +++--
 ftnoir_tracker_joystick/ftnoir_tracker_joystick.h  |  19 +-
 .../ftnoir_tracker_joystick_controls.ui            | 441 +++++++++++++++++++--
 .../ftnoir_tracker_joystick_dialog.cpp             |  11 +-
 4 files changed, 473 insertions(+), 87 deletions(-)

diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp
index 352448a3..2dc0ad6b 100644
--- a/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp
+++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp
@@ -36,9 +36,9 @@ FTNoIR_Tracker::~FTNoIR_Tracker()
         g_pJoystick->Release();
     }
     if (g_pDI)
-	{
+    {
         g_pDI->Release();
-	}
+    }
 }
 
 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
@@ -47,7 +47,7 @@ static BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
                                    VOID* pContext )
 {
     auto self = (FTNoIR_Tracker*) pContext;
-	
+
     if( pdidoi->dwType & DIDFT_AXIS )
     {
         DIPROPRANGE diprg = {0};
@@ -55,8 +55,8 @@ static BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
         diprg.diph.dwHeaderSize = sizeof( DIPROPHEADER );
         diprg.diph.dwHow = DIPH_BYID;
         diprg.diph.dwObj = pdidoi->dwType;
-	diprg.lMax = FTNoIR_Tracker::AXIS_MAX;
-	diprg.lMin = -FTNoIR_Tracker::AXIS_MAX;
+        diprg.lMax = FTNoIR_Tracker::AXIS_MAX;
+        diprg.lMin = -FTNoIR_Tracker::AXIS_MAX;
 
         if( FAILED( self->g_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
             return DIENUM_STOP;
@@ -69,14 +69,14 @@ static BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
 
 static BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext )
 {
-	auto self = reinterpret_cast<FTNoIR_Tracker*>(pContext);
-	bool stop = QString(pdidInstance->tszInstanceName) == self->s.joyid;
+    auto self = reinterpret_cast<FTNoIR_Tracker*>(pContext);
+    bool stop = QString(pdidInstance->tszInstanceName) == self->s.joyid;
 
-	if (stop)
-	{
-		(void) self->g_pDI->CreateDevice( pdidInstance->guidInstance, &self->g_pJoystick, NULL);
-		qDebug() << "device" << static_cast<QString>(self->s.joyid);
-	}
+    if (stop)
+    {
+        (void) self->g_pDI->CreateDevice( pdidInstance->guidInstance, &self->g_pJoystick, NULL);
+        qDebug() << "device" << static_cast<QString>(self->s.joyid);
+    }
 
     return stop ? DIENUM_STOP : DIENUM_CONTINUE;
 }
@@ -94,8 +94,8 @@ void FTNoIR_Tracker::start_tracker(QFrame* frame)
         qDebug() << "create";
         goto fail;
     }
-	
-	if( FAILED( hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL,
+
+    if( FAILED( hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL,
                                          EnumJoysticksCallback,
                                          this,
                                          DIEDFL_ATTACHEDONLY)))
@@ -152,52 +152,67 @@ void FTNoIR_Tracker::data(double *data)
     if( !g_pDI || !g_pJoystick)
         return;
 
-	bool ok = false;
+    bool ok = false;
 
-	for (int i = 0; i < 100; i++)
-	{
-		if (!FAILED(g_pJoystick->Poll()))
-		{
-			ok = true;
-			break;
-		}
-		if (g_pJoystick->Acquire() != DI_OK)
-			continue;
-		else
-			ok = true;
-		break;
-	}
+    for (int i = 0; i < 100; i++)
+    {
+        if (!FAILED(g_pJoystick->Poll()))
+        {
+                ok = true;
+                break;
+        }
+        if (g_pJoystick->Acquire() != DI_OK)
+                continue;
+        else
+                ok = true;
+        break;
+    }
 
-	if (!ok)
-		return;
+    if (!ok)
+            return;
 
-	HRESULT hr = 0;
+    HRESULT hr = 0;
 
     if( FAILED( hr = g_pJoystick->GetDeviceState( sizeof( js ), &js ) ) )
         return;
 
     const LONG values[] = {
-        js.lRx,
-        js.lRy,
-        js.lRz,
         js.lX,
         js.lY,
         js.lZ,
+        js.lRx,
+        js.lRy,
+        js.lRz,
         js.rglSlider[0],
         js.rglSlider[1]
     };
 
+    int map[6] = {
+        s.joy_1 - 1,
+        s.joy_2 - 1,
+        s.joy_3 - 1,
+        s.joy_4 - 1,
+        s.joy_5 - 1,
+        s.joy_6 - 1,
+    };
+
     const double limits[] = {
         100,
         100,
         100,
         180,
-        90,
+        180,
         180
     };
-    
+
     for (int i = 0; i < 6; i++)
-        data[i] = values[i] * limits[i] / AXIS_MAX;
+    {
+        int k = map[i] - 1;
+        if (k < 0 || k >= 8)
+            data[i] = 0;
+        else
+            data[i] = values[k] * limits[i] / AXIS_MAX;
+    }
 }
 
 extern "C" OPENTRACK_EXPORT ITracker* GetConstructor()
diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h
index d1ae427b..7fb26dfd 100644
--- a/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h
+++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h
@@ -32,17 +32,24 @@ using namespace options;
 struct settings {
     pbundle b;
     value<QString> joyid;
+    value<int> joy_1, joy_2, joy_3, joy_4, joy_5, joy_6;
     settings() :
         b(bundle("tracker-joystick")),
-        joyid(b, "joy-id", "")
+        joyid(b, "joy-id", ""),
+        joy_1(b, "axis-map-1", 1),
+        joy_2(b, "axis-map-2", 2),
+        joy_3(b, "axis-map-3", 3),
+        joy_4(b, "axis-map-4", 4),
+        joy_5(b, "axis-map-5", 5),
+        joy_6(b, "axis-map-6", 6)
     {}
 };
 
 class FTNoIR_Tracker : public ITracker
 {
 public:
-	FTNoIR_Tracker();
-	~FTNoIR_Tracker();
+    FTNoIR_Tracker();
+    ~FTNoIR_Tracker();
     void start_tracker(QFrame *frame);
     void data(double *data);
     void reload();
@@ -53,7 +60,7 @@ public:
     DIDEVICEINSTANCE def;
     int iter; // XXX bad style
     settings s;
-	static constexpr int AXIS_MAX = 65535;
+    static constexpr int AXIS_MAX = 65535;
 };
 
 class TrackerControls: public ITrackerDialog
@@ -68,8 +75,8 @@ public:
     FTNoIR_Tracker* tracker;
     settings s;
 private slots:
-	void doOK();
-	void doCancel();
+    void doOK();
+    void doCancel();
 };
 
 class FTNoIR_TrackerDll : public Metadata
diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui
index 424d1c44..3533f93d 100644
--- a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui
+++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui
@@ -9,36 +9,18 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>458</width>
-    <height>134</height>
+    <width>251</width>
+    <height>303</height>
    </rect>
   </property>
-  <property name="sizePolicy">
-   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-    <horstretch>0</horstretch>
-    <verstretch>0</verstretch>
-   </sizepolicy>
-  </property>
   <property name="windowTitle">
-   <string>Joystick protocol settings</string>
+   <string>Tracker settings</string>
   </property>
   <property name="windowIcon">
    <iconset>
     <normaloff>../facetracknoir/images/facetracknoir.png</normaloff>../facetracknoir/images/facetracknoir.png</iconset>
   </property>
-  <property name="layoutDirection">
-   <enum>Qt::LeftToRight</enum>
-  </property>
-  <property name="autoFillBackground">
-   <bool>false</bool>
-  </property>
-  <layout class="QFormLayout" name="formLayout">
-   <property name="horizontalSpacing">
-    <number>6</number>
-   </property>
-   <property name="verticalSpacing">
-    <number>6</number>
-   </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
    <property name="leftMargin">
     <number>12</number>
    </property>
@@ -51,42 +33,417 @@
    <property name="bottomMargin">
     <number>6</number>
    </property>
-   <item row="0" column="0">
-    <widget class="QLabel" name="label">
-     <property name="text">
-      <string>Joystick</string>
-     </property>
-    </widget>
-   </item>
-   <item row="0" column="1">
-    <widget class="QComboBox" name="joylist">
+   <item>
+    <widget class="QFrame" name="frame">
      <property name="sizePolicy">
-      <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+      <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
+     <property name="frameShape">
+      <enum>QFrame::NoFrame</enum>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <widget class="QLabel" name="label">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>Device</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QComboBox" name="joylist">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+       </widget>
+      </item>
+     </layout>
     </widget>
    </item>
-   <item row="2" column="0" colspan="2">
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+   <item>
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>Mapping</string>
      </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="0" column="1">
+       <widget class="QComboBox" name="joy_1">
+        <property name="currentIndex">
+         <number>1</number>
+        </property>
+        <item>
+         <property name="text">
+          <string>Disabled</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #1</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #2</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #3</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #4</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #5</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #6</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #7</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #8</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QComboBox" name="joy_2">
+        <property name="currentIndex">
+         <number>2</number>
+        </property>
+        <item>
+         <property name="text">
+          <string>Disabled</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #1</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #2</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #3</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #4</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #5</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #6</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #7</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #8</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QComboBox" name="joy_3">
+        <property name="currentIndex">
+         <number>3</number>
+        </property>
+        <item>
+         <property name="text">
+          <string>Disabled</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #1</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #2</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #3</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #4</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #5</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #6</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #7</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #8</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="3" column="1">
+       <widget class="QComboBox" name="joy_4">
+        <property name="currentIndex">
+         <number>4</number>
+        </property>
+        <item>
+         <property name="text">
+          <string>Disabled</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #1</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #2</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #3</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #4</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #5</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #6</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #7</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #8</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="4" column="1">
+       <widget class="QComboBox" name="joy_5">
+        <property name="currentIndex">
+         <number>5</number>
+        </property>
+        <item>
+         <property name="text">
+          <string>Disabled</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #1</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #2</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #3</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #4</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #5</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #6</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #7</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #8</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="5" column="1">
+       <widget class="QComboBox" name="joy_6">
+        <property name="currentIndex">
+         <number>6</number>
+        </property>
+        <item>
+         <property name="text">
+          <string>Disabled</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #1</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #2</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #3</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #4</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #5</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #6</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #7</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Joystick axis #8</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="0" column="0">
+       <widget class="QLabel" name="label_5">
+        <property name="text">
+         <string>X</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_6">
+        <property name="text">
+         <string>Y</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0">
+       <widget class="QLabel" name="label_7">
+        <property name="text">
+         <string>Z</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="0">
+       <widget class="QLabel" name="label_2">
+        <property name="text">
+         <string>Yaw</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="0">
+       <widget class="QLabel" name="label_3">
+        <property name="text">
+         <string>Pitch</string>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="0">
+       <widget class="QLabel" name="label_4">
+        <property name="text">
+         <string>Roll</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
     </widget>
    </item>
-   <item row="1" column="0" colspan="2">
-    <widget class="QLabel" name="label_2">
-     <property name="text">
-      <string>Only first 6 axes available.
-Adjust order in mapping window &quot;output remap&quot; option.</string>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
  <tabstops>
-  <tabstop>joylist</tabstop>
   <tabstop>buttonBox</tabstop>
  </tabstops>
  <resources/>
diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp
index bb95dd92..b201f3f8 100644
--- a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp
+++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp
@@ -37,8 +37,15 @@ fin:
         if (g_pDI)
             g_pDI->Release();
     }
-	
-	tie_setting(s.joyid, ui.joylist);
+
+    tie_setting(s.joyid, ui.joylist);
+
+    tie_setting(s.joy_1, ui.joy_1);
+    tie_setting(s.joy_2, ui.joy_2);
+    tie_setting(s.joy_3, ui.joy_3);
+    tie_setting(s.joy_4, ui.joy_4);
+    tie_setting(s.joy_5, ui.joy_5);
+    tie_setting(s.joy_6, ui.joy_6);
 }
 
 void TrackerControls::doOK() {
-- 
cgit v1.2.3