From 8303597a865400a363ae574ccde819302495f498 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 2 Apr 2013 18:41:01 +0200 Subject: Just put everything new in. Conflict resolution will be later --- ftnoir_protocol_ft/FreeTrackClient.c | 330 +++++++++++++++++++++++ ftnoir_protocol_ft/ftnoir_ftcontrols.ui | 302 ++------------------- ftnoir_protocol_ft/ftnoir_protocol_ft.cpp | 321 +++++----------------- ftnoir_protocol_ft/ftnoir_protocol_ft.h | 42 ++- ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp | 80 +----- ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp | 7 +- ftnoir_protocol_ft/fttypes.h | 33 +-- ftnoir_protocol_ft/images/freetrack.ico | Bin 0 -> 17542 bytes 8 files changed, 453 insertions(+), 662 deletions(-) create mode 100644 ftnoir_protocol_ft/FreeTrackClient.c create mode 100644 ftnoir_protocol_ft/images/freetrack.ico (limited to 'ftnoir_protocol_ft') diff --git a/ftnoir_protocol_ft/FreeTrackClient.c b/ftnoir_protocol_ft/FreeTrackClient.c new file mode 100644 index 00000000..b1b62123 --- /dev/null +++ b/ftnoir_protocol_ft/FreeTrackClient.c @@ -0,0 +1,330 @@ +/******************************************************************************** +* FreeTrackClientDll Implements the FreeTrack 2.0 interface for FT-enabled * +* games. * +* It uses the FreeTrack protocol (memory mapping) to * +* receive data from FaceTrackNoIR (or FreeTrack, or ...). * +* * +* Copyright (C) 2013 Wim Vriend (Developing) * +* Ron Hendriks (Testing and Research) * +* * +* Homepage * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the * +* Free Software Foundation; either version 3 of the License, or (at your * +* option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but * +* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program; if not, see . * +* * +********************************************************************************/ +/* + Modifications (last one on top): + + 20130208 - WVR: The old DLL from FreeTrack seems to crash ArmA2. And we need 64-bit support. + +*/ + +/* + * COMPILE WITH: + * % i686-w64-mingw32-gcc -shared -o FreeTrackClient.dll -O2 FreeTrackClient.c + * DO NOT USE MSVC! IT INTRODUCES FAULTY MANIFEST!!! + * -- sthalik + */ + +#ifdef WIN64 +#pragma comment(linker, "/export:FTGetData") +#pragma comment(linker, "/export:FTReportName") +#pragma comment(linker, "/export:FTGetDllVersion") +#pragma comment(linker, "/export:FTProvider") +#endif + +#define FT_DECLSPEC __declspec(dllexport) + +#define FT_EXPORT(t) FT_DECLSPEC t __stdcall +#define NP_AXIS_MAX 16383 + +#include +#include +#include +#include +#include +#include + +typedef struct TFreeTrackData { + int DataID; + int CamWidth; + int CamHeight; + // virtual pose + float Yaw; // positive yaw to the left + float Pitch; // positive pitch up + float Roll; // positive roll to the left + float X; + float Y; + float Z; + // raw pose with no smoothing, sensitivity, response curve etc. + float RawYaw; + float RawPitch; + float RawRoll; + float RawX; + float RawY; + float RawZ; + // raw points, sorted by Y, origin top left corner + float X1; + float Y1; + float X2; + float Y2; + float X3; + float Y3; + float X4; + float Y4; +} TFreeTrackData; +typedef TFreeTrackData * PFreetrackData; + +// +// Functions to create/open the file-mapping +// and to destroy it again. +// +float scale2AnalogLimits( float x, float min_x, float max_x ); +float getDegreesFromRads ( float rads ); +FT_EXPORT(BOOL) FTCreateMapping(void); + +#if 0 +static FILE *debug_stream; +#define dbg_report(...) if (debug_stream) { fprintf(debug_stream, __VA_ARGS__); fflush(debug_stream); } +#else +#define dbg_report(...) +#endif + +// +// Handles to 'handle' the memory mapping +// +#define FT_MM_DATA "FT_SharedMem" +#define FREETRACK_MUTEX "FT_Mutext" + +static HANDLE hFTMemMap = 0; +static TFreeTrackData *pMemData = 0; +static HANDLE hFTMutex = 0; +static const char* dllVersion = "1.0.0.0"; +static const char* dllProvider = "FreeTrack"; + +static unsigned short gameid = 0; + +// +// DllMain gets called, when the DLL is (un)loaded or a process attaches. +// +FT_EXPORT(BOOL) WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + switch (fdwReason) { + case DLL_PROCESS_ATTACH: +#ifdef WIN64 + dbg_report("\n= WIN64 =========================================================================================\n"); +#else + dbg_report("\n= WIN32 =========================================================================================\n"); +#endif + dbg_report("DllMain: (0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); + dbg_report("DllMain: Attach request\n"); +// debug_stream = fopen("c:\\FreeTrackClient.log", "a"); + DisableThreadLibraryCalls(hinstDLL); + break; + + case DLL_PROCESS_DETACH: + dbg_report("DllMain: Detach\n"); + dbg_report("DllMain: (0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); + dbg_report("==========================================================================================\n"); + break; + } + return TRUE; +} + +/****************************************************************** + * FTGetData (FreeTrackClient.1) + */ +#pragma comment(linker, "/export:FTGetData@4=FTGetData") +FT_EXPORT(BOOL) FTGetData(TFreeTrackData* data) +{ + static int frame = 0; + static int prevDataID = 0; + static int dlyTrackingOff = 0; + static int tracking = 0; + +// dbg_report("NP_GetData called."); + if (FTCreateMapping() == FALSE) return FALSE; + + if (hFTMutex && WaitForSingleObject(hFTMutex, 5) == WAIT_OBJECT_0) { + if (pMemData) { + + // + // When FaceTrackNoIR does not update frames (any more), don't update the data. + // + if (prevDataID != pMemData->DataID) { + *data = *pMemData; + dlyTrackingOff = 0; + } + else { + dlyTrackingOff++; + if (dlyTrackingOff > 20) { + dlyTrackingOff = 100; + tracking = FALSE; + } + } + prevDataID = pMemData->DataID; + + // + // Limit the range of DataID + // + if (pMemData->DataID > 1000) { + pMemData->DataID = 0; + } + data->DataID = pMemData->DataID; + + // + // Send the ID to FaceTrackNoIR, so it can display the game-name. + // This could be a FreeTrack-specific ID + // + //sprintf(pMemData->GameID, "%d", gameid ); + + } + ReleaseMutex(hFTMutex); + } + return TRUE; +} + +/****************************************************************** + * FTReportName (FreeTrackClient.2) + */ +#pragma comment(linker, "/export:FTReportName@4=FTReportName") +// +// For some mysterious reason, the previously existing function FTReportID has been changed to FTReportName, but with an integer as argument. +// The Delphi-code from the FreeTrack repo suggest a char * as argument, so it cost me an afternoon to figure it out (and keep ArmA2 from crashing). +// Thanks guys! +// +FT_EXPORT(void) FTReportName( int name ) +{ + dbg_report("FTReportName request (ID = %d).\n", name); + gameid = name; // They might have really passed the name here... but they didn't! + return; +} + +/****************************************************************** + * FTGetDllVersion (FreeTrackClient.3) + */ +#pragma comment(linker, "/export:FTGetDllVersion@0=FTGetDllVersion") +FT_EXPORT(const char*) FTGetDllVersion(void) +{ + dbg_report("FTGetDllVersion request.\n"); + + return dllVersion; +} + +/****************************************************************** + * FTProvider (FreeTrackClient.4) + */ +#pragma comment(linker, "/export:FTProvider@0=FTProvider") +FT_EXPORT(const char*) FTProvider(void) +{ + dbg_report("FTProvider request.\n"); + + return dllProvider; +} + +// +// Create a memory-mapping to the Freetrack data. +// It contains the tracking data, a handle to the main-window and the program-name of the Game! +// +// +#pragma comment(linker, "/export:FTCreateMapping@0=FTCreateMapping") +FT_EXPORT(BOOL) FTCreateMapping(void) +{ + BOOL bMappingExists = FALSE; + PDWORD_PTR MsgResult = 0; + + // + // Memory-mapping already exists! + // + if ( pMemData != NULL ) { + return TRUE; + } + + dbg_report("FTCreateMapping request (pMemData == NULL).\n"); + + // + // A FileMapping is used to create 'shared memory' between the FTClient and the FTServer. + // + // Try to create a FileMapping to the Shared Memory. This is done to check if it's already there (what + // may mean the face-tracker program is already running). + // + // If one already exists: close it and open the file-mapping to the existing one. + // + hFTMemMap = CreateFileMappingA( INVALID_HANDLE_VALUE , 00 , PAGE_READWRITE , 0 , + sizeof( TFreeTrackData ), + (LPCSTR) FT_MM_DATA ); + + if ( ( hFTMemMap != 0 ) && ( GetLastError() == ERROR_ALREADY_EXISTS ) ) { + dbg_report("FTCreateMapping: Mapping already exists.\n"); + bMappingExists = TRUE; // So the server was (probably) already started! + CloseHandle( hFTMemMap ); + hFTMemMap = 0; + } + + // + // Create a new FileMapping, Read/Write access + // + hFTMemMap = OpenFileMappingA( FILE_MAP_ALL_ACCESS , FALSE , (LPCSTR) FT_MM_DATA ); + if ( ( hFTMemMap != 0 ) ) { + dbg_report("FTCreateMapping: Mapping opened.\n"); + pMemData = (TFreeTrackData *) MapViewOfFile(hFTMemMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof( TFreeTrackData ) ); + hFTMutex = CreateMutexA(NULL, FALSE, FREETRACK_MUTEX); + } + else { + return FALSE; + } + return TRUE; +} + +// +// Destory the FileMapping to the shared memory +// +#pragma comment(linker, "/export:FTDestroyMapping@0=FTDestroyMapping") +FT_EXPORT(void) FTDestroyMapping(void) +{ + if ( pMemData != NULL ) { + UnmapViewOfFile ( pMemData ); + } + + CloseHandle( hFTMutex ); + CloseHandle( hFTMemMap ); + pMemData = 0; + hFTMemMap = 0; +} + +// +// 4 convenience +// +float getDegreesFromRads ( float rads ) { + return (rads * 57.295781f); +} + +// +// Scale the measured value to the TIR values +// +float scale2AnalogLimits( float x, float min_x, float max_x ) { +double y; +double local_x; + + local_x = x; + if (local_x > max_x) { + local_x = max_x; + } + if (local_x < min_x) { + local_x = min_x; + } + y = ( NP_AXIS_MAX * local_x ) / max_x; + + return (float) y; +} diff --git a/ftnoir_protocol_ft/ftnoir_ftcontrols.ui b/ftnoir_protocol_ft/ftnoir_ftcontrols.ui index fc5abbcf..34873c76 100644 --- a/ftnoir_protocol_ft/ftnoir_ftcontrols.ui +++ b/ftnoir_protocol_ft/ftnoir_ftcontrols.ui @@ -6,22 +6,16 @@ 0 0 - 645 - 416 + 411 + 112 - - - 645 - 0 - - - FreeTrack 2.0 settings FaceTrackNoIR + FreeTrack settings FaceTrackNoIR - images/FaceTrackNoIR.icoimages/FaceTrackNoIR.ico + images/freetrack.pngimages/freetrack.png Qt::LeftToRight @@ -31,282 +25,7 @@ - - - - - - 0 - 70 - - - - TIRViews - - - - - 80 - 30 - 88 - 17 - - - - Qt::RightToLeft - - - Use TIRViews - - - - - - 189 - 10 - 421 - 16 - - - - TIRViews is only required for some older games (like CFS3). For it to work, TIRViews.dll - - - - - - 189 - 30 - 421 - 16 - - - - must be placed in the FaceTrackNoIR program folder. If the checkbox is disabled, the - - - true - - - - - - 189 - 50 - 411 - 16 - - - - the DLL was not found. You can get it from NaturalPoint. - - - - - - - - - 0 - 70 - - - - TrackIR.exe - - - - - 20 - 30 - 145 - 17 - - - - Qt::RightToLeft - - - Start dummy TrackIR.exe - - - - - - 189 - 10 - 351 - 16 - - - - Some programs check, to see if a process called TrackIR.exe is running, - - - - - - 189 - 30 - 261 - 16 - - - - before enabling head-tracking (EZCA is one of them). - - - true - - - - - - 189 - 50 - 231 - 16 - - - - Check the checkbox, to overcome this problem. - - - - - - - - - 0 - 70 - - - - Select interface - - - - - 189 - 10 - 351 - 16 - - - - Some games support both FreeTrack and TrackIR and may get confused, - - - - - - 189 - 30 - 261 - 16 - - - - when both interfaces are visible. - - - true - - - - - - 189 - 50 - 381 - 16 - - - - Try to disable one interface, if you experience problems. - - - - - - 6 - 30 - 168 - 22 - - - - - - - - - - 0 - 70 - - - - Repair NPClient location - - - - - 188 - 10 - 381 - 20 - - - - Users who use other software with an NPClient DLL (like TrackIR, FreeTrack or - - - - - - 184 - 30 - 411 - 20 - - - - GlovePIE) may need to repair the location of the DLL, after running FaceTrackNoIR. - - - true - - - - - - 187 - 50 - 391 - 20 - - - - Use this button to locate the desired NPClient DLL. - - - - - - 4 - 30 - 171 - 23 - - - - Locate DLL - - - - + @@ -335,6 +54,17 @@ + + + + + + There are no settings necessary for the FreeTrack protocol. + + + + + diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp index b8461993..1482d76c 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft.cpp @@ -3,7 +3,7 @@ * gamers from Holland, who don't like to pay much for * * head-tracking. * * * -* Copyright (C) 2013 Wim Vriend (Developing) * +* Copyright (C) 2010 Wim Vriend (Developing) * * Ron Hendriks (Researching and Testing) * * * * Homepage * @@ -26,10 +26,6 @@ ********************************************************************************/ /* Modifications (last one on top): - 20130209 - WVR: Some games support both interfaces and cause trouble. Added ComboBox to fix this (hide one interface - by clearing the appropriate Registry-setting). - 20130203 - WVR: Added Tirviews and dummy checkboxes to the Settings dialog. This is necessary for CFS3 etc. - 20130125 - WVR: Upgraded to FT2.0: now the FreeTrack protocol supports all TIR-enabled games. 20110401 - WVR: Moved protocol to a DLL, convenient for installation etc. 20101224 - WVR: Base class is no longer inheriting QThread. sendHeadposeToGame is called from run() of Tracker.cpp @@ -39,154 +35,48 @@ Now it works direcly in shared memory! */ #include "ftnoir_protocol_ft.h" -#include "csv.h" +#include "facetracknoir/global-settings.h" /** constructor **/ FTNoIR_Protocol::FTNoIR_Protocol() { comhandle = 0; - useTIRViews = false; - useDummyExe = false; - intUsedInterface = 0; - - // - // Load the INI-settings. - // loadSettings(); - ProgramName = ""; - intGameID = 0; - - dummyTrackIR = 0; - viewsStart = 0; - viewsStop = 0; - } /** destructor **/ FTNoIR_Protocol::~FTNoIR_Protocol() { - - qDebug()<< "~FTNoIR_Protocol: Destructor started."; - // - // Stop if started - // - if (viewsStop != NULL) { - qDebug()<< "~FTNoIR_Protocol: Stopping TIRViews."; - viewsStop(); - FTIRViewsLib.unload(); - } - - // - // Kill the dummy TrackIR process. + // Destroy the File-mapping // - qDebug() << "~FTNoIR_Protocol() about to kill TrackIR.exe process"; - try { - if (dummyTrackIR) { - qDebug() << "FTServer::~FTServer() about to kill TrackIR.exe process"; -// dummyTrackIR->close(); - dummyTrackIR->kill(); - } - } - catch (...) - { - qDebug() << "~FTServer says: some error occurred"; - } + FTDestroyMapping(); // - // Destroy the File-mapping + // Free the DLL's // - FTDestroyMapping(); + //////FTClientLib.unload(); } -void FTNoIR_Protocol::Initialize() +/** helper to Auto-destruct **/ +void FTNoIR_Protocol::Release() { - return; + delete this; } -// -// Read the game-data from CSV -// -bool FTNoIR_Protocol::getGameData( QString gameID ){ -QStringList gameLine; - - qDebug() << "getGameData, ID = " << gameID; - - // - // Open the supported games list, to get the Name. - // - QFile file(QCoreApplication::applicationDirPath() + "/Settings/FaceTrackNoIR Supported Games.csv"); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){ - QString strError( "Cannot load file: FaceTrackNoIR Supported Games.csv" ); - sprintf_s(pMemData->ProgramName, 99, strError.toAscii()); - sprintf_s(pMemData->FTNVERSION, 9, "V160"); - - // - // Return true anyway, because maybe it's V160 compatible. - // - return true; - } - CSV csv(&file); - gameLine = csv.parseLine(); - - while (gameLine.count() > 2) { - //qDebug() << "Column 0: " << gameLine.at(0); // No. - //qDebug() << "Column 1: " << gameLine.at(1); // Game Name - //qDebug() << "Column 2: " << gameLine.at(2); // Game Protocol - //qDebug() << "Column 3: " << gameLine.at(3); // Supported since version - //qDebug() << "Column 4: " << gameLine.at(4); // Verified - //qDebug() << "Column 5: " << gameLine.at(5); // By - //qDebug() << "Column 6: " << gameLine.at(6); // International ID - //qDebug() << "Column 7: " << gameLine.at(7); // FaceTrackNoIR ID - - // - // If the gameID was found, fill the shared memory - // - if (gameLine.count() > 6) { - if (gameLine.at(6).compare( gameID, Qt::CaseInsensitive ) == 0) { - if (pMemData != NULL) { - sprintf_s(pMemData->ProgramName, 99, gameLine.at(1).toAscii()); - sprintf_s(pMemData->FTNVERSION, 9, gameLine.at(3).toAscii()); - sprintf_s(pMemData->FTNID, 24, gameLine.at(7).toAscii()); - } - file.close(); - return true; - } - } - - gameLine = csv.parseLine(); - } - - // - // If the gameID was NOT found, fill only the name "Unknown game connected" - // - QString strUnknown("Unknown game connected (ID = " + gameID + ")"); - sprintf_s(pMemData->ProgramName, 99, strUnknown.toAscii()); - file.close(); - return true; +void FTNoIR_Protocol::Initialize() +{ + QSettings settings("NaturalPoint", "NATURALPOINT\\NPClient Location"); + QString aLocation = QCoreApplication::applicationDirPath() + "/"; + if (QFile::exists( aLocation + "/npclient.dll" )) + settings.setValue( "Path" , aLocation ); } // // Load the current Settings from the currently 'active' INI-file. // void FTNoIR_Protocol::loadSettings() { - QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // 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 ( "FT" ); - intUsedInterface = iniFile.value ( "UsedInterface", 0 ).toInt(); - iniFile.endGroup (); - - // - // Use the settings-section from the deprecated fake-TIR protocol, as they are most likely to be found there. - // - iniFile.beginGroup ( "FTIR" ); - useTIRViews = iniFile.value ( "useTIRViews", 0 ).toBool(); - useDummyExe = iniFile.value ( "useDummyExe", 1 ).toBool(); - iniFile.endGroup (); } // @@ -209,10 +99,7 @@ float headRotX; float headRotY; float headRotZ; -PDWORD_PTR MsgResult = 0; - - - // + // // Scale the Raw measurements to the client measurements. // headRotX = getRadsFromDegrees(headpose->pitch); @@ -265,145 +152,82 @@ PDWORD_PTR MsgResult = 0; pMemData->data.Y3 = 0; pMemData->data.Y4 = 0; - // - // Check if the handle that was sent to the Game, was changed (on x64, this will be done by the ED-API) - // If the "Report Program Name" command arrives (which is a '1', for now), raise the event from here! - // - if (hMainWindow != pMemData->handle) { // Handle in memory-mapping was changed! - comhandle = (__int32) pMemData->handle; // Get the command from the Game. - if (comhandle == 1) { // "Report Program Name" - SendMessageTimeout( (HWND) hMainWindow, RegisterWindowMessageA(FT_PROGRAMID), 0, 0, 0, 2000, MsgResult); - pMemData->handle = 0; // Reset the command, to enable future commands... - } - } + //qDebug() << "FTServer says: pMemData.DataID =" << pMemData->data.DataID; + //qDebug() << "FTServer says: ProgramName =" << pMemData->ProgramName; // - // The game-ID was changed? - // - QString gameID = QString(pMemData->GameID); - //QString gameID = QString("9999"); - -// qDebug() << "sendHeadposeToGame: gameID = " << gameID; - if (gameID.length() > 0) { - if ( gameID.toInt() != intGameID ) { - if (getGameData( gameID ) ) { - SendMessageTimeout( (HWND) hMainWindow, RegisterWindowMessageA(FT_PROGRAMID), 0, 0, 0, 2000, MsgResult); - } - intGameID = gameID.toInt(); - } - } - else { - intGameID = 0; - pMemData->ProgramName[0] = NULL; - pMemData->FTNID[0] = NULL; - pMemData->FTNVERSION[0] = NULL; - } - ReleaseMutex(hFTMutex); } - pMemData->data.DataID += 1; + if (pMemData) + pMemData->data.DataID += 1; } // -// Set the Path variables and load the memory-mapping. -// Simplified function: No need to check if the DLL's actually exist. The are installed by the installer. -// If they are absent, something went terribly wrong anyway... -// +// Check if the Client DLL exists and load it (to test it), if so. // Returns 'true' if all seems OK. // -// -bool FTNoIR_Protocol::checkServerInstallationOK( HANDLE handle ) +bool FTNoIR_Protocol::checkServerInstallationOK() { - QSettings settings("Freetrack", "FreetrackClient"); // Registry settings (in HK_USER) - QSettings settingsTIR("NaturalPoint", "NATURALPOINT\\NPClient Location"); // Registry settings (in HK_USER) - QString aLocation; // Location of Client DLL + QSettings settings("Freetrack", "FreetrackClient"); // Registry settings (in HK_USER) + QString aLocation; // Location of Client DLL + QString aFileName; // File Path and Name - qDebug() << "checkServerInstallationOK says: Starting Function"; + qDebug() << "FTCheckClientDLL says: Starting Function"; try { // - // Write the path in the registry (for FreeTrack and FreeTrack20), for the game(s). + // Load the FreeTrackClient.dll from the current path of FaceTrackNoIR, because there is no + // guarantee FreeTrack is also installed. + // + // Write this path in the registry (under FreeTrack/FreeTrackClient, for the game(s). // aLocation = QCoreApplication::applicationDirPath() + "/"; - - qDebug() << "checkServerInstallationOK says: used interface = " << intUsedInterface; - switch (intUsedInterface) { - case 0: // Use both interfaces - settings.setValue( "Path" , aLocation ); - settingsTIR.setValue( "Path" , aLocation ); - break; - case 1: // Use FreeTrack, disable TrackIR - settings.setValue( "Path" , aLocation ); - settingsTIR.setValue( "Path" , "" ); - break; - case 2: // Use TrackIR, disable FreeTrack - settings.setValue( "Path" , "" ); - settingsTIR.setValue( "Path" , aLocation ); - break; - default: - // should never be reached - break; - } + qDebug() << "FTCheckClientDLL says: Location of DLL =" << aLocation; // - // TIRViews must be started first, or the NPClient DLL will never be loaded. + // Append a '/' to the Path and then the name of the dll. // - if (useTIRViews) { - - QString aFileName = QCoreApplication::applicationDirPath() + "/TIRViews.dll"; - if ( QFile::exists( aFileName ) ) { - - FTIRViewsLib.setFileName(aFileName); - FTIRViewsLib.load(); - - viewsStart = (importTIRViewsStart) FTIRViewsLib.resolve("TIRViewsStart"); - if (viewsStart == NULL) { - qDebug() << "FTServer::run() says: TIRViewsStart function not found in DLL!"; - } - else { - qDebug() << "FTServer::run() says: TIRViewsStart executed!"; - viewsStart(); - } - - // - // Load the Stop function from TIRViews.dll. Call it when terminating the thread. - // - viewsStop = (importTIRViewsStop) FTIRViewsLib.resolve("TIRViewsStop"); - if (viewsStop == NULL) { - qDebug() << "FTServer::run() says: TIRViewsStop function not found in DLL!"; - } - } + aFileName = aLocation; + aFileName.append(FT_CLIENT_FILENAME); + qDebug() << "FTCheckClientDLL says: Full path of DLL =" << aFileName; + + if ( QFile::exists( aFileName ) ) { + qDebug() << "FTCheckClientDLL says: DLL exists!"; + // + // Write the path to the key in the Registry, so the game(s) can find it too... + // + settings.setValue( "Path" , aLocation ); + + // + // Load the DLL and map to the functions in it. + // + ////////FTClientLib.setFileName(aFileName); + ////////FTClientLib.load(); + ////////provider = (importProvider) FTClientLib.resolve("FTProvider"); + ////////if (provider) { + //////// pProvider = provider(); + //////// qDebug() << "FTCheckClientDLL says: Provider =" << pProvider; + ////////} } - - // - // Check if TIRViews or dummy TrackIR.exe is required for this game - // - if (useDummyExe) { - QString program = QCoreApplication::applicationDirPath() + "/TrackIR.exe"; - dummyTrackIR = new QProcess(); - dummyTrackIR->start(program); - - qDebug() << "FTServer::run() says: TrackIR.exe executed!"; + else { + QMessageBox::information(0, "FaceTrackNoIR error", QString("Necessary file (FreeTrackClient.dll) was NOT found!\n")); + return false; } - - } catch(...) { settings.~QSettings(); } - return FTCreateMapping( handle ); + return FTCreateMapping(); } // -// Create a memory-mapping to the FreeTrack data. +// Create a memory-mapping to the TrackIR data. // It contains the tracking data, a handle to the main-window and the program-name of the Game! // // -bool FTNoIR_Protocol::FTCreateMapping( HANDLE handle ) +bool FTNoIR_Protocol::FTCreateMapping() { -bool bFirst = false; - qDebug() << "FTCreateMapping says: Starting Function"; // @@ -413,18 +237,14 @@ bool bFirst = false; // If one already exists: close it. // hFTMemMap = CreateFileMappingA( INVALID_HANDLE_VALUE , 00 , PAGE_READWRITE , 0 , -// sizeof( TFreeTrackData ) + sizeof( HANDLE ) + 100, - sizeof( FTMemMap ), + sizeof( TFreeTrackData ) + sizeof( HANDLE ) + 100, (LPCSTR) FT_MM_DATA ); if ( hFTMemMap != 0 ) { - bFirst = true; qDebug() << "FTCreateMapping says: FileMapping Created!" << hFTMemMap; } if ( ( hFTMemMap != 0 ) && ( (long) GetLastError == ERROR_ALREADY_EXISTS ) ) { - bFirst = false; - qDebug() << "FTCreateMapping says: FileMapping already exists!" << hFTMemMap; CloseHandle( hFTMemMap ); hFTMemMap = 0; } @@ -435,16 +255,7 @@ bool bFirst = false; hFTMemMap = OpenFileMappingA( FILE_MAP_ALL_ACCESS , false , (LPCSTR) FT_MM_DATA ); if ( ( hFTMemMap != 0 ) ) { qDebug() << "FTCreateMapping says: FileMapping Opened:" << hFTMemMap; - pMemData = (FTMemMap *) MapViewOfFile(hFTMemMap, FILE_MAP_ALL_ACCESS, 0, 0, -// sizeof(TFreeTrackData) + sizeof(hFTMemMap) + 100); - sizeof(FTMemMap)); - if (pMemData != NULL) { - if (bFirst) { - memset(pMemData, 0, sizeof(FTMemMap)); // Write zero's, if first... - } - pMemData->handle = handle; // The game uses the handle, to send a message that the Program-Name was set! - hMainWindow = handle; - } + pMemData = (FTMemMap *) MapViewOfFile(hFTMemMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(TFreeTrackData) + sizeof(hFTMemMap) + 100); hFTMutex = CreateMutexA(NULL, false, FREETRACK_MUTEX); } else { @@ -481,7 +292,7 @@ void FTNoIR_Protocol::FTDestroyMapping() // void FTNoIR_Protocol::getNameFromGame( char *dest ) { - sprintf_s(dest, 99, "FreeTrack interface"); + sprintf(dest, "FreeTrack interface"); qDebug() << "FTNoIR_Protocol::getNameFromGame says: Started, pMemData = " << pMemData << ", mutex = " << hFTMutex; @@ -491,7 +302,7 @@ void FTNoIR_Protocol::getNameFromGame( char *dest ) // if ( (pMemData != NULL) && (WaitForSingleObject(hFTMutex, 100) == WAIT_OBJECT_0) ) { if (pMemData != NULL) { qDebug() << "FTNoIR_Protocol::getNameFromGame says: Inside MemData"; - sprintf_s(dest, 99, "%s", pMemData->ProgramName); + sprintf(dest, "%s", pMemData->ProgramName); } return; @@ -505,9 +316,9 @@ void FTNoIR_Protocol::getNameFromGame( char *dest ) // GetProtocol - Undecorated name, which can be easily used with GetProcAddress // Win32 API function. // _GetProtocol@0 - Common name decoration for __stdcall functions in C language. -#pragma comment(linker, "/export:GetProtocol=_GetProtocol@0") +//#pragma comment(linker, "/export:GetProtocol=_GetProtocol@0") -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolPtr __stdcall GetProtocol() +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetConstructor() { - return new FTNoIR_Protocol; + return (IProtocol*) new FTNoIR_Protocol; } diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft.h b/ftnoir_protocol_ft/ftnoir_protocol_ft.h index c82c3e79..690984a4 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft.h +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft.h @@ -28,21 +28,21 @@ #ifndef INCLUDED_FTSERVER_H #define INCLUDED_FTSERVER_H -#include "..\ftnoir_protocol_base\ftnoir_protocol_base.h" -#include "ui_FTNoIR_FTcontrols.h" -#include "FTTypes.h" +#include "ftnoir_protocol_base/ftnoir_protocol_base.h" +#include "ui_ftnoir_ftcontrols.h" +#include "fttypes.h" #include #include #include #include #include #include -#include "Windows.h" +#include +// todo wine glue //#include "math.h" +#include "facetracknoir/global-settings.h" -//typedef char *(WINAPI *importProvider)(void); -typedef void (WINAPI *importTIRViewsStart)(void); -typedef void (WINAPI *importTIRViewsStop)(void); +typedef char *(WINAPI *importProvider)(void); class FTNoIR_Protocol : public IProtocol { @@ -53,35 +53,25 @@ public: void Release(); void Initialize(); - bool checkServerInstallationOK( HANDLE handle ); + bool checkServerInstallationOK(); void sendHeadposeToGame( THeadPoseData *headpose, THeadPoseData *rawheadpose ); void getNameFromGame( char *dest ); // Take care dest can handle up to 100 chars... private: - bool FTCreateMapping(HANDLE handle); + bool FTCreateMapping(); void FTDestroyMapping(); - importTIRViewsStart viewsStart; // Functions inside TIRViews.dll - importTIRViewsStop viewsStop; - HANDLE hFTMemMap; FTMemMap *pMemData; HANDLE hFTMutex; - HANDLE hMainWindow; // Save the handle to FaceTrackNoIR main-window __int32 comhandle; // Handle on x32, command on x64 // Private properties QString ProgramName; - QLibrary FTIRViewsLib; - QProcess *dummyTrackIR; - int intGameID; - int intUsedInterface; // Determine which interface to use (or to hide from the game) - bool useTIRViews; // Needs to be in the Settings dialog - bool useDummyExe; + QLibrary FTClientLib; float getRadsFromDegrees ( float degrees ) { return (degrees * 0.017453f); } - bool getGameData( QString gameID ); void loadSettings(); }; @@ -115,27 +105,25 @@ private: FTNoIR_Protocol *theProtocol; private slots: - void selectDLL(); void doOK(); void doCancel(); void settingChanged() { settingsDirty = true; }; - void settingChanged(int) { settingsDirty = true; }; }; //******************************************************************************************************* // FaceTrackNoIR Protocol DLL. Functions used to get general info on the Protocol //******************************************************************************************************* -class FTNoIR_ProtocolDll : public IProtocolDll +class FTNoIR_ProtocolDll : public Metadata { public: FTNoIR_ProtocolDll(); ~FTNoIR_ProtocolDll(); - void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack 2.0"); }; - void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack 2.0"); }; - void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("Enhanced FreeTrack protocol"); }; + void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack"); }; + void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack"); }; + void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack protocol"); }; - void getIcon(QIcon *icon) { *icon = QIcon(":/images/Freetrack.ico"); }; + void getIcon(QIcon *icon) { *icon = QIcon(":/images/freetrack.png"); }; }; diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp index 2e6c91f7..46dd263f 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft_dialog.cpp @@ -32,7 +32,7 @@ */ #include "ftnoir_protocol_ft.h" #include -#include +#include "facetracknoir/global-settings.h" //******************************************************************************************************* // FaceTrackNoIR Client Settings-dialog. @@ -51,36 +51,12 @@ QWidget() // Connect Qt signals to member-functions connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); - connect(ui.bntLocateNPClient, SIGNAL(clicked()), this, SLOT(selectDLL())); - connect(ui.chkTIRViews, SIGNAL(stateChanged(int)), this, SLOT(settingChanged())); - connect(ui.chkStartDummy, SIGNAL(stateChanged(int)), this, SLOT(settingChanged())); - connect(ui.cbxSelectInterface, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged( int ))); - - ui.cbxSelectInterface->addItem("Enable both"); - ui.cbxSelectInterface->addItem("Use FreeTrack, hide TrackIR"); - ui.cbxSelectInterface->addItem("Use TrackIR, hide FreeTrack"); +// connect(ui.chkTIRViews, SIGNAL(stateChanged(int)), this, SLOT(chkTIRViewsChanged())); theProtocol = NULL; // Load the settings from the current .INI-file loadSettings(); - - - aFileName = QCoreApplication::applicationDirPath() + "/TIRViews.dll"; - if ( !QFile::exists( aFileName ) ) { - ui.chkTIRViews->setChecked( false ); - ui.chkTIRViews->setEnabled ( false ); - - // - // Best do this save() last, or it will continually reset the settings... :-( - // - save(); - } - else { - ui.chkTIRViews->setEnabled ( true ); - } - - } // @@ -90,6 +66,11 @@ FTControls::~FTControls() { qDebug() << "~FTControls() says: started"; } +void FTControls::Release() +{ + delete this; +} + // // Initialize tracker-client-dialog // @@ -161,12 +142,7 @@ void FTControls::loadSettings() { qDebug() << "loadSettings says: iniFile = " << currentFile; iniFile.beginGroup ( "FT" ); - ui.cbxSelectInterface->setCurrentIndex( iniFile.value ( "UsedInterface", 0 ).toInt() ); - iniFile.endGroup (); - - iniFile.beginGroup ( "FTIR" ); - ui.chkTIRViews->setChecked (iniFile.value ( "useTIRViews", 0 ).toBool()); - ui.chkStartDummy->setChecked (iniFile.value ( "useDummyExe", 1 ).toBool()); +// ui.chkTIRViews->setChecked (iniFile.value ( "useTIRViews", 0 ).toBool()); iniFile.endGroup (); settingsDirty = false; @@ -182,44 +158,12 @@ void FTControls::save() { QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file) iniFile.beginGroup ( "FT" ); - iniFile.setValue ( "UsedInterface", ui.cbxSelectInterface->currentIndex()); - iniFile.endGroup (); - - iniFile.beginGroup ( "FTIR" ); - iniFile.setValue ( "useTIRViews", ui.chkTIRViews->isChecked() ); - iniFile.setValue ( "useDummyExe", ui.chkStartDummy->isChecked() ); +// iniFile.setValue ( "useTIRViews", ui.chkTIRViews->isChecked() ); iniFile.endGroup (); settingsDirty = false; } -// -// Select a NPClient.dll file, to repair the Location in the Registry. -// Several program distribute their own version of this file. -// -void FTControls::selectDLL() { - QFileDialog::Options options; - QFileDialog::FileMode mode; - - options |= QFileDialog::DontUseNativeDialog; - mode = QFileDialog::ExistingFile; - QString selectedFilter; - QString fileName = QFileDialog::getOpenFileName( this, tr("Select the desired NPClient DLL"), QCoreApplication::applicationDirPath() + "/NPClient.dll", tr("Dll file (*.dll);;All Files (*)")); - - // - // Write the location of the file in the required Registry-key. - // - if (! fileName.isEmpty() ) { - if (fileName.endsWith("NPClient.dll", Qt::CaseInsensitive) ) { - QSettings settingsTIR("NaturalPoint", "NATURALPOINT\\NPClient Location"); // Registry settings (in HK_USER) - QString aLocation = fileName.left(fileName.length() - 12); // Location of Client DLL - - settingsTIR.setValue( "Path" , aLocation ); - } - } -} - - //////////////////////////////////////////////////////////////////////////////// // Factory function that creates instances if the Protocol-settings dialog object. @@ -227,9 +171,9 @@ void FTControls::selectDLL() { // GetProtocolDialog - Undecorated name, which can be easily used with GetProcAddress // Win32 API function. // _GetProtocolDialog@0 - Common name decoration for __stdcall functions in C language. -#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0") +//#pragma comment(linker, "/export:GetProtocolDialog=_GetProtocolDialog@0") -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDialogPtr __stdcall GetProtocolDialog( ) +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT void* CALLING_CONVENTION GetDialog( ) { - return new FTControls; + return (IProtocolDialog*) new FTControls; } diff --git a/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp b/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp index 4513c6ba..1209e38b 100644 --- a/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp +++ b/ftnoir_protocol_ft/ftnoir_protocol_ft_dll.cpp @@ -32,6 +32,7 @@ */ #include "ftnoir_protocol_ft.h" #include +#include "facetracknoir/global-settings.h" FTNoIR_ProtocolDll::FTNoIR_ProtocolDll() { } @@ -48,9 +49,9 @@ FTNoIR_ProtocolDll::~FTNoIR_ProtocolDll() // GetProtocolDll - Undecorated name, which can be easily used with GetProcAddress // Win32 API function. // _GetProtocolDll@0 - Common name decoration for __stdcall functions in C language. -#pragma comment(linker, "/export:GetProtocolDll=_GetProtocolDll@0") +//#pragma comment(linker, "/export:GetProtocolDll=_GetProtocolDll@0") -FTNOIR_PROTOCOL_BASE_EXPORT IProtocolDllPtr __stdcall GetProtocolDll() +extern "C" FTNOIR_PROTOCOL_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() { - return new FTNoIR_ProtocolDll; + return new FTNoIR_ProtocolDll; } diff --git a/ftnoir_protocol_ft/fttypes.h b/ftnoir_protocol_ft/fttypes.h index 1f389711..3f411cfe 100644 --- a/ftnoir_protocol_ft/fttypes.h +++ b/ftnoir_protocol_ft/fttypes.h @@ -4,7 +4,7 @@ * It was loosely translated from FTTypes.pas * * which was created by the FreeTrack-team. * * * -* Copyright (C) 2013 Wim Vriend (Developing) * +* Copyright (C) 2010 Wim Vriend (Developing) * * Ron Hendriks (Testing and Research) * * * * Homepage * @@ -25,26 +25,23 @@ * We would like to extend our grattitude to the creators of SweetSpotter, * * which has become the basis of this program: "Great work guys!" * ********************************************************************************/ -/* - Modifications (last one on top): - 20130125 - WVR: Upgraded to FT2.0: now the FreeTrack protocol supports all TIR-enabled games. The memory-mapping was expanded for this purpose. -*/ #pragma once #ifndef INCLUDED_FTTYPES_H #define INCLUDED_FTTYPES_H -#include "Windows.h" +#include #include #include //#include "Registry.h" // static const char* FT_CLIENT_LOCATION = "Software\\Freetrack\\FreetrackClient"; - static const char* FT_CLIENT_FILENAME = "FreeTrackClient.Dll"; - static const char* FT_MM_DATA = "FT_SharedMem"; - static const char* FREETRACK = "Freetrack"; - static const char* FREETRACK_MUTEX = "FT_Mutext"; - static const char* FT_PROGRAMID = "FT_ProgramID"; + +#define FT_CLIENT_FILENAME "FreeTrackClient.Dll" +#define FT_MM_DATA "FT_SharedMem" +#define FREETRACK "Freetrack" +#define FREETRACK_MUTEX "FT_Mutext" +#define FT_PROGRAMID "FT_ProgramID" struct TFreeTrackData { @@ -85,20 +82,10 @@ struct FTMemMap { #else HANDLE handle; #endif - char ProgramName[100]; // The name of the game - char GameID[10]; // The international game-ID - char FTNID[30]; // The FaceTrackNoIR game-ID - char FTNVERSION[10]; // The version of FaceTrackNoIR, in which the game was first supported + char ProgramName[100]; }; typedef FTMemMap * PFTMemMap; -//extern bool (*FTGetData) (PFreetrackData data); -// DLL function signatures -// These match those given in FTTypes.pas -// WINAPI is macro for __stdcall defined somewhere in the depths of windows.h -typedef bool (WINAPI *importGetData)(TFreeTrackData * data); -typedef char *(WINAPI *importGetDllVersion)(void); -typedef void (WINAPI *importReportID)(int name); -typedef char *(WINAPI *importProvider)(void); +extern bool (*FTGetData) (PFreetrackData data); #endif//INCLUDED_FTTYPES_H diff --git a/ftnoir_protocol_ft/images/freetrack.ico b/ftnoir_protocol_ft/images/freetrack.ico new file mode 100644 index 00000000..02554c3d Binary files /dev/null and b/ftnoir_protocol_ft/images/freetrack.ico differ -- cgit v1.2.3