summaryrefslogtreecommitdiffhomepage
path: root/ftnoir_tracker_joystick
diff options
context:
space:
mode:
Diffstat (limited to 'ftnoir_tracker_joystick')
-rw-r--r--ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp230
-rw-r--r--ftnoir_tracker_joystick/ftnoir_tracker_joystick.h104
-rw-r--r--ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui439
-rw-r--r--ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp66
-rw-r--r--ftnoir_tracker_joystick/ftnoir_tracker_joystick_dll.cpp28
5 files changed, 867 insertions, 0 deletions
diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp
new file mode 100644
index 00000000..f9789dce
--- /dev/null
+++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp
@@ -0,0 +1,230 @@
+#include "ftnoir_tracker_joystick.h"
+#include "facetracknoir/global-settings.h"
+#undef NDEBUG
+#include <QMutexLocker>
+
+FTNoIR_Tracker::FTNoIR_Tracker() :
+ g_pDI(nullptr),
+ g_pJoystick(nullptr),
+ iter(-1),
+ mtx(QMutex::Recursive)
+{
+ for (int i = 0; i < 6; i++)
+ min_[i] = max_[i] = 0;
+ GUID bar = {0};
+}
+
+void FTNoIR_Tracker::reload()
+{
+ s.b->reload();
+ QMutexLocker foo(&mtx);
+ if (g_pJoystick)
+ {
+ g_pJoystick->Unacquire();
+ g_pJoystick->Release();
+ }
+ if (g_pDI)
+ g_pDI->Release();
+
+ g_pJoystick = nullptr;
+ g_pDI = nullptr;
+
+ StartTracker(frame);
+}
+
+FTNoIR_Tracker::~FTNoIR_Tracker()
+{
+ if (g_pJoystick)
+ {
+ g_pJoystick->Unacquire();
+ g_pJoystick->Release();
+ }
+ if (g_pDI)
+ {
+ g_pDI->Release();
+ }
+}
+
+static BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
+ VOID* pContext )
+{
+ auto self = (FTNoIR_Tracker*) pContext;
+
+ // For axes that are returned, set the DIPROP_RANGE property for the
+ // enumerated axis in order to scale min/max values.
+ if( pdidoi->dwType & DIDFT_AXIS )
+ {
+ DIPROPRANGE diprg = {0};
+ diprg.diph.dwSize = sizeof( DIPROPRANGE );
+ diprg.diph.dwHeaderSize = sizeof( DIPROPHEADER );
+ diprg.diph.dwHow = DIPH_BYID;
+ diprg.diph.dwObj = pdidoi->dwType;
+
+ // Set the range for the axis
+
+ if( FAILED( self->g_pJoystick->GetProperty( DIPROP_RANGE, &diprg.diph ) ) )
+ return DIENUM_STOP;
+
+ self->min_[self->iter] = diprg.lMin;
+ self->max_[self->iter] = diprg.lMax;
+ qDebug() << "axis" << self->iter << diprg.lMin << diprg.lMax;
+ self->iter++;
+ }
+
+ return self->iter == 8 ? DIENUM_STOP : DIENUM_CONTINUE;
+}
+
+static BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext )
+{
+ 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);
+ }
+
+ return stop ? DIENUM_STOP : DIENUM_CONTINUE;
+}
+
+void FTNoIR_Tracker::StartTracker(QFrame* frame)
+{
+ QMutexLocker foo(&mtx);
+ this->frame = frame;
+ iter = 0;
+ auto hr = CoInitialize( nullptr );
+
+ if( FAILED( hr = DirectInput8Create( GetModuleHandle( NULL ), DIRECTINPUT_VERSION,
+ IID_IDirectInput8, ( VOID** )&g_pDI, NULL ) ) )
+ {
+ qDebug() << "create";
+ goto fail;
+ }
+
+ if( FAILED( hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL,
+ EnumJoysticksCallback,
+ this,
+ DIEDFL_ATTACHEDONLY)))
+ {
+ qDebug() << "enum2";
+ goto fail;
+ }
+
+ if (!g_pJoystick)
+ {
+ qDebug() << "ENODEV";
+ goto fail;
+ }
+
+ if (FAILED(g_pJoystick->SetDataFormat(&c_dfDIJoystick)))
+ {
+ qDebug() << "format";
+ goto fail;
+ }
+
+ if (FAILED(g_pJoystick->SetCooperativeLevel((HWND) frame->window()->winId(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)))
+ {
+ qDebug() << "coop";
+ goto fail;
+ }
+
+ iter = 0;
+
+ if( FAILED( hr = g_pJoystick->EnumObjects( EnumObjectsCallback,
+ ( VOID* )this, DIDFT_ALL )))
+ {
+ qDebug() << "enum axes";
+ goto fail;
+ }
+
+ qDebug() << "joy init success";
+
+ return;
+
+fail:
+ if (g_pJoystick)
+ g_pJoystick->Release();
+ if (g_pDI)
+ g_pDI->Release();
+ g_pJoystick = nullptr;
+ g_pDI = nullptr;
+
+ qDebug() << "joy init failure";
+}
+
+void FTNoIR_Tracker::GetHeadPoseData(double *data)
+{
+ QMutexLocker foo(&mtx);
+ DIJOYSTATE js = {0};
+
+ if( !g_pDI || !g_pJoystick)
+ return;
+
+ auto hr = g_pJoystick->Poll();
+ if( FAILED( hr ))
+ {
+ hr = g_pJoystick->Acquire();
+ for (int i = 0; hr == DIERR_INPUTLOST && i < 200; i++)
+ hr = g_pJoystick->Acquire();
+ if (hr != DI_OK)
+ {
+ qDebug() << "joy read failure" << hr;
+ return;
+ }
+ }
+
+ 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.rglSlider[0],
+ js.rglSlider[1]
+ };
+
+ const double limits[] = {
+ 100,
+ 100,
+ 100,
+ 180,
+ 90,
+ 180
+ };
+
+ int axes[] = {
+ s.axis_0,
+ s.axis_1,
+ s.axis_2,
+ s.axis_3,
+ s.axis_4,
+ s.axis_5
+ };
+
+ for (int i = 0; i < 6; i++)
+ {
+ auto idx = axes[i] - 1;
+ if (idx < 0 || idx > 7)
+ {
+ data[i] = 0;
+ }
+ else {
+ auto mid = (min_[idx] + max_[idx]) / 2;
+ auto val = values[idx] - mid;
+
+ auto max = (max_[idx] - min_[idx]) / 2;
+ auto min = (min_[idx] - max_[idx]) / -2;
+ data[i] = val * limits[i] / (double) (val >= 0 ? max : min);
+ }
+ }
+}
+
+extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor()
+{
+ return new FTNoIR_Tracker;
+}
diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h
new file mode 100644
index 00000000..06d06186
--- /dev/null
+++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h
@@ -0,0 +1,104 @@
+/* Copyright (c) 2013 Stanislaw Halik <sthalik@misaki.pl>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ */
+#pragma once
+#include "ftnoir_tracker_base/ftnoir_tracker_base.h"
+#include "ui_ftnoir_tracker_joystick_controls.h"
+#include <QComboBox>
+#include <QCheckBox>
+#include <QSpinBox>
+#include <QMessageBox>
+#include <QSettings>
+#include <QList>
+#include <QMutex>
+#include <QFrame>
+#include <cmath>
+#include "facetracknoir/global-settings.h"
+#ifndef DIRECTINPUT_VERSION
+# define DIRECTINPUT_VERSION 0x800
+#endif
+#include <windows.h>
+#include <commctrl.h>
+#include <basetsd.h>
+#include <dinput.h>
+#include <oleauto.h>
+#include <shellapi.h>
+
+#include "facetracknoir/options.h"
+using namespace options;
+
+struct settings {
+ pbundle b;
+ value<int> axis_0;
+ value<int> axis_1;
+ value<int> axis_2;
+ value<int> axis_3;
+ value<int> axis_4;
+ value<int> axis_5;
+ value<QString> joyid;
+ settings() :
+ b(bundle("tracker-joystick")),
+ axis_0(b, "axis-0", 0),
+ axis_1(b, "axis-1", 0),
+ axis_2(b, "axis-2", 0),
+ axis_3(b, "axis-3", 0),
+ axis_4(b, "axis-4", 0),
+ axis_5(b, "axis-5", 0),
+ joyid(b, "joy-id", "")
+ {}
+};
+
+class FTNoIR_Tracker : public ITracker
+{
+public:
+ FTNoIR_Tracker();
+ ~FTNoIR_Tracker();
+ void StartTracker(QFrame *frame);
+ void GetHeadPoseData(double *data);
+ void reload();
+ LPDIRECTINPUT8 g_pDI;
+ LPDIRECTINPUTDEVICE8 g_pJoystick;
+ int min_[8], max_[8];
+ QMutex mtx;
+ QFrame* frame;
+ DIDEVICEINSTANCE def;
+ int iter; // XXX bad style
+ settings s;
+};
+
+class TrackerControls: public QWidget, public ITrackerDialog
+{
+ Q_OBJECT
+public:
+ TrackerControls();
+ void registerTracker(ITracker *foo) {
+ tracker = dynamic_cast<FTNoIR_Tracker*>(foo);
+ }
+ void unRegisterTracker() {
+ tracker = NULL;
+ }
+ QList<GUID> guids;
+ Ui::UIJoystickControls ui;
+ FTNoIR_Tracker* tracker;
+ settings s;
+private slots:
+ void doOK();
+ void doCancel();
+};
+
+class FTNoIR_TrackerDll : public Metadata
+{
+public:
+ void getFullName(QString *strToBeFilled);
+ void getShortName(QString *strToBeFilled);
+ void getDescription(QString *strToBeFilled);
+ void getIcon(QIcon *icon);
+private:
+ QString trackerFullName; // Trackers' name and description
+ QString trackerShortName;
+ QString trackerDescription;
+};
+
diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui
new file mode 100644
index 00000000..5d349169
--- /dev/null
+++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui
@@ -0,0 +1,439 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UIJoystickControls</class>
+ <widget class="QWidget" name="UIJoystickControls">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>216</width>
+ <height>259</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Joystick protocol 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="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="groupBox_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>85</height>
+ </size>
+ </property>
+ <property name="title">
+ <string>Axis enablement</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>X</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_9">
+ <property name="text">
+ <string>Y</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_16">
+ <property name="text">
+ <string>Roll</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QComboBox" name="comboBox_5">
+ <item>
+ <property name="text">
+ <string/>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#2</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#3</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#4</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#5</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#6</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#7</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#8</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <widget class="QComboBox" name="comboBox_6">
+ <item>
+ <property name="text">
+ <string/>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#2</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#3</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#4</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#5</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#6</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#7</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#8</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QComboBox" name="comboBox_4">
+ <item>
+ <property name="text">
+ <string/>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#2</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#3</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#4</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#5</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#6</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#7</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#8</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="comboBox_2">
+ <item>
+ <property name="text">
+ <string/>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#2</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#3</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#4</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#5</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#6</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#7</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#8</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="comboBox">
+ <item>
+ <property name="text">
+ <string/>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#2</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#3</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#4</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#5</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#6</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#7</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#8</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_14">
+ <property name="text">
+ <string>Yaw</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QComboBox" name="comboBox_3">
+ <item>
+ <property name="text">
+ <string/>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#2</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#3</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#4</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#5</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#6</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#7</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>#8</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Z</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_15">
+ <property name="text">
+ <string>Pitch</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Joy Id</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <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>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>joylist</tabstop>
+ <tabstop>comboBox</tabstop>
+ <tabstop>comboBox_2</tabstop>
+ <tabstop>comboBox_3</tabstop>
+ <tabstop>comboBox_4</tabstop>
+ <tabstop>comboBox_5</tabstop>
+ <tabstop>comboBox_6</tabstop>
+ <tabstop>buttonBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+ <slots>
+ <slot>startEngineClicked()</slot>
+ <slot>stopEngineClicked()</slot>
+ <slot>cameraSettingsClicked()</slot>
+ </slots>
+</ui>
diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp
new file mode 100644
index 00000000..b0766634
--- /dev/null
+++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp
@@ -0,0 +1,66 @@
+#include "ftnoir_tracker_joystick.h"
+#include "facetracknoir/global-settings.h"
+
+static BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext )
+{
+ auto self = ( TrackerControls* )pContext;
+
+ self->guids.push_back(pdidInstance->guidInstance);
+ self->ui.joylist->addItem(QString(pdidInstance->tszInstanceName));
+
+ return DIENUM_CONTINUE;
+}
+
+TrackerControls::TrackerControls() : tracker(nullptr)
+{
+ ui.setupUi( this );
+
+ // Connect Qt signals to member-functions
+ connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK()));
+ connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel()));
+
+ tie_setting(s.axis_0, ui.comboBox);
+ tie_setting(s.axis_1, ui.comboBox_2);
+ tie_setting(s.axis_2, ui.comboBox_3);
+ tie_setting(s.axis_3, ui.comboBox_4);
+ tie_setting(s.axis_4, ui.comboBox_5);
+ tie_setting(s.axis_5, ui.comboBox_6);
+
+ {
+ auto hr = CoInitialize( nullptr );
+ LPDIRECTINPUT8 g_pDI = nullptr;
+
+ if( FAILED( hr = DirectInput8Create( GetModuleHandle( NULL ), DIRECTINPUT_VERSION,
+ IID_IDirectInput8, ( VOID** )&g_pDI, NULL ) ) )
+ goto fin;
+
+ if( FAILED( hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL,
+ EnumJoysticksCallback,
+ this,
+ DIEDFL_ATTACHEDONLY )))
+ goto fin;
+
+fin:
+ if (g_pDI)
+ g_pDI->Release();
+ }
+
+ tie_setting(s.joyid, ui.joylist);
+}
+
+void TrackerControls::doOK() {
+ s.b->save();
+ if (tracker)
+ tracker->reload();
+ this->close();
+}
+
+void TrackerControls::doCancel() {
+ s.b->revert();
+ this->close();
+}
+
+extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( )
+{
+ return new TrackerControls;
+}
diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dll.cpp b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dll.cpp
new file mode 100644
index 00000000..325d24a4
--- /dev/null
+++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dll.cpp
@@ -0,0 +1,28 @@
+#include "ftnoir_tracker_joystick.h"
+#include <QDebug>
+#include "facetracknoir/global-settings.h"
+
+void FTNoIR_TrackerDll::getFullName(QString *strToBeFilled)
+{
+ *strToBeFilled = "Joystick";
+}
+
+void FTNoIR_TrackerDll::getShortName(QString *strToBeFilled)
+{
+ *strToBeFilled = "Joystick";
+}
+
+void FTNoIR_TrackerDll::getDescription(QString *strToBeFilled)
+{
+ *strToBeFilled = "Joystick";
+}
+
+void FTNoIR_TrackerDll::getIcon(QIcon *icon)
+{
+ *icon = QIcon(":/images/facetracknoir.png");
+}
+
+extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata()
+{
+ return new FTNoIR_TrackerDll;
+}