diff --git a/xpcPlugin/Drawing.cpp b/xpcPlugin/Drawing.cpp new file mode 100644 index 0000000..4e67100 --- /dev/null +++ b/xpcPlugin/Drawing.cpp @@ -0,0 +1,277 @@ +//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the +//National Aeronautics and Space Administration. All Rights Reserved. +#include "Drawing.h" +#include "XPLMDisplay.h" +#include "XPLMGraphics.h" +#include "XPLMDataAccess.h" +#include +#include +#include +//OpenGL includes +#if IBM +#include +#endif +#if __GNUC__ +#include +#else +#include +#endif + +namespace XPC +{ + //Internal Structures + typedef struct + { + double x; + double y; + double z; + } LocalPoint; + + //Internal Memory + static const size_t MSG_MAX = 1024; + static const size_t MSG_LINE_MAX = MSG_MAX / 16; + static bool msgEnabled = false; + static int msgX = -1; + static int msgY = -1; + static char msgVal[MSG_MAX] = { 0 }; + static size_t newLineCount = 0; + static size_t newLines[MSG_LINE_MAX] = { 0 }; + static float rgb[3] = { 0.25F, 1.0F, 0.25F }; + + static const size_t WAYPOINT_MAX = 128; + static bool routeEnabled = false; + static size_t numWaypoints = 0; + static Waypoint waypoints[WAYPOINT_MAX]; + static LocalPoint localPoints[WAYPOINT_MAX]; + + XPLMDataRef planeXref; + XPLMDataRef planeYref; + XPLMDataRef planeZref; + + //Internal Functions + static int cmp(const void * a, const void * b) + { + return (*(size_t*)a - *(size_t*)b); + } + + static void gl_drawCube(float x, float y, float z, float d) + { + //tan(0.25) degrees. Should scale all markers to appear about the same size + const float TAN = 0.00436335082070156648652885284203; + float h = d * TAN; + + glBegin(GL_QUAD_STRIP); + //Top + glVertex3f(x - h, y + h, z - h); + glVertex3f(x + h, y + h, z - h); + glVertex3f(x - h, y + h, z + h); + glVertex3f(x + h, y + h, z + h); + //Front + glVertex3f(x - h, y - h, z + h); + glVertex3f(x + h, y - h, z + h); + //Bottom + glVertex3f(x - h, y - h, z - h); + glVertex3f(x + h, y - h, z - h); + //Back + glVertex3f(x - h, y + h, z - h); + glVertex3f(x + h, y + h, z - h); + + glEnd(); + glBegin(GL_QUADS); + //Left + glVertex3f(x - h, y + h, z - h); + glVertex3f(x - h, y + h, z + h); + glVertex3f(x - h, y - h, z + h); + glVertex3f(x - h, y - h, z - h); + //Right + glVertex3f(x + h, y + h, z + h); + glVertex3f(x + h, y + h, z - h); + glVertex3f(x + h, y - h, z - h); + glVertex3f(x + h, y - h, z + h); + + glEnd(); + } + + static int MessageDrawCallback(XPLMDrawingPhase inPhase, int inIsBefore, void * inRefcon) + { + XPLMDrawString(rgb, msgX, msgY, msgVal, NULL, xplmFont_Basic); + int y = msgY - 16; + for (size_t i = 0; i < newLineCount; ++i) + { + XPLMDrawString(rgb, msgX, y, msgVal + newLines[i], NULL, xplmFont_Basic); + y -= 16; + } + return 1; + } + + static int RouteDrawCallback(XPLMDrawingPhase inPhase, int inIsBefore, void * inRefcon) + { + float px = XPLMGetDataf(planeXref); + float py = XPLMGetDataf(planeYref); + float pz = XPLMGetDataf(planeZref); + + Waypoint* g; + LocalPoint* l; + //Convert to local + for (size_t i = 0; i < numWaypoints; ++i) + { + g = &waypoints[i]; + l = &localPoints[i]; + XPLMWorldToLocal(g->latitude, g->longitude, g->altitude, + &l->x, &l->y, &l->z); + } + + + //Draw posts + glColor3f(1.0F, 1.0F, 1.0F); + glBegin(GL_LINES); + for (size_t i = 0; i < numWaypoints; ++i) + { + l = &localPoints[i]; + glVertex3f((float)l->x, (float)l->y, (float)l->z); + glVertex3f((float)l->x, -1000.0F, (float)l->z); + } + glEnd(); + + //Draw route + glColor3f(1.0F, 0.0F, 0.0F); + glBegin(GL_LINE_STRIP); + for (size_t i = 0; i < numWaypoints; ++i) + { + l = &localPoints[i]; + glVertex3f((float)l->x, (float)l->y, (float)l->z); + } + glEnd(); + + //Draw markers + glColor3f(1.0F, 1.0F, 1.0F); + for (size_t i = 0; i < numWaypoints; ++i) + { + l = &localPoints[i]; + float xoff = (float)l->x - px; + float yoff = (float)l->y - py; + float zoff = (float)l->z - pz; + float d = sqrtf(xoff*xoff + yoff*yoff + zoff*zoff); + gl_drawCube((float)l->x, (float)l->y, (float)l->z, d); + } + return 1; + } + + //Public Functions + void Drawing::ClearMessage() + { + XPLMUnregisterDrawCallback(MessageDrawCallback, xplm_Phase_Window, 0, NULL); + msgEnabled = false; + } + + void Drawing::SetMessage(int x, int y, char* msg) + { + //Determine size of message and clear instead if the message string + //is empty. + size_t len = strnlen(msg, MSG_MAX); + if (len == 0) + { + ClearMessage(); + return; + } + + //Set the message, location, and mark new lines. + strncpy(msgVal, msg, len); + newLineCount = 0; + for (size_t i = 0; i < len && newLineCount < MSG_LINE_MAX; ++i) + { + if (msgVal[i] == '\n' || msgVal[i] == '\r') + { + msgVal[i] = 0; + newLines[newLineCount++] = i + 1; + } + } + msgX = x < 0 ? 10 : x; + msgY = y < 0 ? 600 : y; + + //Enable drawing if necessary + if (!msgEnabled) + { + XPLMRegisterDrawCallback(MessageDrawCallback, xplm_Phase_LastCockpit, 0, NULL); + msgEnabled = true; + } + } + + void Drawing::ClearWaypoints() + { + numWaypoints = 0; + if (routeEnabled) + { + XPLMUnregisterDrawCallback(RouteDrawCallback, xplm_Phase_Objects, 0, NULL); + } + return; + } + + void Drawing::AddWaypoints(Waypoint points[], size_t numPoints) + { + if (numWaypoints + numPoints > WAYPOINT_MAX) + { + numPoints = WAYPOINT_MAX - numWaypoints; + } + size_t finalNumWaypoints = numPoints + numWaypoints; + for (size_t i = 0; i < numPoints; ++i) + { + waypoints[numWaypoints + i] = points[i]; + } + numWaypoints = finalNumWaypoints; + + if (!routeEnabled) + { + XPLMRegisterDrawCallback(RouteDrawCallback, xplm_Phase_Objects, 0, NULL); + } + if (!planeXref) + { + planeXref = XPLMFindDataRef("sim/flightmodel/position/local_x"); + planeYref = XPLMFindDataRef("sim/flightmodel/position/local_y"); + planeZref = XPLMFindDataRef("sim/flightmodel/position/local_z"); + } + } + + void Drawing::RemoveWaypoints(Waypoint points[], size_t numPoints) + { + //Build a list of indices of waypoints we should delete. + size_t delPoints[WAYPOINT_MAX]; + size_t delPointsCur = 0; + for (size_t i = 0; i < numPoints; ++i) + { + Waypoint p = points[i]; + for (size_t j = 0; j < numWaypoints; ++j) + { + Waypoint q = waypoints[j]; + if (p.latitude == q.latitude && + p.longitude == q.longitude && + p.altitude == q.altitude) + { + delPoints[delPointsCur++] = j; + break; + } + } + } + //Sort the indices so that we only have to iterate them once + qsort(delPoints, delPointsCur, sizeof(size_t), cmp); + + //Copy the new array on top of the old array + size_t copyCur = 0; + size_t count = delPointsCur; + delPointsCur = 0; + for (size_t i = 0; i < numWaypoints; ++i) + { + if (i == delPoints[delPointsCur]) + { + ++delPointsCur; + continue; + } + waypoints[copyCur++] = waypoints[i]; + } + numWaypoints -= count; + if (numWaypoints == 0) + { + ClearWaypoints(); + } + } +} \ No newline at end of file diff --git a/xpcPlugin/Drawing.h b/xpcPlugin/Drawing.h new file mode 100644 index 0000000..7dd2927 --- /dev/null +++ b/xpcPlugin/Drawing.h @@ -0,0 +1,55 @@ +//Copyright (c) 2013-2015 United States Government as represented by the Administrator of the +//National Aeronautics and Space Administration. All Rights Reserved. +#ifndef XPC_DRAWING_H +#define XPC_DRAWING_H + +#include +#include "xplaneConnect.h" + +namespace XPC +{ + /// Handles tasks that involve drawing to the screen in X-Plane. + /// + /// \author Jason Watkins + /// \version 1.0 + /// \since 1.0 + /// \date Intial Version: 2015-04-10 + /// \date Last Updated: 2015-04-10 + class Drawing + { + public: + /// Clears the current message on the screen if any and unregisters the + /// draw callback for message drawing. + static void ClearMessage(); + + /// Sets the message to be drawn on the screen. + /// + /// \param x The x coordinate of the message relative to the left edge + /// of the screen. + /// \param y The y coordinate of the message relative to the bottom + /// edge of the screen + /// \param msg A C string containing the message to display. The message + /// value is copied into a local buffer. + static void SetMessage(int x, int y, char* msg); + + /// Adds the given waypoints to the list of waypoints to draw. + /// + /// \param points A pointer to an array of waypoints. + /// \param numPoints The number of points in the array. + static void AddWaypoints(Waypoint points[], size_t numPoints); + + /// Removes all waypoints and unregisters the callback for waypoint + /// drawing. + static void ClearWaypoints(); + + /// Removes the given waypoints from the list of waypoints to draw. + /// If all waypoints are removed as a result of this action, unregisters + /// the callback for waypoint drawing. + /// + /// \param points A pointer to an array of waypoints. + /// \param numPoints The number of points in the array. + static void RemoveWaypoints(Waypoint points[], size_t numPoints); + }; +} + +#endif \ No newline at end of file diff --git a/xpcPlugin/XPCPlugin.cpp b/xpcPlugin/XPCPlugin.cpp index 38ffb73..2a6c51c 100755 --- a/xpcPlugin/XPCPlugin.cpp +++ b/xpcPlugin/XPCPlugin.cpp @@ -60,18 +60,21 @@ #define _WINSOCKAPI_ +// XPC Includes #include "Log.h" +#include "Drawing.h" +#include "xpcPluginTools.h" + +// XPLM Includes +//#include "XPLMPlanes.h" +#include "XPLMProcessing.h" +#include "XPLMGraphics.h" + +// System Includes #include #include #include #include - -//#include "XPLMPlanes.h" -#include "XPLMProcessing.h" -#include "XPLMGraphics.h" -#include "xpcDrawing.h" -#include "xpcPluginTools.h" - #ifdef _WIN32 /* WIN32 SYSTEM */ #include #elif (__APPLE__) @@ -191,10 +194,10 @@ PLUGIN_API void XPluginDisable(void) closeUDP(sendSocket); // Stop rendering messages to screen. - XPCClearMessage(); + XPC::Drawing::ClearMessage(); // Stop rendering waypoints to screen. - XPCClearWaypoints(); + XPC::Drawing::ClearWaypoints(); XPC::Log::WriteLine("[EXEC] xpcPlugin Disabled, sockets closed"); } @@ -498,7 +501,7 @@ int handleTEXT(char *buf, int len) size_t msgLen = (unsigned char)buf[13]; if (msgLen == 0) { - XPCClearMessage(); + XPC::Drawing::ClearMessage(); XPC::Log::WriteLine("[TEXT] Text cleared"); } else @@ -506,7 +509,7 @@ int handleTEXT(char *buf, int len) int x = *((int*)(buf + 5)); int y = *((int*)(buf + 9)); strncpy(msg, buf + 14, msgLen); - XPCSetMessage(x, y, msg); + XPC::Drawing::SetMessage(x, y, msg); XPC::Log::WriteLine("[TEXT] Text set"); } return 0; @@ -837,13 +840,13 @@ int handleWYPT(char buf[], int len) switch (wypt.op) { case xpc_WYPT_ADD: - XPCAddWaypoints(wypt.points, wypt.numPoints); + XPC::Drawing::AddWaypoints(wypt.points, wypt.numPoints); break; case xpc_WYPT_DEL: - XPCRemoveWaypoints(wypt.points, wypt.numPoints); + XPC::Drawing::RemoveWaypoints(wypt.points, wypt.numPoints); break; case xpc_WYPT_CLR: - XPCClearWaypoints(); + XPC::Drawing::ClearWaypoints(); break; default: //If parseWYPT is doing its job, we shouldn't ever hit this. return -2; diff --git a/xpcPlugin/XPlaneConnect/64/win.xpl b/xpcPlugin/XPlaneConnect/64/win.xpl index fc59e9c..76fe77a 100644 Binary files a/xpcPlugin/XPlaneConnect/64/win.xpl and b/xpcPlugin/XPlaneConnect/64/win.xpl differ diff --git a/xpcPlugin/XPlaneConnect/win.xpl b/xpcPlugin/XPlaneConnect/win.xpl index be3ea64..4f6ac16 100644 Binary files a/xpcPlugin/XPlaneConnect/win.xpl and b/xpcPlugin/XPlaneConnect/win.xpl differ diff --git a/xpcPlugin/xpcDrawing.cpp b/xpcPlugin/xpcDrawing.cpp deleted file mode 100644 index d770d27..0000000 --- a/xpcPlugin/xpcDrawing.cpp +++ /dev/null @@ -1,268 +0,0 @@ -#include "xpcDrawing.h" -#include "XPLMDisplay.h" -#include "XPLMGraphics.h" -#include "XPLMDataAccess.h" -#include -#include -#include -//OpenGL includes -#if IBM -#include -#endif -#if __GNUC__ -#include -#else -#include -#endif - -//Internal Structures -typedef struct -{ - double x; - double y; - double z; -} LocalPoint; - -//Internal Memory -static const size_t MSG_MAX = 1024; -static const size_t MSG_LINE_MAX = MSG_MAX / 16; -static bool msgEnabled = false; -static int msgX = -1; -static int msgY = -1; -static char msgVal[MSG_MAX] = { 0 }; -static size_t newLineCount = 0; -static size_t newLines[MSG_LINE_MAX] = { 0 }; -static float rgb[3] = { 0.25F, 1.0F, 0.25F }; - -static const size_t WAYPOINT_MAX = 128; -static bool routeEnabled = false; -static size_t numWaypoints = 0; -static Waypoint waypoints[WAYPOINT_MAX]; -static LocalPoint localPoints[WAYPOINT_MAX]; - -XPLMDataRef planeXref; -XPLMDataRef planeYref; -XPLMDataRef planeZref; - -//Internal Functions -int cmp(const void * a, const void * b) -{ - return (*(size_t*)a - *(size_t*)b); -} - -static void gl_drawCube(float x, float y, float z, float d) -{ - //tan(0.25) degrees. Should scale all markers to appear about the same size - const float TAN = 0.00436335082070156648652885284203; - float h = d * TAN; - - glBegin(GL_QUAD_STRIP); - //Top - glVertex3f(x - h, y + h, z - h); - glVertex3f(x + h, y + h, z - h); - glVertex3f(x - h, y + h, z + h); - glVertex3f(x + h, y + h, z + h); - //Front - glVertex3f(x - h, y - h, z + h); - glVertex3f(x + h, y - h, z + h); - //Bottom - glVertex3f(x - h, y - h, z - h); - glVertex3f(x + h, y - h, z - h); - //Back - glVertex3f(x - h, y + h, z - h); - glVertex3f(x + h, y + h, z - h); - - glEnd(); - glBegin(GL_QUADS); - //Left - glVertex3f(x - h, y + h, z - h); - glVertex3f(x - h, y + h, z + h); - glVertex3f(x - h, y - h, z + h); - glVertex3f(x - h, y - h, z - h); - //Right - glVertex3f(x + h, y + h, z + h); - glVertex3f(x + h, y + h, z - h); - glVertex3f(x + h, y - h, z - h); - glVertex3f(x + h, y - h, z + h); - - glEnd(); -} - -static int MessageDrawCallback(XPLMDrawingPhase inPhase, int inIsBefore, void * inRefcon) -{ - XPLMDrawString(rgb, msgX, msgY, msgVal, NULL, xplmFont_Basic); - int y = msgY - 16; - for (size_t i = 0; i < newLineCount; ++i) - { - XPLMDrawString(rgb, msgX, y, msgVal + newLines[i], NULL, xplmFont_Basic); - y -= 16; - } - return 1; -} - -static int RouteDrawCallback(XPLMDrawingPhase inPhase, int inIsBefore, void * inRefcon) -{ - float px = XPLMGetDataf(planeXref); - float py = XPLMGetDataf(planeYref); - float pz = XPLMGetDataf(planeZref); - - Waypoint* g; - LocalPoint* l; - //Convert to local - for (size_t i = 0; i < numWaypoints; ++i) - { - g = &waypoints[i]; - l = &localPoints[i]; - XPLMWorldToLocal(g->latitude, g->longitude, g->altitude, - &l->x, &l->y, &l->z); - } - - - //Draw posts - glColor3f(1.0F, 1.0F, 1.0F); - glBegin(GL_LINES); - for (size_t i = 0; i < numWaypoints; ++i) - { - l = &localPoints[i]; - glVertex3f((float)l->x, (float)l->y, (float)l->z); - glVertex3f((float)l->x, -1000.0F, (float)l->z); - } - glEnd(); - - //Draw route - glColor3f(1.0F, 0.0F, 0.0F); - glBegin(GL_LINE_STRIP); - for (size_t i = 0; i < numWaypoints; ++i) - { - l = &localPoints[i]; - glVertex3f((float)l->x, (float)l->y, (float)l->z); - } - glEnd(); - - //Draw markers - glColor3f(1.0F, 1.0F, 1.0F); - for (size_t i = 0; i < numWaypoints; ++i) - { - l = &localPoints[i]; - float xoff = (float)l->x - px; - float yoff = (float)l->y - py; - float zoff = (float)l->z - pz; - float d = sqrtf(xoff*xoff + yoff*yoff + zoff*zoff); - gl_drawCube((float)l->x, (float)l->y, (float)l->z, d); - } - return 1; -} - -//Public Functions -void XPCClearMessage() -{ - XPLMUnregisterDrawCallback(MessageDrawCallback, xplm_Phase_Window, 0, NULL); - msgEnabled = false; -} - -void XPCSetMessage(int x, int y, char* msg) -{ - //Determine size of message and clear instead if the message string - //is empty. - size_t len = strnlen(msg, MSG_MAX); - if (len == 0) - { - XPCClearMessage(); - return; - } - - //Set the message, location, and mark new lines. - strncpy(msgVal, msg, len); - newLineCount = 0; - for (size_t i = 0; i < len && newLineCount < MSG_LINE_MAX; ++i) - { - if (msgVal[i] == '\n' || msgVal[i] == '\r') - { - msgVal[i] = 0; - newLines[newLineCount++] = i + 1; - } - } - msgX = x < 0 ? 10 : x; - msgY = y < 0 ? 600 : y; - - //Enable drawing if necessary - if (!msgEnabled) - { - XPLMRegisterDrawCallback(MessageDrawCallback, xplm_Phase_LastCockpit, 0, NULL); - msgEnabled = true; - } -} - -void XPCClearWaypoints() -{ - numWaypoints = 0; - if (routeEnabled) - { - XPLMUnregisterDrawCallback(RouteDrawCallback, xplm_Phase_Objects, 0, NULL); - } - return; -} - -void XPCAddWaypoints(Waypoint points[], size_t numPoints) -{ - if (numWaypoints + numPoints > WAYPOINT_MAX) - { - numPoints = WAYPOINT_MAX - numWaypoints; - } - size_t finalNumWaypoints = numPoints + numWaypoints; - for (size_t i = 0; i < numPoints; ++i) - { - waypoints[numWaypoints + i] = points[i]; - } - numWaypoints = finalNumWaypoints; - - if (!routeEnabled) - { - XPLMRegisterDrawCallback(RouteDrawCallback, xplm_Phase_Objects, 0, NULL); - } - if (!planeXref) - { - planeXref = XPLMFindDataRef("sim/flightmodel/position/local_x"); - planeYref = XPLMFindDataRef("sim/flightmodel/position/local_y"); - planeZref = XPLMFindDataRef("sim/flightmodel/position/local_z"); - } -} - -void XPCRemoveWaypoints(Waypoint points[], size_t numPoints) -{ - //Build a list of indices of waypoints we should delete. - size_t delPoints[WAYPOINT_MAX]; - size_t delPointsCur = 0; - for (size_t i = 0; i < numPoints; ++i) - { - Waypoint p = points[i]; - for (size_t j = 0; j < numWaypoints; ++j) - { - Waypoint q = waypoints[j]; - if (p.latitude == q.latitude && - p.longitude == q.longitude && - p.altitude == q.altitude) - { - delPoints[delPointsCur++] = j; - break; - } - } - } - //Sort the indices so that we only have to iterate them once - qsort(delPoints, delPointsCur, sizeof(size_t), cmp); - - //Copy the new array on top of the old array - size_t copyCur = 0; - size_t count = delPointsCur; - delPointsCur = 0; - for (size_t i = 0; i < numWaypoints; ++i) - { - if (i == delPoints[delPointsCur]) - { - ++delPointsCur; - continue; - } - waypoints[copyCur++] = waypoints[i]; - } - numWaypoints -= count; -} \ No newline at end of file diff --git a/xpcPlugin/xpcDrawing.h b/xpcPlugin/xpcDrawing.h deleted file mode 100644 index 4d79275..0000000 --- a/xpcPlugin/xpcDrawing.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef xpcDrawing_h -#define xpcDrawing_h - -#include -#include "xplaneConnect.h" - -void XPCClearMessage(); - -void XPCSetMessage(int x, int y, char* msg); - -void XPCClearWaypoints(); - -void XPCAddWaypoints(Waypoint points[], size_t numPoints); - -void XPCRemoveWaypoints(Waypoint points[], size_t numPoints); - -#endif diff --git a/xpcPlugin/xpcPlugin/xpcPlugin.vcxproj b/xpcPlugin/xpcPlugin/xpcPlugin.vcxproj index 70d07dd..a3e0ebd 100644 --- a/xpcPlugin/xpcPlugin/xpcPlugin.vcxproj +++ b/xpcPlugin/xpcPlugin/xpcPlugin.vcxproj @@ -99,14 +99,14 @@ + - + - diff --git a/xpcPlugin/xpcPlugin/xpcPlugin.vcxproj.filters b/xpcPlugin/xpcPlugin/xpcPlugin.vcxproj.filters index 6f82ea3..f5b2117 100644 --- a/xpcPlugin/xpcPlugin/xpcPlugin.vcxproj.filters +++ b/xpcPlugin/xpcPlugin/xpcPlugin.vcxproj.filters @@ -21,10 +21,10 @@ Header Files - + Header Files - + Header Files @@ -38,10 +38,10 @@ Source Files - + Source Files - + Source Files