From 16c527ee66123ed29ca2d6c0c6baae6e113eda40 Mon Sep 17 00:00:00 2001 From: Wim Vriend Date: Fri, 1 Feb 2013 12:38:35 +0000 Subject: Updated to FreeTrack 2.0 git-svn-id: svn+ssh://svn.code.sf.net/p/facetracknoir/code@258 19e81ba0-9b1a-49c3-bd6c-561e1906d5fb --- FTNoIR_Protocol_FT/FTNoIR_Protocol_FT.cpp | 228 +++++++++++++++++++++++------- FTNoIR_Protocol_FT/FTNoIR_Protocol_FT.h | 19 ++- FTNoIR_Protocol_FT/FTTypes.h | 11 +- 3 files changed, 198 insertions(+), 60 deletions(-) (limited to 'FTNoIR_Protocol_FT') diff --git a/FTNoIR_Protocol_FT/FTNoIR_Protocol_FT.cpp b/FTNoIR_Protocol_FT/FTNoIR_Protocol_FT.cpp index 789b036f..159d3c31 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) 2010 Wim Vriend (Developing) * +* Copyright (C) 2013 Wim Vriend (Developing) * * Ron Hendriks (Researching and Testing) * * * * Homepage * @@ -26,6 +26,7 @@ ********************************************************************************/ /* Modifications (last one on top): + 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 @@ -35,6 +36,7 @@ Now it works direcly in shared memory! */ #include "ftnoir_protocol_ft.h" +#include "csv.h" /** constructor **/ FTNoIR_Protocol::FTNoIR_Protocol() @@ -42,20 +44,48 @@ FTNoIR_Protocol::FTNoIR_Protocol() comhandle = 0; loadSettings(); ProgramName = ""; + intGameID = 0; + + dummyTrackIR = 0; + viewsStart = 0; + viewsStop = 0; } /** destructor **/ FTNoIR_Protocol::~FTNoIR_Protocol() { + + qDebug()<< "~FTNoIR_Protocol: Destructor started."; + // - // Destroy the File-mapping + // Stop if started // - FTDestroyMapping(); + if (viewsStop != NULL) { + qDebug()<< "~FTNoIR_Protocol: Stopping TIRViews."; + viewsStop(); + FTIRViewsLib.unload(); + } + + // + // Kill the dummy TrackIR process. + // + 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"; + } // - // Free the DLL's + // Destroy the File-mapping // - //////FTClientLib.unload(); + FTDestroyMapping(); } /** helper to Auto-destruct **/ @@ -69,6 +99,61 @@ void FTNoIR_Protocol::Initialize() return; } +// +// 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)){ + qDebug()<< "cannot read file!"; + return false; + } + 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" + // + sprintf_s(pMemData->ProgramName, 99, gameLine.at(1).toAscii()); + file.close(); + return true; +} + // // Load the current Settings from the currently 'active' INI-file. // @@ -151,9 +236,6 @@ PDWORD_PTR MsgResult = 0; pMemData->data.Y3 = 0; pMemData->data.Y4 = 0; - //qDebug() << "FTServer says: pMemData.DataID =" << pMemData->data.DataID; - //qDebug() << "FTServer says: ProgramName =" << pMemData->ProgramName; - // // 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! @@ -166,6 +248,63 @@ PDWORD_PTR MsgResult = 0; } } + // + // The game-ID was changed? + // + QString gameID = QString(pMemData->GameID); +// QString gameID = QString("2304"); + + 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); + + // + // Check if TIRViews or dummy TrackIR.exe is required for this game + // + QString ftnID = QString(pMemData->FTNID); + if (ftnID.length() >= 22) { + if (ftnID.at(20) != '0') { + FTIRViewsLib.setFileName(QCoreApplication::applicationDirPath() + "/TIRViews.dll"); + 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!"; + } + } + if (ftnID.at(21) != '0') { + QString program = QCoreApplication::applicationDirPath() + "/TrackIR.exe"; + dummyTrackIR = new QProcess(); + dummyTrackIR->start(program); + + qDebug() << "FTServer::run() says: TrackIR.exe executed!"; + } + } + } + intGameID = gameID.toInt(); + } + } + else { + intGameID = 0; + pMemData->ProgramName[0] = NULL; + pMemData->FTNID[0] = NULL; + pMemData->FTNVERSION[0] = NULL; + } + ReleaseMutex(hFTMutex); } @@ -173,60 +312,32 @@ PDWORD_PTR MsgResult = 0; } // -// Check if the Client DLL exists and load it (to test it), if so. +// 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... +// // Returns 'true' if all seems OK. // +// bool FTNoIR_Protocol::checkServerInstallationOK( HANDLE handle ) { - QSettings settings("Freetrack", "FreetrackClient"); // Registry settings (in HK_USER) - QString aLocation; // Location of Client DLL - QString aFileName; // File Path and Name - - importProvider provider; - char *pProvider; + 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 - qDebug() << "FTCheckClientDLL says: Starting Function"; + qDebug() << "checkServerInstallationOK says: Starting Function"; try { // - // 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). + // Write the path in the registry (for FreeTrack and FreeTrack20), for the game(s). // aLocation = QCoreApplication::applicationDirPath() + "/"; - qDebug() << "FTCheckClientDLL says: Location of DLL =" << aLocation; + settings.setValue( "Path" , aLocation ); + settingsTIR.setValue( "Path" , aLocation ); + + - // - // Append a '/' to the Path and then the name of the 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; - ////////} - } - else { - QMessageBox::information(0, "FaceTrackNoIR error", QString("Necessary file (FreeTrackClient.dll) was NOT found!\n")); - return false; - } } catch(...) { settings.~QSettings(); } @@ -234,12 +345,14 @@ bool FTNoIR_Protocol::checkServerInstallationOK( HANDLE handle ) } // -// Create a memory-mapping to the TrackIR data. +// 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! // // bool FTNoIR_Protocol::FTCreateMapping( HANDLE handle ) { +bool bFirst = false; + qDebug() << "FTCreateMapping says: Starting Function"; // @@ -249,14 +362,18 @@ bool FTNoIR_Protocol::FTCreateMapping( HANDLE handle ) // If one already exists: close it. // hFTMemMap = CreateFileMappingA( INVALID_HANDLE_VALUE , 00 , PAGE_READWRITE , 0 , - sizeof( TFreeTrackData ) + sizeof( HANDLE ) + 100, +// sizeof( TFreeTrackData ) + sizeof( HANDLE ) + 100, + sizeof( FTMemMap ), (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; } @@ -267,8 +384,13 @@ bool FTNoIR_Protocol::FTCreateMapping( HANDLE handle ) 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); + 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; } diff --git a/FTNoIR_Protocol_FT/FTNoIR_Protocol_FT.h b/FTNoIR_Protocol_FT/FTNoIR_Protocol_FT.h index bd461b1e..12a20ee8 100644 --- a/FTNoIR_Protocol_FT/FTNoIR_Protocol_FT.h +++ b/FTNoIR_Protocol_FT/FTNoIR_Protocol_FT.h @@ -40,7 +40,9 @@ #include "Windows.h" //#include "math.h" -typedef char *(WINAPI *importProvider)(void); +//typedef char *(WINAPI *importProvider)(void); +typedef void (WINAPI *importTIRViewsStart)(void); +typedef void (WINAPI *importTIRViewsStop)(void); class FTNoIR_Protocol : public IProtocol { @@ -59,6 +61,9 @@ private: bool FTCreateMapping(HANDLE handle); void FTDestroyMapping(); + importTIRViewsStart viewsStart; // Functions inside TIRViews.dll + importTIRViewsStop viewsStop; + HANDLE hFTMemMap; FTMemMap *pMemData; HANDLE hFTMutex; @@ -68,9 +73,13 @@ private: // Private properties QString ProgramName; - QLibrary FTClientLib; +// QLibrary FTClientLib; + QLibrary FTIRViewsLib; + QProcess *dummyTrackIR; + int intGameID; float getRadsFromDegrees ( float degrees ) { return (degrees * 0.017453f); } + bool getGameData( QString gameID ); void loadSettings(); }; @@ -118,9 +127,9 @@ public: FTNoIR_ProtocolDll(); ~FTNoIR_ProtocolDll(); - void getFullName(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack"); }; - void getShortName(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack"); }; - void getDescription(QString *strToBeFilled) { *strToBeFilled = QString("FreeTrack protocol"); }; + 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 getIcon(QIcon *icon) { *icon = QIcon(":/images/Freetrack.ico"); }; }; diff --git a/FTNoIR_Protocol_FT/FTTypes.h b/FTNoIR_Protocol_FT/FTTypes.h index c83ce90d..ece410ff 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) 2010 Wim Vriend (Developing) * +* Copyright (C) 2013 Wim Vriend (Developing) * * Ron Hendriks (Testing and Research) * * * * Homepage * @@ -25,6 +25,10 @@ * 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 @@ -81,7 +85,10 @@ struct FTMemMap { #else HANDLE handle; #endif - char ProgramName[100]; + 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 }; typedef FTMemMap * PFTMemMap; -- cgit v1.2.3