mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-08 07:28:22 -10:00
190 lines
4.1 KiB
C++
190 lines
4.1 KiB
C++
|
|
#ifdef _WIN32
|
|
|
|
#include "headtracking/freetrack.h"
|
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
|
|
namespace
|
|
{
|
|
const char* const LIBRARY_NAME_32 = "FreeTrackClient.dll";
|
|
const char* const LIBRARY_NAME_64 = "FreeTrackClient64.dll";
|
|
|
|
/**
|
|
* @brief Find the location of the FreeTrack library
|
|
*
|
|
* For windows there is a registry entry at HKEY_CURRENT_USER\Software\FreeTrack\FreeTrackClient
|
|
* that specifies where the dll is located.
|
|
*/
|
|
SCP_string getLibraryLocation()
|
|
{
|
|
HKEY hKey = NULL;
|
|
LONG lResult = RegOpenKeyEx(HKEY_CURRENT_USER,
|
|
TEXT("Software\\FreeTrack\\FreeTrackClient"),
|
|
0,
|
|
KEY_QUERY_VALUE,
|
|
&hKey);
|
|
|
|
if (lResult != ERROR_SUCCESS) {
|
|
return "";
|
|
}
|
|
|
|
DWORD dwLen;
|
|
|
|
// First get the size of the value
|
|
lResult = RegQueryValueEx(hKey,
|
|
"Path",
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&dwLen);
|
|
|
|
if (lResult != ERROR_SUCCESS) {
|
|
return "";
|
|
}
|
|
|
|
SCP_string value;
|
|
value.resize(dwLen);
|
|
|
|
dwLen = static_cast<DWORD>(value.size());
|
|
|
|
lResult = RegQueryValueEx(hKey,
|
|
"Path",
|
|
NULL,
|
|
NULL,
|
|
reinterpret_cast<BYTE*>(&value[0]),
|
|
&dwLen);
|
|
|
|
// Windows appends a \0 character at the end
|
|
value.resize(value.length() - 1);
|
|
|
|
// Fix paths without slash at the end
|
|
if (!value.empty() && value[value.length() - 1] != '\\' && value[value.length() - 1] != '/')
|
|
{
|
|
value.append("/");
|
|
}
|
|
|
|
// now append the name of the library and return
|
|
#ifdef _WIN64
|
|
value.append(LIBRARY_NAME_64);
|
|
#else
|
|
value.append(LIBRARY_NAME_32);
|
|
#endif
|
|
return value;
|
|
}
|
|
}
|
|
|
|
namespace headtracking
|
|
{
|
|
namespace freetrack
|
|
{
|
|
FreeTrackLibrary::FreeTrackLibrary() : mFTGetData(nullptr), mFTGetDllVersion(nullptr),
|
|
mFTReportID(nullptr), mFTProvider(nullptr), mEnabled(false)
|
|
{
|
|
if (!LoadExternal(getLibraryLocation().c_str()))
|
|
return;
|
|
|
|
mFTGetData = LoadFunction<FTGetData_PTR>("FTGetData");
|
|
mFTGetDllVersion = LoadFunction<FTGetDllVersion_PTR>("FTGetDllVersion");
|
|
mFTReportID = LoadFunction<FTReportID_PTR>("FTReportName");
|
|
mFTProvider = LoadFunction<FTProvider_PTR>("FTProvider");
|
|
|
|
mEnabled = true;
|
|
}
|
|
|
|
bool FreeTrackLibrary::GetData(FreeTrackData * data)
|
|
{
|
|
if (mFTGetData)
|
|
return mFTGetData(data);
|
|
|
|
return false;
|
|
}
|
|
|
|
char* FreeTrackLibrary::GetDllVersion(void)
|
|
{
|
|
if (mFTGetDllVersion)
|
|
return mFTGetDllVersion();
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void FreeTrackLibrary::ReportID(int name)
|
|
{
|
|
if (mFTReportID)
|
|
mFTReportID(name);
|
|
}
|
|
|
|
char* FreeTrackLibrary::Provider(void)
|
|
{
|
|
if (mFTProvider)
|
|
return mFTProvider();
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
FreeTrackProvider::FreeTrackProvider(): library(FreeTrackLibrary())
|
|
{
|
|
if (!library.Enabled())
|
|
{
|
|
throw internal::HeadTrackingException("Library could not be loaded!");
|
|
}
|
|
|
|
// Try to get initial test data
|
|
FreeTrackData data;
|
|
data.dataID = std::numeric_limits<unsigned int>::max();
|
|
data.camHeight = std::numeric_limits<int>::min();
|
|
data.camWidth = std::numeric_limits<int>::min();
|
|
|
|
if (!library.GetData(&data))
|
|
{
|
|
throw internal::HeadTrackingException("Failed to get test data set!");
|
|
}
|
|
|
|
if (data.dataID == std::numeric_limits<unsigned int>::max() ||
|
|
data.camHeight == std::numeric_limits<int>::min() ||
|
|
data.camWidth == std::numeric_limits<int>::min())
|
|
{
|
|
// Check if all the values have been changed
|
|
throw internal::HeadTrackingException("The test values reported by FreeTrack were invalid!");
|
|
}
|
|
|
|
// I have no idea what a correct value for this function is so I used this random value
|
|
library.ReportID(7919);
|
|
|
|
mprintf(("Found FreeTrack provider '%s' with version %s.\n", library.Provider(), library.GetDllVersion()));
|
|
}
|
|
|
|
FreeTrackProvider::~FreeTrackProvider()
|
|
{
|
|
}
|
|
|
|
bool FreeTrackProvider::query(HeadTrackingStatus* statusOut)
|
|
{
|
|
FreeTrackData data;
|
|
if (!library.GetData(&data))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
statusOut->pitch = data.pitch;
|
|
statusOut->yaw = data.yaw;
|
|
statusOut->roll = data.roll;
|
|
|
|
// Coordinates are in millimeters
|
|
statusOut->x = data.x / 1000.0f;
|
|
statusOut->y = data.y / 1000.0f;
|
|
statusOut->z = data.z / 1000.0f;
|
|
|
|
return true;
|
|
}
|
|
|
|
SCP_string FreeTrackProvider::getName()
|
|
{
|
|
return "FreeTrack";
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif // _WIN32
|