diff --git a/C/src/xplaneConnect.c b/C/src/xplaneConnect.c index fdcba8e..d48ac02 100755 --- a/C/src/xplaneConnect.c +++ b/C/src/xplaneConnect.c @@ -692,6 +692,63 @@ int getTERRResponse(XPCSocket sock, double values[11], char ac) return 0; } +int sendPOST(XPCSocket sock, double posi[], int size, double values[11], char ac) +{ + // Validate input + if (ac < 0 || ac > 20) + { + printError("sendPOST", "aircraft should be a value between 0 and 20."); + return -1; + } + if (size < 1 || size > 7) + { + printError("sendPOST", "size should be a value between 1 and 7."); + return -2; + } + + // Setup command + char buffer[46] = "POST"; + buffer[4] = 0xff; //Placeholder for message length + buffer[5] = ac; + int i; // iterator + + for (i = 0; i < 7; i++) // double for lat/lon/h + { + double val = -998; + + if (i < size) + { + val = posi[i]; + } + if (i < 3) /* lat/lon/h */ + { + memcpy(&buffer[6 + i*8], &val, sizeof(double)); + } + else /* attitude and gear */ + { + float f = (float)val; + memcpy(&buffer[18 + i*4], &f, sizeof(float)); + } + } + + // Send Command + if (sendUDP(sock, buffer, 46) < 0) + { + printError("sendPOST", "Failed to send command"); + return -3; + } + + // Read Response + int result = getTERRResponse(sock, values, ac); + if (result < 0) + { + // A error ocurred while reading the response. + // getTERRResponse will print an error message, so just return. + return result; + } + return 0; +} + int getTERR(XPCSocket sock, double posi[3], double values[11], char ac) { // Send Command diff --git a/C/src/xplaneConnect.h b/C/src/xplaneConnect.h index 67eafba..842a215 100644 --- a/C/src/xplaneConnect.h +++ b/C/src/xplaneConnect.h @@ -159,7 +159,7 @@ int sendDREF(XPCSocket sock, const char* dref, float values[], int size); /// the type described on the wiki. This doesn't cause any data loss for most datarefs. /// \param sock The socket to use to send the command. /// \param drefs The names of the datarefs to set. -/// \param values A 2D array array containing the values for each dataref to set. +/// \param values A 2D array containing the values for each dataref to set. /// \param sizes The number of elements in each array in values /// \param count The number of datarefs being set. /// \returns 0 if successful, otherwise a negative value. @@ -208,7 +208,7 @@ int getPOSI(XPCSocket sock, double values[7], char ac); /// Sets the position and orientation of the specified aircraft. /// /// \param sock The socket to use to send the command. -/// \param values An array representing position data about the aircraft. The format of values is +/// \param values A double array representing position data about the aircraft. The format of values is /// [Lat, Lon, Alt, Pitch, Roll, Yaw, Gear]. If less than 7 values are specified, /// the unspecified values will be left unchanged. /// \param size The number of elements in values. @@ -218,6 +218,23 @@ int sendPOSI(XPCSocket sock, double values[], int size, char ac); // Terrain +/// Sets the position and orientation and gets the terrain information of the specified aircraft. +/// +/// \param sock The socket to use to send the command. +/// \param posi A double array representing position data about the aircraft. The format of values is +/// [Lat, Lon, Alt, Pitch, Roll, Yaw, Gear]. If less than 7 values are specified, +/// the unspecified values will be left unchanged. +/// \param size The number of elements in posi. +/// \param values A double array with the information for the terrain output. The format of values is +/// [Lat, Lon, Alt, Nx, Ny, Nz, Vx, Vy, Vz, wet, result]. The first three are for output of +/// the Lat and Lon of the aircraft with the terrain height directly below. The next three +/// represent the terrain normal. The next three represent the velocity of the terrain. +/// The wet variable is 0.0 if the terrain is dry and 1.0 if wet. +/// The last output is the terrain probe result parameter. +/// \param ac The aircraft number to set the position of. 0 for the main/user's aircraft. +/// \returns 0 if successful, otherwise a negative value. +int sendPOST(XPCSocket sock, double posi[], int size, double values[11], char ac); + /// Gets the terrain information of the specified aircraft. /// /// \param sock The socket to use to send the command. diff --git a/xpcPlugin/Message.cpp b/xpcPlugin/Message.cpp index c1eb448..3dcaf3b 100644 --- a/xpcPlugin/Message.cpp +++ b/xpcPlugin/Message.cpp @@ -138,7 +138,7 @@ namespace XPC cur += 1 + buffer[cur]; } } - else if (head == "POSI") + else if (head == "POSI" || head == "POST") { char aircraft = buffer[5]; float gear; diff --git a/xpcPlugin/MessageHandlers.cpp b/xpcPlugin/MessageHandlers.cpp index 43e90af..9e5c799 100644 --- a/xpcPlugin/MessageHandlers.cpp +++ b/xpcPlugin/MessageHandlers.cpp @@ -63,6 +63,7 @@ namespace XPC handlers.insert(std::make_pair("DREF", MessageHandlers::HandleDref)); handlers.insert(std::make_pair("GETD", MessageHandlers::HandleGetD)); handlers.insert(std::make_pair("POSI", MessageHandlers::HandlePosi)); + handlers.insert(std::make_pair("POST", MessageHandlers::HandlePosT)); handlers.insert(std::make_pair("SIMU", MessageHandlers::HandleSimu)); handlers.insert(std::make_pair("TEXT", MessageHandlers::HandleText)); handlers.insert(std::make_pair("WYPT", MessageHandlers::HandleWypt)); @@ -630,6 +631,21 @@ namespace XPC } } + void MessageHandlers::HandlePosT(const Message& msg) + { + MessageHandlers::HandlePosi(msg); + + const unsigned char* buffer = msg.GetBuffer(); + char aircraftNumber = buffer[5]; + Log::FormatLine(LOG_TRACE, "POST", "Getting terrain information for aircraft %u", aircraftNumber); + + double pos[3]; + pos[0] = DataManager::GetDouble(DREF_Latitude, aircraftNumber); + pos[1] = DataManager::GetDouble(DREF_Longitude, aircraftNumber); + pos[2] = 0.0; + MessageHandlers::SendTerr(pos, aircraftNumber); + } + void MessageHandlers::HandleGetT(const Message& msg) { const unsigned char* buffer = msg.GetBuffer(); diff --git a/xpcPlugin/MessageHandlers.h b/xpcPlugin/MessageHandlers.h index 76c8468..ee39492 100644 --- a/xpcPlugin/MessageHandlers.h +++ b/xpcPlugin/MessageHandlers.h @@ -70,12 +70,13 @@ namespace XPC static void HandleGetC(const Message& msg); static void HandleGetD(const Message& msg); static void HandleGetP(const Message& msg); + static void HandleGetT(const Message& msg); static void HandlePosi(const Message& msg); + static void HandlePosT(const Message& msg); static void HandleSimu(const Message& msg); static void HandleText(const Message& msg); static void HandleWypt(const Message& msg); static void HandleView(const Message& msg); - static void HandleGetT(const Message& msg); static void HandleXPlaneData(const Message& msg); static void HandleUnknown(const Message& msg);