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

Author Topic: Double Click without events - Help!  (Read 1557 times)

0 Members and 1 Guest are viewing this topic.

Eggman1414

  • Newbie
  • *
  • Posts: 1
    • View Profile
    • Email
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);
}

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Double Click without events - Help!
« Reply #1 on: March 01, 2017, 08:52:07 am »
So where are you stuck?

You'll have to track the button state (pressed/released) on your own. From there you can add a clock to track time between presses and if it's below a certain threshold, you consider it as a double click.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

 

anything