diff options
-rw-r--r-- | CMakeLists.txt | 27 | ||||
-rw-r--r-- | ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp | 241 | ||||
-rw-r--r-- | ftnoir_tracker_joystick/ftnoir_tracker_joystick.h | 105 | ||||
-rw-r--r-- | ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui | 429 | ||||
-rw-r--r-- | ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp | 170 | ||||
-rw-r--r-- | ftnoir_tracker_joystick/ftnoir_tracker_joystick_dll.cpp | 49 |
6 files changed, 1020 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 15b75b45..885e9a96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -239,7 +239,7 @@ if(NOT SDK_FACEAPI_ONLY) file(GLOB opentrack-tracker-aruco-h "ftnoir_tracker_aruco/*.h") file(GLOB opentrack-tracker-aruco-ui "ftnoir_tracker_aruco/*.ui") file(GLOB opentrack-tracker-aruco-rc "ftnoir_tracker_aruco/*.qrc") - QT5_WRAP_UI(opentrack-tracker-aruco-uih ${opentrack-tracker-aruco-ui}) + QT5_WRAP_UI(opentracktracker-aruco-uih ${opentrack-tracker-aruco-ui}) QT5_ADD_RESOURCES(opentrack-tracker-aruco-rcc ${opentrack-tracker-aruco-rc}) file(GLOB opentrack-tracker-pt-c "FTNoIR_Tracker_PT/*.cpp") @@ -255,6 +255,13 @@ if(NOT SDK_FACEAPI_ONLY) file(GLOB opentrack-tracker-udp-rc "ftnoir_tracker_udp/*.qrc") QT5_WRAP_UI(opentrack-tracker-udp-uih ${opentrack-tracker-udp-ui}) QT5_ADD_RESOURCES(opentrack-tracker-udp-rcc ${opentrack-tracker-udp-rc}) + + file(GLOB opentrack-tracker-joystick-c "ftnoir_tracker_joystick/*.cpp") + file(GLOB opentrack-tracker-joystick-h "ftnoir_tracker_joystick/*.h") + file(GLOB opentrack-tracker-joystick-ui "ftnoir_tracker_joystick/*.ui") + file(GLOB opentrack-tracker-joystick-rc "ftnoir_tracker_joystick/*.qrc") + QT5_WRAP_UI(opentrack-tracker-joystick-uih ${opentrack-tracker-joystick-ui}) + QT5_ADD_RESOURCES(opentrack-tracker-joystick-rcc ${opentrack-tracker-joystick-rc}) file(GLOB opentrack-tracker-rift-c "ftnoir_tracker_rift/*.cpp") file(GLOB opentrack-tracker-rift-h "ftnoir_tracker_rift/*.h") @@ -419,6 +426,15 @@ endif() PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_SOURCE_DIR}/facetracknoir/posix-version-script.txt") endif() + if(WIN32) + add_library(opentrack-tracker-joystick SHARED ${opentrack-tracker-joystick-c} ${opentrack-tracker-joystick-h} ${opentrack-tracker-joystick-moc} ${opentrack-tracker-joystick-uih} ${opentrack-tracker-joystick-rcc}) + target_link_libraries(opentrack-tracker-joystick ${MY_QT_LIBS}) + if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUCC) + SET_TARGET_PROPERTIES(opentrack-tracker-joystick + PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_SOURCE_DIR}/facetracknoir/posix-version-script.txt") + endif() + endif() + if(NOT WIN32 AND SDK_WINE_PREFIX) add_library(opentrack-proto-wine SHARED ${opentrack-proto-wine-c} ${opentrack-proto-wine-h} ${opentrack-proto-wine-moc} ${opentrack-proto-wine-uih} ${opentrack-proto-wine-rcc}) target_link_libraries(opentrack-proto-wine ${MY_QT_LIBS} opentrack-compat opentrack-csv) @@ -470,6 +486,11 @@ endif() "${CMAKE_SOURCE_DIR}/dinput/dxguid.lib" "${CMAKE_SOURCE_DIR}/dinput/strmiids.lib" uuid) + target_link_libraries(opentrack-tracker-joystick + "${CMAKE_SOURCE_DIR}/dinput/dinput8.lib" + "${CMAKE_SOURCE_DIR}/dinput/dxguid.lib" + "${CMAKE_SOURCE_DIR}/dinput/strmiids.lib" + uuid) endif() if(OpenCV_FOUND) @@ -669,6 +690,10 @@ if(NOT SDK_FACEAPI_ONLY) NAMELINK_SKIP ) + if(WIN32) + install(TARGETS opentrack-tracker-joystick RUNTIME DESTINATION . LIBRARY DESTINATION . NAMELINK_SKIP) + endif() + if(WIN32 AND SDK_VJOY) install(TARGETS opentrack-proto-vjoy RUNTIME DESTINATION . diff --git a/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp new file mode 100644 index 00000000..35d3927f --- /dev/null +++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.cpp @@ -0,0 +1,241 @@ +#include "ftnoir_tracker_joystick.h" +#include "facetracknoir/global-settings.h" +#undef NDEBUG +#include <cassert> +#include <QMutexLocker> + +static BOOL CALLBACK EnumJoysticksCallback2( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext ) +{ + auto self = ( FTNoIR_Tracker* )pContext; + + self->def = *pdidInstance; + + return self->iter++ == self->joyid ? DIENUM_STOP : DIENUM_CONTINUE; +} + +FTNoIR_Tracker::FTNoIR_Tracker() : + g_pDI(nullptr), + g_pJoystick(nullptr), + joyid(-1), + iter(-1), + mtx(QMutex::Recursive) +{ + for (int i = 0; i < 6; i++) + axes[i] = -1; + GUID foo = {0}; + preferred = foo; +} + +void FTNoIR_Tracker::reload() +{ + QMutexLocker foo(&mtx); + if (g_pJoystick) + { + g_pJoystick->Unacquire(); + g_pJoystick->Release(); + } + if (g_pDI) + g_pDI->Release(); + + 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; + diprg.lMin = -AXIS_MAX; + diprg.lMax = AXIS_MAX; + + // Set the range for the axis + if( FAILED( self->g_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) ) + return DIENUM_STOP; + } + + return DIENUM_CONTINUE; +} + +static BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext ) +{ + DI_ENUM_CONTEXT* pEnumContext = ( DI_ENUM_CONTEXT* )pContext; + + if (!IsEqualGUID(pEnumContext->preferred_instance, pdidInstance->guidInstance)) + return DIENUM_CONTINUE; + + (void) pEnumContext->g_pDI->CreateDevice( pdidInstance->guidInstance, pEnumContext->g_pJoystick, NULL); + + return DIENUM_STOP; +} + +void FTNoIR_Tracker::StartTracker(QFrame* frame) +{ + QMutexLocker foo(&mtx); + iter = 0; + loadSettings(); + auto hr = CoInitialize( nullptr ); + DI_ENUM_CONTEXT enumContext = {0}; + + 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, + EnumJoysticksCallback2, + this, + DIEDFL_ATTACHEDONLY))) + { + qDebug() << "enum2"; + goto fail; + } + + enumContext.pPreferredJoyCfg = &def; + enumContext.g_pDI = g_pDI; + enumContext.g_pJoystick = &g_pJoystick; + enumContext.preferred_instance = def.guidInstance; + + if( FAILED( hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL, + EnumJoysticksCallback, + &enumContext, + DIEDFL_ATTACHEDONLY))) + { + qDebug() << "enum1"; + goto fail; + } + + if (!g_pJoystick) + { + qDebug() << "ENODEV"; + goto fail; + } + + if (FAILED(g_pJoystick->SetDataFormat(&c_dfDIJoystick2))) + { + qDebug() << "format"; + goto fail; + } + + if (FAILED(g_pJoystick->SetCooperativeLevel((HWND) frame->window()->winId(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND))) + { + qDebug() << "coop"; + goto fail; + } + + 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"; +} + +bool FTNoIR_Tracker::GiveHeadPoseData(double *data) +{ + QMutexLocker foo(&mtx); + DIJOYSTATE2 js; + + if( !g_pJoystick) + return false; + +start: + auto hr = g_pJoystick->Poll(); + if( FAILED( hr )) + { + hr = g_pJoystick->Acquire(); + while( hr == DIERR_INPUTLOST ) + hr = g_pJoystick->Acquire(); + goto start; + } + + if( FAILED( hr = g_pJoystick->GetDeviceState( sizeof( DIJOYSTATE2 ), &js ) ) ) + return false; + + const LONG values[] = { + js.lX, + js.lY, + js.lZ, + js.lRx, + js.lRy, + js.lRz, + js.rglSlider[0], + js.rglSlider[1] + }; + + const double max[] = { + 100, + 100, + 100, + 180, + 90, + 180 + }; + + for (int i = 0; i < 6; i++) + { + auto idx = axes[i] - 1; + if (idx < 0 || idx > 7) + { + data[i] = 0; + } + else { + data[i] = values[i] * max[i] / (double) AXIS_MAX; + } + } + + return true; +} + +void FTNoIR_Tracker::loadSettings() { + + QMutexLocker foo(&mtx); + QSettings settings("opentrack"); // Registry settings (in HK_USER) + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); + QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) + iniFile.beginGroup ( "tracker-joy" ); + joyid = iniFile.value("joyid", -1).toInt(); + for (int i = 0; i < 6; i++) + axes[i] = iniFile.value(QString("axis-%1").arg(i), 0).toInt() - 1; + iniFile.endGroup (); +} + +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..72471f3f --- /dev/null +++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick.h @@ -0,0 +1,105 @@ +#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 <math.h> +#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 <dinputd.h> +#include <oleauto.h> +#include <shellapi.h> + +#define AXIS_MAX 8192 + +struct DI_ENUM_CONTEXT +{ + DIDEVICEINSTANCE* pPreferredJoyCfg; + GUID preferred_instance; + LPDIRECTINPUTDEVICE8* g_pJoystick; + LPDIRECTINPUT8 g_pDI; +}; + +class FTNoIR_Tracker : public ITracker +{ +public: + FTNoIR_Tracker(); + ~FTNoIR_Tracker(); + + void StartTracker(QFrame *frame); + bool GiveHeadPoseData(double *data); + void loadSettings(); + LPDIRECTINPUT8 g_pDI; + LPDIRECTINPUTDEVICE8 g_pJoystick; + int axes[6]; + GUID preferred; + int joyid; + QMutex mtx; + QFrame* frame; + DIDEVICEINSTANCE def; + void reload(); + int iter; // XXX bad style +}; + +// Widget that has controls for FTNoIR protocol client-settings. +class TrackerControls: public QWidget, public ITrackerDialog +{ + Q_OBJECT +public: + explicit TrackerControls(); + ~TrackerControls(); + void showEvent (QShowEvent *); + + void Initialize(QWidget *parent); + void registerTracker(ITracker *foo) { + tracker = dynamic_cast<FTNoIR_Tracker*>(foo); + } + void unRegisterTracker() { + tracker = NULL; + } + QList<GUID> guids; + Ui::UIJoystickControls ui; + void loadSettings(); + void save(); + bool settingsDirty; + FTNoIR_Tracker* tracker; + +private slots: + void doOK(); + void doCancel(); + void settingChanged() { settingsDirty = true; } + void settingChanged(int) { settingsDirty = true; } +}; + +//******************************************************************************************************* +// FaceTrackNoIR Tracker DLL. Functions used to get general info on the Tracker +//******************************************************************************************************* +class FTNoIR_TrackerDll : public Metadata +{ +public: + FTNoIR_TrackerDll(); + ~FTNoIR_TrackerDll(); + + 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..a19a3cad --- /dev/null +++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_controls.ui @@ -0,0 +1,429 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>UIJoystickControls</class> + <widget class="QWidget" name="UIJoystickControls"> + <property name="windowModality"> + <enum>Qt::ApplicationModal</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>FTNoIR tracker settings FaceTrackNoIR</string> + </property> + <property name="windowIcon"> + <iconset> + <normaloff>images/FaceTrackNoIR.png</normaloff>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>Yaw</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string>Pitch</string> + </property> + </widget> + </item> + <item row="7" column="0"> + <widget class="QLabel" name="label_16"> + <property name="text"> + <string>Z</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>X</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>Roll</string> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="label_15"> + <property name="text"> + <string>Y</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> + <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..80431b99 --- /dev/null +++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dialog.cpp @@ -0,0 +1,170 @@ +#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() : + QWidget(), tracker(nullptr), settingsDirty(false) +{ + 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())); + + connect(ui.joylist, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged(int))); + connect(ui.comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged(int))); + connect(ui.comboBox_2, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged(int))); + connect(ui.comboBox_3, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged(int))); + connect(ui.comboBox_4, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged(int))); + connect(ui.comboBox_5, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged(int))); + connect(ui.comboBox_6, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged(int))); + + { + 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(); + } + + loadSettings(); +} + +// +// Destructor for server-dialog +// +TrackerControls::~TrackerControls() { +} + +void TrackerControls::Initialize(QWidget *parent) { + QPoint offsetpos(100, 100); + if (parent) { + this->move(parent->pos() + offsetpos); + } + show(); +} + +void TrackerControls::doOK() { + save(); + this->close(); +} + +void TrackerControls::showEvent ( QShowEvent * ) { + loadSettings(); +} + +void TrackerControls::doCancel() { + if (settingsDirty) { + int ret = QMessageBox::question ( this, "Settings have changed", "Do you want to save the settings?", QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Discard ); + + switch (ret) { + case QMessageBox::Save: + save(); + this->close(); + break; + case QMessageBox::Discard: + this->close(); + break; + case QMessageBox::Cancel: + // Cancel was clicked + break; + default: + // should never be reached + break; + } + } + else { + this->close(); + } +} + +void TrackerControls::loadSettings() { + + QSettings settings("opentrack"); // Registry settings (in HK_USER) + + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); + QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) + + QComboBox* boxen[] = { + ui.comboBox, + ui.comboBox_2, + ui.comboBox_3, + ui.comboBox_4, + ui.comboBox_5, + ui.comboBox_6, + }; + + iniFile.beginGroup ( "tracker-joy" ); + for (int i = 0; i < 6; i++) + { + boxen[i]->setCurrentIndex(iniFile.value(QString("axis-%1").arg(i), 0).toInt()); + } + ui.joylist->setCurrentIndex(iniFile.value("joyid", -1).toInt()); + iniFile.endGroup (); + + settingsDirty = false; +} + +void TrackerControls::save() { + QSettings settings("opentrack"); // Registry settings (in HK_USER) + + QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString(); + QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) + + QComboBox* boxen[] = { + ui.comboBox, + ui.comboBox_2, + ui.comboBox_3, + ui.comboBox_4, + ui.comboBox_5, + ui.comboBox_6, + }; + + iniFile.beginGroup ( "tracker-joy" ); + for (int i = 0; i < 6; i++) + { + iniFile.setValue(QString("axis-%1").arg(i), boxen[i]->currentIndex()); + } + iniFile.setValue("joyid", ui.joylist->currentIndex()); + iniFile.endGroup (); + + if(tracker) + { + tracker->reload(); + } + + settingsDirty = false; +} +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Tracker-settings dialog object. + +// Export both decorated and undecorated names. +// GetTrackerDialog - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetTrackerDialog@0 - Common name decoration for __stdcall functions in C language. +//#pragma comment(linker, "/export:GetTrackerDialog=_GetTrackerDialog@0") + +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..c5ee4e5f --- /dev/null +++ b/ftnoir_tracker_joystick/ftnoir_tracker_joystick_dll.cpp @@ -0,0 +1,49 @@ +#include "ftnoir_tracker_joystick.h" +#include <QDebug> +#include "facetracknoir/global-settings.h" + +FTNoIR_TrackerDll::FTNoIR_TrackerDll() { + //populate the description strings + trackerFullName = "Joystick"; + trackerShortName = "Joystick"; + trackerDescription = "joystick"; +} + +FTNoIR_TrackerDll::~FTNoIR_TrackerDll() +{ + +} + +void FTNoIR_TrackerDll::getFullName(QString *strToBeFilled) +{ + *strToBeFilled = trackerFullName; +} + +void FTNoIR_TrackerDll::getShortName(QString *strToBeFilled) +{ + *strToBeFilled = trackerShortName; +} + +void FTNoIR_TrackerDll::getDescription(QString *strToBeFilled) +{ + *strToBeFilled = trackerDescription; +} + +void FTNoIR_TrackerDll::getIcon(QIcon *icon) +{ + *icon = QIcon(":/images/facetracknoir.png"); +} + +//////////////////////////////////////////////////////////////////////////////// +// Factory function that creates instances if the Tracker object. + +// Export both decorated and undecorated names. +// GetTrackerDll - Undecorated name, which can be easily used with GetProcAddress +// Win32 API function. +// _GetTrackerDll@0 - Common name decoration for __stdcall functions in C language. +//#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0") + +extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() +{ + return new FTNoIR_TrackerDll; +} |