//
// Update Headpose in Game.
//
void FTNoIR_Protocol::sendHeadposeToGame(const double *headpose ) {
DWORD result;
TFSState pitch;
TFSState yaw;
TFSState roll;
WORD FSZoom;

float virtPosX;
float virtPosY;
float virtPosZ;

float virtRotX;
float virtRotY;
float virtRotZ;

//	qDebug() << "FSUIPCServer::run() says: started!";

    virtRotX = -headpose[Pitch];				// degrees
    virtRotY = headpose[Yaw];
    virtRotZ = headpose[Roll];

	virtPosX = 0.0f;											// cm, X and Y are not working for FS2002/2004!
	virtPosY = 0.0f;
    virtPosZ = headpose[TZ];

	//
	// Init. the FSUIPC offsets (derived from Free-track...)
	//
	pitch.Control = 66503;
	yaw.Control = 66504;
	roll.Control = 66505;

	//
	// Only do this when the data has changed. This way, the HAT-switch can be used when tracking is OFF.
	//
	if ((prevPosX != virtPosX) || (prevPosY != virtPosY) || (prevPosZ != virtPosZ) ||
		(prevRotX != virtRotX) || (prevRotY != virtRotY) || (prevRotZ != virtRotZ)) {
		//
		// Open the connection
		//
		FSUIPC_Open(SIM_ANY, &result);

		//
		// Check the FS-version
		//
		if  (((result == FSUIPC_ERR_OK) || (result == FSUIPC_ERR_OPEN)) && 
			 ((FSUIPC_FS_Version == SIM_FS2K2) || (FSUIPC_FS_Version == SIM_FS2K4))) {
//			qDebug() << "FSUIPCServer::run() says: FSUIPC opened succesfully";
			//
			// Write the 4! DOF-data to FS. Only rotations and zoom are possible.
			//
			pitch.Value = scale2AnalogLimits(virtRotX, -180, 180);
			FSUIPC_Write(0x3110, 8, &pitch, &result);

			yaw.Value = scale2AnalogLimits(virtRotY, -180, 180);
			FSUIPC_Write(0x3110, 8, &yaw, &result);

			roll.Value = scale2AnalogLimits(virtRotZ, -180, 180);
			FSUIPC_Write(0x3110, 8, &roll, &result);

			FSZoom = (WORD) (64/50) * virtPosZ + 64;
			FSUIPC_Write(0x832E, 2, &FSZoom, &result);

			//
			// Write the data, in one go!
			//
			FSUIPC_Process(&result);
			if (result == FSUIPC_ERR_SENDMSG) {
				FSUIPC_Close();							//timeout (1 second) so assume FS closed
			}
		}
	}

	prevPosX = virtPosX;
	prevPosY = virtPosY;
	prevPosZ = virtPosZ;
	prevRotX = virtRotX;
	prevRotY = virtRotY;
	prevRotZ = virtRotZ;
}
//
// Update Headpose in Game.
//
void FTNoIR_Protocol_MOUSE::sendHeadposeToGame( T6DOF *headpose ) {
float fMouse_X;							// The actual value
float fMouse_Y;
float fMouse_Wheel;


	//
	// Determine which of the 6DOF's is used.
	// The rotations are from -180 to +180 and the translations from -50cm to +50cm.
	// Let's scale the translations to the degrees for simplicity sake...
	//
	switch (Mouse_X) {
		case FTN_PITCH:
			fMouse_X = headpose->position.pitch;
			break;

		case FTN_YAW:
			fMouse_X = headpose->position.yaw;
			break;

		case FTN_ROLL:
			fMouse_X = headpose->position.roll;
			break;

		case FTN_X:
			fMouse_X = headpose->position.x * 3.0f;
			break;

		case FTN_Y:
			fMouse_X = headpose->position.y * 3.0f;
			break;

		case FTN_Z:
			fMouse_X = headpose->position.z * 3.0f;
			break;

		default:
			break;
	}

	//
	// Determine which of the 6DOF's is used.
	// The rotations are from -180 to +180 and the translations from -50cm to +50cm.
	// Let's scale the translations to the degrees for simplicity sake...
	//
	switch (Mouse_Y) {
		case FTN_PITCH:
			fMouse_Y = headpose->position.pitch;
			break;

		case FTN_YAW:
			fMouse_Y = headpose->position.yaw;
			break;

		case FTN_ROLL:
			fMouse_Y = headpose->position.roll;
			break;

		case FTN_X:
			fMouse_Y = headpose->position.x * 3.0f;
			break;

		case FTN_Y:
			fMouse_Y = headpose->position.y * 3.0f;
			break;

		case FTN_Z:
			fMouse_Y = headpose->position.z * 3.0f;
			break;

		default:
			break;
	}

	//
	// Determine which of the 6DOF's is used.
	// The rotations are from -180 to +180 and the translations from -50cm to +50cm.
	// Let's scale the translations to the degrees for simplicity sake...
	//
	switch (Mouse_Wheel) {
		case FTN_PITCH:
			fMouse_Wheel = headpose->position.pitch;
			break;

		case FTN_YAW:
			fMouse_Wheel = headpose->position.yaw;
			break;

		case FTN_ROLL:
			fMouse_Wheel = headpose->position.roll;
			break;

		case FTN_X:
			fMouse_Wheel = headpose->position.x * 3.0f;
			break;

		case FTN_Y:
			fMouse_Wheel = headpose->position.y * 3.0f;
			break;

		case FTN_Z:
			fMouse_Wheel = headpose->position.z * 3.0f;
			break;

		default:
			break;
	}

	//
	// Determine which style is used.
	//
	SecureZeroMemory(&MouseStruct, sizeof(MouseStruct));
	MouseStruct.type = INPUT_MOUSE;
	switch (Mouse_Style) {
		case FTN_ABSOLUTE:
			MouseStruct.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_WHEEL | MOUSEEVENTF_ABSOLUTE;
			if (useVirtualDesk) {
				MouseStruct.mi.dwFlags |= MOUSEEVENTF_VIRTUALDESK;
			}
			MouseStruct.mi.dx = scale2AnalogLimits(-1.0f * fMouse_X * mouse_X_factor, -150, 150);
			MouseStruct.mi.dy = scale2AnalogLimits(fMouse_Y * mouse_Y_factor, -150, 150);
			MouseStruct.mi.mouseData = mouse_Wheel_factor * (fMouse_Wheel - prev_fMouse_Wheel);

			frame_delay = 9999;					// Seems no problem with Absolute positioning
			break;

		case FTN_RELATIVE:
			MouseStruct.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_WHEEL;
			MouseStruct.mi.dx = -1.0f * mouse_X_factor * (fMouse_X - prev_fMouse_X);
			MouseStruct.mi.dy = mouse_Y_factor * (fMouse_Y - prev_fMouse_Y);
			MouseStruct.mi.mouseData = - 1.0f * mouse_Wheel_factor * (fMouse_Wheel - prev_fMouse_Wheel);

			frame_delay += 1;					// Add 1 to the counter
			qDebug() << "sendHeadposeToGame(): FTN_RELATIVE x = " << MouseStruct.mi.dx << ", y = " << MouseStruct.mi.dy;
			break;

		default:
			Mouse_Style = FTN_ABSOLUTE;			// Force to a valid value...
			break;
	}

	//
	// Only send Input, when it has changed.
	// This releases the Mouse, when tracking is stopped (for a while).
	//
	if (frame_delay > 10) {
		if ((prev_fMouse_X != fMouse_X) || (prev_fMouse_Y != fMouse_Y) || (prev_fMouse_Wheel != fMouse_Wheel)) {
			SendInput(1, &MouseStruct, sizeof(MouseStruct));
		}

		prev_fMouse_X = fMouse_X;
		prev_fMouse_Y = fMouse_Y;
		prev_fMouse_Wheel = fMouse_Wheel;
	}
}