Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Eggman1414

Pages: [1]
1
General / Double Click without events - Help!
« on: March 01, 2017, 03:39:40 am »
Hello dear SFML'ers. I have a problem that I hope you can help me with. I am using the joystick module from sfml to read gamepad inputs from a PLRF25C Rangefinder. Everything works great, the program sees the button and changes states when pressed. The issue I am running into is because I am using SFML inside the .dll I am writing for a Plugin for VRSG, I can not use events. I need to be able to detect a double and a multiple click inside the double click.

Link for PLRF: http://www.vectronix.us/XooWebKit/bin/download.php/203a_b21acf3fdd/PLRF25C%20(web).pdf

For example:

If I hold the button, the lcd inside the PLRF displays the current heading(Deg Magnetic).
When the button is let go, the PLRF displays the range for a couple of seconds.

If the button is pressed again within a second or two it needs to enter a new state, where each sequential button press will show other data (Range,Vertical Distance, Horizontal Distance, Heading, Inclination angle) and just cycle those data values.

Button Held: Show Heading

Button Release from first click: Show Range

Click again within a sec: Show Vertical Distance
click again: show Horizontal Distance
click again: Show Vertical Distance
click again: show inclination angle
click again and just repeat the cycle.

I have included my code to see if anyone can help me or point me in the right direction. I have holding and releasing of the button to display heading and range but not the double click stuff. Most of the code is probably not useful to you but I included it anyway.

// HUD Plugin.cpp : Defines the initialization routines for the DLL.
//

#include <afxwin.h>
#include "stdafx.h" // Must be here, otherwise lots of errors
#include <afxdlgs.h>
#include <afxcmn.h>
#include <afxdllx.h>
#include <d3d11.h>
#include <stdio.h>
#include <math.h>
#include <time.h>

#include "SFML\Window.hpp"
#include "VertexShader.h"
#include "PixelShader.h"
#include "Resource.h"
#include "Plugins.h"
#include "Vector.h"
#include "Coord.h"
#include "Geodesy.h"
#include "Dis.h"
#include "Swap.h"



static AFX_EXTENSION_MODULE NEAR extensionDLL = { NULL, NULL };

#define SAFE_RELEASE(p) { if (p) { (p)->Release();  (p) = NULL; } }

static ID3D11Texture2D          *pWhiteTexture;
static ID3D11ShaderResourceView *pWhiteTextureSRV;
static ID3D11Texture2D          *pFontTexture;
static ID3D11ShaderResourceView *pFontTextureSRV;
static ID3D11SamplerState       *pSampler;

static ID3D11VertexShader       *pVertexShader;
static ID3D11PixelShader        *pPixelShader;
static ID3D11InputLayout        *pLayout;

static ID3D11Buffer             *pVB;
static ID3D11Buffer             *pIB;

#define VB_MAX 5000  // Max verts in our buffer before we reset
#define IB_MAX 2000  // Max indices in the buffer before we reset

static int vertsInBuffer;   // Position in vertex buffer to insert next primitive's verts
static int indicesInBuffer; // Position in vertex buffer to insert next primitive's indices

extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
        if (dwReason == DLL_PROCESS_ATTACH)
        {
                // Extension DLL one-time initialization.
                if (!AfxInitExtensionModule(extensionDLL, hInstance))
                        return 0;

                // Other initialization could be done here, as long as
                // it doesn't result in direct or indirect calls to AfxGetApp.
                // This extension DLL needs to add doc templates to the
                // app object, so it waits for the application to boot
                // and call an initialization function (see below).

                new CDynLinkLibrary(extensionDLL);
        }
        return 1;   // ok
}

// Data queries for sending DesignatorPDUs
static ExtDataQueryInteger         dqDisVersion(DATA_QUERY_DIS_VERSION);
static ExtDataQueryInteger         dqDisExercise(DATA_QUERY_EXERCISE_ID);
static ExtDataQueryAttachEntityId  dqEntityID;
static ExtDataQueryVrsgId                  VrsgID;

static CPtrList dataQueries;
static LaserPDU pdu;

void sendDesignatorPDU(float power);


const int maxRange = 6000;                                      // Max range of PLRF device: 6000 meters
static ExtLaserRangeData laserData;                     // Laserdata object
static Viewport viewPortData;                           // Viewportdata object
double heading, pitch;                                          // Global heading, pitch
double geoc_pos[3], llz_pos[3];                         // Global Location Values
int button = 4;                                                         // Button on device     0 = PLRF
                                                                                        //                      4 = Fire Button on SOFLAM
int joystick = 0;                                                       // Joystick number
int seconds = 60;                                                       // 60 ticks in one second (60FPS)
bool entityLased;
bool debug, btnWasPressed, dblClick, cycleData,
        sendStartPDU, sendEndPDU, firstClick;
int keyPressTimer, notPressedTimer, DCTimer,
        singleClickTimer, done, displayTimer;
int dataType;


// Math Defines
#define pi      ((double)3.14159265358979)
#define pio2    ((double)0.5*pi)
#define twopi   ((double)2.0*pi)
#define deg_to_rad      (twopi/(double)360.0)
#define rad_to_deg      ((double)360.0/twopi)
#define Mil_to_deg              (6400.0 / 360.0)

struct pointData
{
        double range;
        double lat;
        double lon;
        double alt;
        double inclination;
        double horizontalDistance;
        double verticalDistance;
        double azimuth;
        unsigned short site;
        unsigned short host;
        unsigned short entity;
};

pointData point1;
pointData point2;

// A simple vertex format for drawing primitives
struct HomoVertex
{
        // Homogeneous space
        float    x; // -1.0 (left edge) to 1.0 (right edge)
        float    y; // -1.0 (bottom edge) to 1.0 (top edge)
        float    z; // use zero here

                                // Color (0xAABBGGRR format)
        DWORD color;

        // Texture coords
        float    tu;
        float    tv;

};

// Texture coordinate table to convert characters to UV pairs
struct TCoordTable
{
        float llu;
        float llv;
        float uru;
        float urv;
} tcoordTable[256];

// makeFontTexture - uses the GDI to render a font to a bitmap.  the
// bitmap is turned into a texture.  tcoordTable contains the texture
// coordinates for each character in the font.
static ID3D11Texture2D *createFontTexture(ID3D11Device *pDevice)
{
        // Make a bitmap for the GDI to render to

        int hdrLen = sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255;
        BITMAPINFO *bmi = (BITMAPINFO *) new char[hdrLen];
        memset(bmi, 0, hdrLen);

        bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmi->bmiHeader.biWidth = 256;
        bmi->bmiHeader.biHeight = 256;
        bmi->bmiHeader.biPlanes = 1;
        bmi->bmiHeader.biCompression = BI_RGB;
        bmi->bmiHeader.biBitCount = 8;

        for (int i = 0; i < 256; i++)
        {
                bmi->bmiColors[i].rgbRed = i;
                bmi->bmiColors[i].rgbGreen = i;
                bmi->bmiColors[i].rgbBlue = i;
                bmi->bmiColors[i].rgbReserved = 0;
        }

        // Create a DC and a bitmap for the font

        HDC hDC = CreateCompatibleDC(NULL);
        DWORD *pBitmapBits;
        HBITMAP hbmBitmap = CreateDIBSection(hDC, bmi, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0);

        SetMapMode(hDC, MM_TEXT);

        // Create a font.  A 30 unit height should allow all printable chars to fit into a 256x256

        int nHeight = MulDiv(30, 96, GetDeviceCaps(hDC, LOGPIXELSY));

        HFONT hFont = CreateFont(nHeight, 0, 0, 0, FW_HEAVY, FALSE,
                FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
                CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
                VARIABLE_PITCH, "Lucida Console");

        SelectObject(hDC, hbmBitmap);
        SelectObject(hDC, hFont);
        SetTextColor(hDC, RGB(255, 255, 255));
        SetBkColor(hDC, RGB(0, 0, 0));
        SetTextAlign(hDC, TA_TOP | TA_LEFT);
        // Output all the chars and save the tcoords

        int x = 0;
        int y = 0;
        SIZE size;

        for (char c = 32; c < 127; c++)
        {
                // See if char will fit on current line or if we need to wrap
                GetTextExtentPoint32(hDC, &c, 1, &size);
                if (x + size.cx + 1 > 256)
                {
                        x = 0;
                        y += size.cy + 1;
                }

                // Output the char
                ExtTextOut(hDC, x, y, ETO_OPAQUE, NULL, &c, 1, NULL);

                // Save tcoords of this char
                tcoordTable[c - 32].llu = (float)x / 256.0f;
                tcoordTable[c - 32].llv = 1.0f - ((float)(y + size.cy) / 256.0f);
                tcoordTable[c - 32].uru = (float)(x + size.cx) / 256.0f;
                tcoordTable[c - 32].urv = 1.0f - ((float)y / 256.0f);

                x += size.cx + 1;
        }

        // Create an array of data to initialize the texture from.
        // Populate the texels of the texture with the image
        // the GDI rendered to.  Treat black pixels as transparent
        // and others as pure white.

        DWORD *pImageData = new DWORD[256 * 256];

        DWORD *p = pImageData;
        DWORD color;
        BYTE *pColor = (BYTE *)pBitmapBits;

        for (int y = 0; y < 256; y++)
        {
                for (int x = 0; x < 256; x++)
                {
                        if (*pColor++)
                                color = 0xffffffff;
                        else
                                color = 0x00ffffff;

                        *p++ = color;
                }
        }

        // Cleanup GDI stuff
        DeleteObject(hbmBitmap);
        DeleteDC(hDC);
        DeleteObject(hFont);
        delete[] bmi;

        D3D11_TEXTURE2D_DESC tdesc;
        memset(&tdesc, 0, sizeof(tdesc));

        tdesc.Width = 256;
        tdesc.Height = 256;
        tdesc.MipLevels = 1;
        tdesc.ArraySize = 1;
        tdesc.SampleDesc.Count = 1;
        tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        tdesc.Usage = D3D11_USAGE_DEFAULT;
        tdesc.CPUAccessFlags = 0;
        tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;

        D3D11_SUBRESOURCE_DATA initData;
        initData.pSysMem = pImageData;
        initData.SysMemPitch = 4 * 256;

        ID3D11Texture2D *pTexture;
        pDevice->CreateTexture2D(&tdesc, &initData, &pTexture);

        delete[] pImageData;
        return pTexture;
}

static bool copyToBuffer(const void *data, int elementSize, int count, int maxCount, int &index,
        ID3D11Buffer *pBuffer, ID3D11DeviceContext *pContext)
{
        D3D11_MAPPED_SUBRESOURCE mapData;
        D3D11_MAP mapType;

        if (index + count < maxCount)
        {
                // Append to active buffer
                mapType = D3D11_MAP_WRITE_NO_OVERWRITE;
        }
        else
        {
                // Buffer full, must start over
                mapType = D3D11_MAP_WRITE_DISCARD;
                index = 0;
        }

        if (pContext->Map(pBuffer, 0, mapType, 0, &mapData) != S_OK)
                return false;

        CopyMemory((BYTE*)mapData.pData + index*elementSize, data, count*elementSize);
        pContext->Unmap(pBuffer, 0);

        return true;
}

// Drawing non-indexed primitives
static void drawPrimitive(
        const HomoVertex *verts, int numVerts,
        D3D11_PRIMITIVE_TOPOLOGY topo,
        ID3D11DeviceContext *pContext)
{
        // Copy verts and indicies into their respective buffers
        copyToBuffer(verts, sizeof(HomoVertex), numVerts, VB_MAX, vertsInBuffer, pVB, pContext);

        // Now we can draw
        pContext->IASetPrimitiveTopology(topo);
        pContext->Draw(numVerts, vertsInBuffer);

        vertsInBuffer += numVerts;
}

// Drawing indexed primitives
static void drawPrimitive(
        const HomoVertex *verts, int numVerts,
        const WORD *indices, int numIndices,
        D3D11_PRIMITIVE_TOPOLOGY topo,
        ID3D11DeviceContext *pContext)
{
        // Copy verts and indicies into their respective buffers
        copyToBuffer(verts, sizeof(HomoVertex), numVerts, VB_MAX, vertsInBuffer, pVB, pContext);
        copyToBuffer(indices, sizeof(WORD), numIndices, IB_MAX, indicesInBuffer, pIB, pContext);

        // Now we can draw
        pContext->IASetPrimitiveTopology(topo);
        pContext->DrawIndexed(numIndices, indicesInBuffer, vertsInBuffer);

        // Update the buffer indices
        vertsInBuffer += numVerts;
        indicesInBuffer += numIndices;
}

// This function get the 4 texture coordinates needed to pull out a given
// character from the font texture.
static void getTextureCoords(char c,
        float &u0, float &v0, float &u1, float &v1,
        float &u2, float &v2, float &u3, float &v3)
{
        c -= 32;

        if (c < 0)
        {
                u0 = 0.0f;
                v0 = 0.0f;
                u1 = 0.0f;
                v1 = 0.0f;
                u2 = 0.0f;
                v2 = 0.0f;
                u3 = 0.0f;
                v3 = 0.0f;
        }
        else
        {
                u0 = tcoordTable[c].llu;
                v0 = tcoordTable[c].llv;
                u1 = tcoordTable[c].uru;
                v1 = tcoordTable[c].llv;
                u2 = tcoordTable[c].uru;
                v2 = tcoordTable[c].urv;
                u3 = tcoordTable[c].llu;
                v3 = tcoordTable[c].urv;
        }
}

// This function draws a string of text characters as a triangle list of textured quads.
// It uses getTextureCoords to get the texture coords from the font texture for each
// quad.  

static void drawText(const char *msg, float x, float y, float thetaRadians, float width, float height, DWORD color,
        ID3D11DeviceContext *pContext)
{
        // Bind the font texture
        pContext->PSSetShaderResources(0, 1, &pFontTextureSRV);

        static HomoVertex p[80];      // Draw up to 20 chars (80/4) in a single API call
        static WORD indicies[120];  // Need 6 indices for each of the 20 chars (two quads)

        int len = (int)strlen(msg);
        int t = 0;
        int v = 0;

        float dx = width*cosf(thetaRadians);
        float dy = -width*sinf(thetaRadians);

        float hdx = -height*0.5f*sinf(thetaRadians);
        float hdy = -height*0.5f*cosf(thetaRadians);

        // For each character, make a quad
        for (int i = 0; i < len; i++)
        {
                // Get tcoords of current char
                getTextureCoords(msg[i],
                        p[v + 0].tu, p[v + 0].tv,
                        p[v + 1].tu, p[v + 1].tv,
                        p[v + 2].tu, p[v + 2].tv,
                        p[v + 3].tu, p[v + 3].tv);

                // Lower left
                p[v + 0].x = x + hdx + i*dx;
                p[v + 0].y = y + hdy + i*dy;
                p[v + 0].z = 0.0f;
                p[v + 0].color = color;

                // Lower right
                p[v + 1].x = x + hdx + (i + 1.0f)*dx;
                p[v + 1].y = y + hdy + (i + 1.0f)*dy;
                p[v + 1].z = 0.0f;
                p[v + 1].color = color;

                // Upper right
                p[v + 2].x = x - hdx + (i + 1.0f)*dx;
                p[v + 2].y = y - hdy + (i + 1.0f)*dy;
                p[v + 2].z = 0.0f;
                p[v + 2].color = color;

                // Upper left
                p[v + 3].x = x - hdx + i*dx;
                p[v + 3].y = y - hdy + i*dy;
                p[v + 3].z = 0.0f;;
                p[v + 3].color = color;

                // Make the indicies.  Note indices are in counter-clockwise order
                indicies[t++] = v + 0;
                indicies[t++] = v + 1;
                indicies[t++] = v + 2;
                indicies[t++] = v + 0;
                indicies[t++] = v + 2;
                indicies[t++] = v + 3;
                v += 4;

                // See if we need to flush
                if (v == ARRAYSIZE(p))
                {
                        drawPrimitive(p, v, indicies, t, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, pContext);
                        v = 0;
                        t = 0;
                }
        }

        // Draw anything remaining
        if (v)
        {
                drawPrimitive(p, v, indicies, t, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, pContext);
        }
}

static void createDeviceObjects(ID3D11DeviceContext *pContext)
{
        // Create all the objects we need under the new D3D Device

        // Need a handle to the device
        ID3D11Device *pDevice = NULL;
        pContext->GetDevice(&pDevice);

        // Create the vertex layout
        D3D11_INPUT_ELEMENT_DESC layout[] =
        {
                { "POSITION",  0, DXGI_FORMAT_R32G32B32_FLOAT,    0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
                { "COLOR",     0, DXGI_FORMAT_R8G8B8A8_UNORM,     0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
                { "TEXCOORD",  0, DXGI_FORMAT_R32G32_FLOAT,       0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        };

        pDevice->CreateInputLayout(layout, ARRAYSIZE(layout), g_VertexShader, sizeof(g_VertexShader), &pLayout);

        // Create the shaders
        pDevice->CreateVertexShader(g_VertexShader, sizeof(g_VertexShader), NULL, &pVertexShader);
        pDevice->CreatePixelShader(g_PixelShader, sizeof(g_PixelShader), NULL, &pPixelShader);

        // Create the font texture
        pFontTexture = createFontTexture(pDevice);

        // Create the shader resource view for the font texture
        pDevice->CreateShaderResourceView(pFontTexture, NULL, &pFontTextureSRV);

        // Create a sampler state
        D3D11_SAMPLER_DESC sampDesc;
        ZeroMemory(&sampDesc, sizeof(sampDesc));

        sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
        sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
        sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
        sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
        sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
        sampDesc.MinLOD = 0;
        sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
        pDevice->CreateSamplerState(&sampDesc, &pSampler);

        // Create the vertex buffer
        D3D11_BUFFER_DESC bd;
        ZeroMemory(&bd, sizeof(bd));

        bd.ByteWidth = sizeof(HomoVertex) * VB_MAX;
        bd.Usage = D3D11_USAGE_DYNAMIC;
        bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
        bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

        pDevice->CreateBuffer(&bd, NULL, &pVB);

        // Create an index buffer
        bd.ByteWidth = sizeof(WORD) * IB_MAX;
        bd.Usage = D3D11_USAGE_DYNAMIC;
        bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
        bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

        pDevice->CreateBuffer(&bd, NULL, &pIB);

        // Initialize indexes into buffers
        vertsInBuffer = 0;
        indicesInBuffer = 0;

        // Create a plain white texture for things we dont want textured
        D3D11_TEXTURE2D_DESC tdesc;
        memset(&tdesc, 0, sizeof(tdesc));

        tdesc.Width = 1;
        tdesc.Height = 1;
        tdesc.MipLevels = 1;
        tdesc.ArraySize = 1;
        tdesc.SampleDesc.Count = 1;
        tdesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        tdesc.Usage = D3D11_USAGE_DEFAULT;
        tdesc.CPUAccessFlags = 0;
        tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;

        D3D11_SUBRESOURCE_DATA initData;
        DWORD white = 0xffffffff;
        initData.pSysMem = &white;
        initData.SysMemPitch = 4 * 256;

        pDevice->CreateTexture2D(&tdesc, &initData, &pWhiteTexture);
        pDevice->CreateShaderResourceView(pWhiteTexture, NULL, &pWhiteTextureSRV);
}

struct Viewport;

__declspec(dllexport) void __cdecl extPostViewportUserDraw(ID3D11DeviceContext *pContext, int vpId, Viewport *vp)
{
        // First time in or after device reset, create our resources
        if (pFontTexture == NULL)
                createDeviceObjects(pContext);

        // Remove the depth buffer
        ID3D11RenderTargetView *pBackBufferView;
        ID3D11DepthStencilView *pDepthStencilView = NULL;
        pContext->OMGetRenderTargets(1, &pBackBufferView, &pDepthStencilView);
        pContext->OMSetRenderTargets(1, &pBackBufferView, NULL);
        SAFE_RELEASE(pDepthStencilView);

        // Setup some required render states
        UINT stride = sizeof(HomoVertex);
        UINT offset = 0;
        pContext->IASetVertexBuffers(0, 1, &pVB, &stride, &offset);
        pContext->IASetIndexBuffer(pIB, DXGI_FORMAT_R16_UINT, 0);
        pContext->IASetInputLayout(pLayout);
        pContext->VSSetShader(pVertexShader, NULL, 0);
        pContext->PSSetShader(pPixelShader, NULL, 0);
        pContext->PSSetSamplers(0, 1, &pSampler);

        // You are drawing in 3D.  There is an coordinate system aligned with the ownship.
        // It is using the DIS/CIGI convention of X forward, Y right, Z down.  Imagine
        // the canvans 'renderPlaneDist' meters in front of the airplane.  The Y and Z axes
        // position the objects horizontally and vertically on this canvas.  

        // Bind the white texture, since we dont want texture on lines.  Color can be
        // given per-vertex on non-textured primitives, using the DWORD color member of
        // HomoVertex.  Colors are encoded in AAGGBBRR format.  Note that drawing text
        // binds the font texture, so you need to call this again after drawing text.
        pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

        // Draw crosshairs.  Since this a list of independant lines, no verts are
        // repeated, and we can use the simpler non-indexed form of drawPrimtive().
        // For drawing a strip of connected lines, you would instead use
        // D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP.

        // x,y,z(always 0),color,(tu,tv) textured cords
        HomoVertex verts[] = {

                // First Segment on Vertical (From Center) (2 Verts) Black
                -.025f,   .18f, 0.0f,  0xff000000, 0.0f, 0.0f,
                .025f,   .18f, 0.0f,  0xff000000, 0.0f, 0.0f,
                // Second Segment on Vertical (2 Verts)
                -.025f,   .36f, 0.0f,  0xff000000, 0.0f, 0.0f,
                .025f,   .36f, 0.0f,  0xff000000, 0.0f, 0.0f,
                // Third Segment on Vertical (2 Verts)
                -.025f,   .54f, 0.0f,  0xff000000, 0.0f, 0.0f,
                .025f,   .54f, 0.0f,  0xff000000, 0.0f, 0.0f,
                // Fourth Segment on Vertical (2 Verts)
                -.025f,   .72f, 0.0f,  0xff000000, 0.0f, 0.0f,
                .025f,   .72f, 0.0f,  0xff000000, 0.0f, 0.0f,
                // Fifth Segment on Vertical (2 Verts)
                -.025f,   .90f, 0.0f,  0xff000000, 0.0f, 0.0f,
                .025f,   .90f, 0.0f,  0xff000000, 0.0f, 0.0f,


                // First Segment on Left (From Center) (2 Verts) Black
                -.18f,   0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                -.18f,  -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                // Second Segment on left (2 Verts)
                -.36f,   0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                -.36f,  -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                // Third Segment on left (2 Verts)
                -.54f,   0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                -.54f,  -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                // Forth Segment on left (2 Verts)
                -.72f,   0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                -.72f,  -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                // Fifth Segment on left (2 Verts)
                -.90f,   0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                -.90f,  -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,


                // First Segment on Right (From Center) (2 Verts) Black
                .18f,   0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                .18f,  -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                // Second Segment on Right (2 Verts)
                .36f,   0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                .36f,  -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                // Third Segment on Right (2 Verts)
                .54f,   0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                .54f,  -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                // Forth Segment on Right (2 Verts)
                .72f,   0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                .72f,  -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                // Fifth Segment on Right (2 Verts)
                .90f,   0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                .90f,  -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,


                // Center Crosshair (4 Verts) Black
                // Horizontal Line
                -0.025f,  0.0f, 0.0f, 0xff000000, 0.0f, 0.0f,
                0.025f,  0.0f, 0.0f, 0xff000000, 0.0f, 0.0f,
                // Vertical Line
                0.0f, -0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
                0.0f,  0.025f, 0.0f, 0xff000000, 0.0f, 0.0f,
        };

        // Draw Crosshairs
        drawPrimitive(verts, 34, D3D11_PRIMITIVE_TOPOLOGY_LINELIST, pContext);


        // Draw text on Screen then Reset to Null Texture after each Text draw
        // Draw text on left side
        // Draw 30-50 degree markings
        drawText("30", -.57f, -0.075f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
        pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
        drawText("50", -.93f, -0.075f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
        pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);


        // Draw text on right side
        drawText("30", .51f, -0.075f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
        pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
        drawText("50", .87f, -0.075f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
        pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);


        // Draw text on vertical side
        drawText("30", -.1f, 0.54f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
        pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
        drawText("50", -.1f, 0.9f, 0.0f, 0.025f, 0.035f, 0xff000000, pContext); // Black
        pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

        // **************************************************************************************************

        // Draw a circle.  There are many shared verts, so we do this as an indexed
        // triangle list for efficiency.

        for (int j = 1; j < 6; j++) // Draw Circles on left side
        {
                double offset = .09;
                double answer = ((.18 * j) - offset);
                const int numVerts = 20;
                double centerX = -(answer);
                double centerY = 0.0f;
                const float radius = 0.005f;
                const float PI = 3.14159265f;

                HomoVertex circVerts[numVerts + 1];  // add an extra vert for the center
                WORD indicies[numVerts * 3];       // need 3 indices per triangle

                                                                                   // verts around the circumference
                for (int i = 0; i < numVerts; i++)
                {
                        float theta = (2.0f * PI) * (float)i / (float)numVerts;

                        circVerts[i].x = centerX + radius*cosf(theta);
                        circVerts[i].y = centerY + radius*sinf(theta);
                        circVerts[i].z = 0.0f;
                        circVerts[i].color = 0xff000000; // black
                        circVerts[i].tu = 0.0f;
                        circVerts[i].tv = 0.0;
                }

                // and one at the center
                circVerts[numVerts].x = centerX;
                circVerts[numVerts].y = centerY;
                circVerts[numVerts].z = 0.0f;
                circVerts[numVerts].color = 0xff000000; // black
                circVerts[numVerts].tu = 0.0f;
                circVerts[numVerts].tv = 0.0;

                // make the triangle indices
                for (int i = 0; i < numVerts; i++)
                {
                        indicies[i * 3 + 0] = numVerts; // the center
                        indicies[i * 3 + 1] = i;
                        indicies[i * 3 + 2] = (i + 1) % numVerts;
                }

                // Now we can draw it
                drawPrimitive(circVerts, numVerts + 1, indicies, numVerts * 3, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, pContext);
        }

        // ********************************************************************************************************************** //
        for (int j = 1; j < 6; j++) // Draw Circles on Right side
        {
                float offset = .09;
                float answer = ((.18 * j) - offset);
                const int numVerts = 20;
                float centerX = (answer);
                float centerY = 0.0f;
                const float radius = 0.005f;
                const float PI = 3.14159265f;

                HomoVertex circVerts[numVerts + 1];  // add an extra vert for the center
                WORD indicies[numVerts * 3];       // need 3 indices per triangle

                                                                                   // verts around the circumference
                for (int i = 0; i < numVerts; i++)
                {
                        float theta = (2.0f * PI) * (float)i / (float)numVerts;

                        circVerts[i].x = centerX + radius*cosf(theta);
                        circVerts[i].y = centerY + radius*sinf(theta);
                        circVerts[i].z = 0.0f;
                        circVerts[i].color = 0xff000000; // black
                        circVerts[i].tu = 0.0f;
                        circVerts[i].tv = 0.0;
                }

                // and one at the center
                circVerts[numVerts].x = centerX;
                circVerts[numVerts].y = centerY;
                circVerts[numVerts].z = 0.0f;
                circVerts[numVerts].color = 0xff000000; // black
                circVerts[numVerts].tu = 0.0f;
                circVerts[numVerts].tv = 0.0;

                // make the triangle indices
                for (int i = 0; i < numVerts; i++)
                {
                        indicies[i * 3 + 0] = numVerts; // the center
                        indicies[i * 3 + 1] = i;
                        indicies[i * 3 + 2] = (i + 1) % numVerts;
                }

                // Now we can draw it
                drawPrimitive(circVerts, numVerts + 1, indicies, numVerts * 3, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, pContext);
        }


        // ********************************************************************************************************************** //
        for (int j = 1; j < 6; j++) // Draw Circles on Vertical side
        {
                float offset = .09;
                float answer = ((.18 * j) - offset);
                const int numVerts = 20;
                float centerX = 0.0f;
                float centerY = answer;
                const float radius = 0.005f;
                const float PI = 3.14159265f;

                HomoVertex circVerts[numVerts + 1];  // add an extra vert for the center
                WORD indicies[numVerts * 3];       // need 3 indices per triangle

                                                                                   // verts around the circumference
                for (int i = 0; i < numVerts; i++)
                {
                        float theta = (2.0f * PI) * (float)i / (float)numVerts;

                        circVerts[i].x = centerX + radius*cosf(theta);
                        circVerts[i].y = centerY + radius*sinf(theta);
                        circVerts[i].z = 0.0f;
                        circVerts[i].color = 0xff000000; // black
                        circVerts[i].tu = 0.0f;
                        circVerts[i].tv = 0.0;
                }

                // and one at the center
                circVerts[numVerts].x = centerX;
                circVerts[numVerts].y = centerY;
                circVerts[numVerts].z = 0.0f;
                circVerts[numVerts].color = 0xff000000; // black
                circVerts[numVerts].tu = 0.0f;
                circVerts[numVerts].tv = 0.0;

                // make the triangle indices
                for (int i = 0; i < numVerts; i++)
                {
                        indicies[i * 3 + 0] = numVerts; // the center
                        indicies[i * 3 + 1] = i;
                        indicies[i * 3 + 2] = (i + 1) % numVerts;
                }
                // Now we can draw it
                drawPrimitive(circVerts, numVerts + 1, indicies, numVerts * 3, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, pContext);
        }



        // Lat in geocentric
        geoc_pos[0] = viewPortData.posGcc[0];
        // Lon in geocentric
        geoc_pos[1] = viewPortData.posGcc[1];
        // Height in geocentric
        geoc_pos[2] = viewPortData.posGcc[2];

        // Convert geocentric postion to lat/lon/height
        coord_gcc_to_llz(geoc_pos[0], geoc_pos[1], geoc_pos[2], DATUM_WGS84, &llz_pos[0], &llz_pos[1], &llz_pos[2]);


        // Calculate Magnetic variance from lat/lon
        double MagVar = MetaVR::getMagVar(llz_pos[0], llz_pos[1]);

        // Add Variance to True Heading to get Magnetic Heading. East is negative
        double MagHeading = heading - MagVar;

        if (MagHeading > 360.0) // Degree Correction for Magnetic Heading being greater than 360
        {
                MagHeading = round(MagHeading - 360); // Round Magnetic Heading
        }
        if (MagHeading < 0.0) // Degree Correction for Magnetic Heading being less than 0
        {
                MagHeading = round(MagHeading + 360); // Round Magnetic Heading
        }



        // ********************************************************************************************************************** //
        // Create Joystick Code Here

        char headingText[15];

        //// Height
        //height = sin(point1.inclination) * point1.range;

        //// Horizontal Distance
        //hDist = tan(point1.inclination) * height;
        //drawText("AZI", -.18f, -0.2f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "AZ"
        //pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

        //sprintf_s(headingText, "%3.0f", MagHeading);
        //drawText(headingText, 0.0f, -0.2, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red magnetic heading
        //pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
        //drawText("o", 0.13f, -0.17f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "o"
        //pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
        //
        //drawText("D", -.18f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "D"
        //pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
        //
        //char rangeText[6];
        //sprintf_s(rangeText, "%4.0f", point1.range);
        //drawText(rangeText, 0.0f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red range distance
        //pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
        //drawText("m", 0.18f, -0.08f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "m"
        //pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);


        // Holding Button
        if (sf::Joystick::isButtonPressed(joystick, button) && firstClick == true)
        {
                // Single Click
                drawText("AZI", -.18f, -0.2f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "AZ"
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                sprintf_s(headingText, "%3.0f", MagHeading);
                drawText(headingText, 0.0f, -0.2, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red magnetic heading
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                drawText("o", 0.13f, -0.17f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "o"
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                btnWasPressed = true;
                done = false;   // Get new data on button release
                notPressedTimer = 0;
                displayTimer = 0;
                sendStartPDU = false;
                sendEndPDU = false;
        }

        // Release of Button
        if (!(sf::Joystick::isButtonPressed(joystick, button)) && btnWasPressed == true)
        {
                if (displayTimer < (3 * seconds))
                {
                        //if (cycleData == true)
                        //{
                        //      if (dataType == 1) // Distance
                        //      {
                        //              drawText("D", -.18f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "D"
                        //              pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                        //              char rangeText[6];
                        //              sprintf_s(rangeText, "%4.0f", point1.range);
                        //              drawText(rangeText, 0.0f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red range distance
                        //              pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                        //              drawText("m", 0.18f, -0.08f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "m"
                        //              pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                        //      }
                        //      else if (dataType == 2) // Horizontal Distance
                        //      {
                        //              drawText("H", -.18f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "D"
                        //              pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                        //              char rangeText[6];
                        //              sprintf_s(rangeText, "%4.0f", point1.horizontalDistance);
                        //              drawText(rangeText, 0.0f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red range distance
                        //              pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                        //              drawText("m", 0.18f, -0.08f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "m"
                        //              pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                        //      }
                        //      else if (dataType == 3) // Vertical Height Distance
                        //      {
                        //              drawText("V", -.18f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "D"
                        //              pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                        //              char rangeText[6];
                        //              sprintf_s(rangeText, "%4.0f", point1.verticalDistance);
                        //              drawText(rangeText, 0.0f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red range distance
                        //              pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                        //              drawText("m", 0.18f, -0.08f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "m"
                        //              pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                        //      }
                        //      else if (dataType == 4) // Azimuth (Heading)
                        //      {
                        //              drawText("AZI", -.18f, -0.2f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "AZ"
                        //              pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                        //              sprintf_s(headingText, "%3.0f", MagHeading);
                        //              drawText(headingText, 0.0f, -0.2, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red magnetic heading
                        //              pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                        //              drawText("o", 0.13f, -0.17f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "o"
                        //              pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                        //      }
                        //      else if (dataType == 5) // inclination
                        //      {
                        //              drawText("INC", -.18f, -0.2f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "AZ"
                        //              pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                        //              sprintf_s(headingText, "%3.0f", point1.inclination);
                        //              drawText(headingText, 0.0f, -0.2, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red magnetic heading
                        //              pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                        //              drawText("o", 0.13f, -0.17f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "o"
                        //              pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                        //      }
                        //}
                        //else
                        //{
                        drawText("D", -.18f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red "D"
                        pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                        if (done == false)
                        {
                                // Range
                                point1.range = laserData.range;
                                // Alt
                                point1.alt = laserData.alt;
                                // Lat
                                point1.lat = laserData.lat;
                                // Lon
                                point1.lon = laserData.lon;

                                // Entity Lased
                                if (laserData.bEntityIdValid == true)
                                {
                                        point1.site = laserData.site;
                                        point1.host = laserData.host;
                                        point1.entity = laserData.entity;
                                        entityLased = true;
                                }
                                else
                                {
                                        point1.site = 0;
                                        point1.host = 0;
                                        point1.entity = 0;
                                        entityLased = false;
                                }


                                // Inclination
                                point1.inclination = pitch;

                                // Vertical Distance
                                point1.verticalDistance = sin(point1.inclination) * point1.range;

                                // Horizontal Distance
                                point1.horizontalDistance = tan(point1.inclination) * point1.verticalDistance;

                                // Azimuth
                                point1.azimuth = MagHeading;

                                done = true;
                        }

                        if ((point1.range <= maxRange) && (point1.range != 0)) // Display Range if laser range is below maxRange
                        {
                                if (sendStartPDU == false)
                                {
                                        sendDesignatorPDU(10.0f);
                                        sendStartPDU = true;
                                }

                                char rangeText[6];
                                sprintf_s(rangeText, "%4.0f", point1.range);
                                drawText(rangeText, 0.0f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Red range distance
                                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                                drawText("m", 0.18f, -0.08f, 0.0f, 0.03f, 0.04f, 0xff0000ff, pContext); // Red "m"
                                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                        }
                        else // Draw ---- to indicate range > maxrange
                        {
                                drawText("----", 0.0f, -0.1f, 0.0f, 0.04f, 0.06f, 0xff0000ff, pContext); // Red "----"
                                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                        }
                }

                if (displayTimer > (.1 * seconds))
                {
                        if (sendEndPDU == false)
                        {
                                sendDesignatorPDU(0.0f);
                                sendEndPDU = true;
                        }
                }

                firstClick = false;
                displayTimer += 1;
        }


        // Cycle Data
        if (sf::Joystick::isButtonPressed(joystick, button) && btnWasPressed == true && dblClick == true)
        {
                dataType++;
                cycleData = true;
                if (dataType == 6) // start over
                {
                        dataType = 1;
                }
               
        }


        // Button not being pressed
        if (!(sf::Joystick::isButtonPressed(joystick, button)))
        {
                notPressedTimer += 1;
                if (notPressedTimer < (1 * seconds))
                {
                        dblClick == true;
                }
                else
                {
                        dblClick == false;
                }
               
                // No Click
                if (notPressedTimer > (3 * seconds)) // reset all timers and states after 3 seconds since last button press
                {
                        dataType = 1;
                        firstClick = true;
                        done = false;
                        dblClick = false;
                        btnWasPressed = false;
                        displayTimer = 0;
                        sendStartPDU = false;
                        sendEndPDU = false;
                }
        }

       
















        // ********************************************************************************************************************** //
        // Debug Screen if "D" on keyboard is pressed
        char debugText[15];
        if ((sf::Keyboard::isKeyPressed(sf::Keyboard::F6)) && debug == false)
        {
                keyPressTimer += 1;

                if (keyPressTimer > (.3 * seconds))
                {
                        debug = true;
                        keyPressTimer = 0;
                }
        }

        if ((sf::Keyboard::isKeyPressed(sf::Keyboard::F6)) && debug == true)
        {
                keyPressTimer += 1;

                if (keyPressTimer > (.3 * seconds))
                {
                        debug = false;
                        keyPressTimer = 0;
                }
        }

        if (!(sf::Keyboard::isKeyPressed(sf::Keyboard::F6)))
        {
                keyPressTimer = 0;
        }

        if (debug == true)
        {
                if (sf::Joystick::isConnected(joystick))
                {
                        drawText("Is Connected", .03f, 0.45f, 0.0f, 0.04f, 0.06f, 0xff0000ff, pContext); // Connected
                        pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                }
                else
                {
                        drawText("Is not Connected", .05f, 0.5f, 0.0f, 0.04f, 0.06f, 0xff0000ff, pContext); // Not Connected
                        pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                }
                drawText("Heading", -.4f, -0.1f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Heading
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                sprintf_s(debugText, "%3.3f", heading);
                drawText(debugText, 0.0f, -0.1, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                drawText("MagVar", -.4f, -0.2f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Magnetic Variation
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                sprintf_s(debugText, "%3.3f", MagVar);
                drawText(debugText, 0.0f, -0.2, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                drawText("MagHeading", -.5f, -0.3f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Magnetic Heading
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                sprintf_s(debugText, "%3.3f", MagHeading);
                drawText(debugText, 0.0f, -0.3, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                drawText("LAT", -.18f, -0.4f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Latitude
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                sprintf_s(debugText, "%3.3f", llz_pos[0]);
                drawText(debugText, 0.0f, -0.4, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                drawText("LON", -.18f, -0.5f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Longitude
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                sprintf_s(debugText, "%3.3f", llz_pos[1]);
                drawText(debugText, 0.0f, -0.5, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                drawText("ALT", -.18f, -0.6f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Altitude
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                sprintf_s(debugText, "%3.3f", llz_pos[2]);
                drawText(debugText, 0.0f, -0.6, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                drawText("Geo X", -.28f, -0.7f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Geocentric X position
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                sprintf_s(debugText, "%3.3f", geoc_pos[0]);
                drawText(debugText, 0.0f, -0.7, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                drawText("Geo Y", -.28f, -0.8f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Geocentric Y position
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                sprintf_s(debugText, "%3.3f", geoc_pos[1]);
                drawText(debugText, 0.0f, -0.8, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);

                drawText("Geo Z", -.28f, -0.9f, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext); // Geocentric Z position
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
                sprintf_s(debugText, "%3.3f", geoc_pos[2]);
                drawText(debugText, 0.0f, -0.9, 0.0f, 0.045f, 0.065f, 0xff0000ff, pContext);
                pContext->PSSetShaderResources(0, 1, &pWhiteTextureSRV);
        }

        // ********************************************************************************************************************** //
}

__declspec(dllexport) void __cdecl extResetDevice()
{
        // Device has been reset.  Release the objects we created under the device.
        // We will recreate them on the next call to extPostViewportUserDraw

        SAFE_RELEASE(pWhiteTexture);
        SAFE_RELEASE(pWhiteTextureSRV);
        SAFE_RELEASE(pFontTexture);
        SAFE_RELEASE(pFontTextureSRV);
        SAFE_RELEASE(pSampler);
        SAFE_RELEASE(pVertexShader);
        SAFE_RELEASE(pPixelShader);
        SAFE_RELEASE(pLayout);
        SAFE_RELEASE(pVB);
        SAFE_RELEASE(pIB);
}

__declspec(dllexport) void __cdecl extLaserRange(const ExtLaserRangeData *data)
{
        laserData = *data; // copy ExtLaserRangeData *data to laserData object
}

__declspec(dllexport) BOOL __cdecl extInitialize(CWinApp *theApp)
{
        // Enque some data queries to get some info we need to generate DIS PDUs.
        // Done here in extInitialize, assuming they wont change on the fly and we only need to this once.

        dataQueries.AddTail(&dqDisVersion);
        dataQueries.AddTail(&dqDisExercise);

        return TRUE;
}

__declspec(dllexport) void __cdecl extPreViewportUserDraw(ID3D11DeviceContext *pContext, int vpId, Viewport *vp)
{
        // Heading Code (True Heading)
        memcpy(&viewPortData, vp, sizeof(Viewport));

        Matrix gccToView;
        memcpy(gccToView.m, vp->gccToView, sizeof(vp->gccToView));

        Matrix nedToGcc;
        nedToGcc.makeNEDToGeo(vp->posGcc[0], vp->posGcc[1], vp->posGcc[2]);

        Matrix nedToView = gccToView * nedToGcc;

        double yaw, pitch, roll;
        nedToView.getAngles(yaw, pitch, roll);

        // Yaw euler angle is angle in radians. Convert from radians to degrees
        heading = yaw * rad_to_deg;

        // Degree Correction for (-180 - 0) range
        if (heading < 0.0)
        {
                heading = heading + 360.0;
        }
        // End of heading code
}

_declspec(dllexport) void __cdecl extTick()
{
        sf::Joystick::update();

        static ExtDataQueryAttachEntityId dqEID;
        dataQueries.AddTail(&dqEID);
        dqEntityID.site = dqEID.site;
        dqEntityID.host = dqEID.host;
        dqEntityID.entity = dqEID.entity;
}

__declspec(dllexport) ExtDataQuery* __cdecl extDataQuery(void)
{
        // Submit any pending queries to VRSG via return value.  VRSG will
        // call this in a loop until NULL is returned.

        if (dataQueries.GetCount())
                return (ExtDataQuery*)dataQueries.RemoveHead();

        // None left to submit this frame.
        return NULL;
}

void sendDesignatorPDU(float power)
{
        memset(&pdu, 0, sizeof(pdu));

        // Initialize header

        pdu.header.family = 6;
        pdu.header.kind = LaserPDUKind;
        pdu.header.version = (BYTE)dqDisVersion.result;
        pdu.header.exercise = (BYTE)dqDisExercise.result;
        pdu.header.length = sizeof(pdu);

        swapEndian(pdu.header.length);

        // Who its from (Pull from VRSG)
        pdu.entityID.simulator.site = dqEntityID.site;
        pdu.entityID.simulator.host = dqEntityID.host;
        pdu.entityID.entity = dqEntityID.entity;

        pdu.drAlgo = 2;

        swapEndian(pdu.entityID.simulator.site);
        swapEndian(pdu.entityID.simulator.host);
        swapEndian(pdu.entityID.entity);

        // Laser params

        pdu.codeName = 3;
        swapEndian(pdu.codeName);
       
        pdu.laserCode = 1118;
        swapEndian(pdu.laserCode);

        pdu.power = power;
        swapEndian(pdu.power);

        pdu.waveLength = 0.9f;
        swapEndian(pdu.waveLength);

        // Point lased
       
        // If lased point is an entity, put entity info in pdu
        if (entityLased == true)
        {
                pdu.lasedEntityID.simulator.site = point1.site;
                pdu.lasedEntityID.simulator.host = point1.host;
                pdu.lasedEntityID.entity = point1.entity;
        }

        swapEndian(pdu.lasedEntityID.simulator.site);
        swapEndian(pdu.lasedEntityID.simulator.host);
        swapEndian(pdu.lasedEntityID.entity = point1.entity);

        coord_llz_to_gcc(DATUM_WGS84,
                point1.lat,
                point1.lon,
                point1.alt,
                &pdu.spot.x, &pdu.spot.y, &pdu.spot.z);

        swapEndian(pdu.spot.x);
        swapEndian(pdu.spot.y);
        swapEndian(pdu.spot.z);

        pdu.acceleration.x = 0;
        pdu.acceleration.y = 0;
        pdu.acceleration.z = 0;

        swapEndian(pdu.acceleration.x);
        swapEndian(pdu.acceleration.y);
        swapEndian(pdu.acceleration.z);

        static ExtDataQuerySendDisPdu dqSendPdu(sizeof(pdu), &pdu);
        dataQueries.AddTail(&dqSendPdu);
}

Pages: [1]