#include "XPLMDisplay.h"
#include "XPLMGraphics.h"
#include "XPLMProcessing.h"
#include "XPLMDataAccess.h"
#include "XPLMMenus.h"
#include "XPLMUtilities.h"
#include "XPWidgets.h"
#include "XPStandardWidgets.h"
#include "XPLMCamera.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#if IBM
#include <windows.h>
#endif
#define MAX_ITEMS 11
static XPLMDataRef gPositionDataRef[MAX_ITEMS];
static char DataRefString[MAX_ITEMS][255] = { "sim/flightmodel/position/local_x", "sim/flightmodel/position/local_y", "sim/flightmodel/position/local_z",
"sim/flightmodel/position/lat_ref", "sim/flightmodel/position/lon_ref", "sim/flightmodel/position/theta",
"sim/flightmodel/position/phi", "sim/flightmodel/position/psi",
"sim/flightmodel/position/latitude", "sim/flightmodel/position/longitude", "sim/flightmodel/position/elevation"};
static char DataRefDesc[MAX_ITEMS][255] = {"Local x", "Local y", "Local z", "Lat Ref", "Lon Ref", "Theta", "Phi", "Psi"};
static char Description[3][255] = {"Latitude", "Longitude", "Elevation"};
static int Element = 0, IntVals[128];
static float FloatVals[128];
static int ByteVals[128];
static int MenuItem1;
static XPWidgetID PositionWidget = NULL, PositionWindow = NULL;
static XPWidgetID PositionApplyButton = NULL;
static XPWidgetID PositionText[MAX_ITEMS] = {NULL};
static XPWidgetID PositionEdit[MAX_ITEMS] = {NULL};
static XPWidgetID UpArrow[MAX_ITEMS] = {NULL};
static XPWidgetID DownArrow[MAX_ITEMS] = {NULL};
static XPWidgetID LatLonAltApplyButton = NULL, LatLonRefApplyButton = NULL, ReloadSceneryButton = NULL;
static XPWidgetID Position2Text[3] = {NULL};
static XPWidgetID Position2Edit[3] = {NULL};
static void PositionMenuHandler(void *, void *);
static void CreatePosition(int x1, int y1, int w, int h);
static int PositionHandler(
XPWidgetMessage inMessage,
XPWidgetID inWidget,
intptr_t inParam1,
intptr_t inParam2);
static void DisplayFindDataRef(void);
static void ApplyValues(void);
static void ApplyLatLonRefValues(void);
static void ApplyLatLonAltValues(void);
inline float HACKFLOAT(float val)
{
return val;
}
/*
#if IBM
inline float HACKFLOAT(float val)
{
return val;
}
#else
inline long long HACKFLOAT(float val)
{
double d = val;
long long temp;
temp = *((long long *) &d);
return temp;
}
#endif
*/
PLUGIN_API int XPluginStart(
char * outName,
char * outSig,
char * outDesc)
{
XPLMMenuID id;
int item;
strcpy(outName, "Position");
strcpy(outSig, "xpsdk.examples.position");
strcpy(outDesc, "A plug-in that allows positioning of lat/lon etc.");
item = XPLMAppendMenuItem(XPLMFindPluginsMenu(), "Position", NULL, 1);
id = XPLMCreateMenu("Position", XPLMFindPluginsMenu(), item, PositionMenuHandler, NULL);
XPLMAppendMenuItem(id, "Position", (void *)"Position", 1);
MenuItem1 = 0;
for (int Item=0; Item<MAX_ITEMS; Item++)
gPositionDataRef[Item] = XPLMFindDataRef(DataRefString[Item]);
return 1;
}
PLUGIN_API void XPluginStop(void)
{
if (MenuItem1 == 1)
{
XPDestroyWidget(PositionWidget, 1);
MenuItem1 = 0;
}
}
PLUGIN_API void XPluginDisable(void)
{
}
PLUGIN_API int XPluginEnable(void)
{
return 1;
}
PLUGIN_API void XPluginReceiveMessage(XPLMPluginID inFrom, int inMsg, void * inParam)
{
}
void PositionMenuHandler(void * mRef, void * iRef)
{
if (!strcmp((char *) iRef, "Position"))
{
if (MenuItem1 == 0)
{
CreatePosition(300, 600, 300, 550);
MenuItem1 = 1;
}
else
if(!XPIsWidgetVisible(PositionWidget))
XPShowWidget(PositionWidget);
}
}
void CreatePosition(int x, int y, int w, int h)
{
int x2 = x + w;
int y2 = y - h;
float FloatValue[MAX_ITEMS];
double DoubleValue[3];
char buffer[512];
int Item;
for (Item=0; Item<MAX_ITEMS; Item++)
FloatValue[Item] = XPLMGetDataf(gPositionDataRef[Item]);
/// X, Y, Z, Lat, Lon, Alt
XPLMLocalToWorld(FloatValue[0], FloatValue[1], FloatValue[2], &DoubleValue[0], &DoubleValue[1], &DoubleValue[2]);
DoubleValue[2] *= 3.28;
PositionWidget = XPCreateWidget(x, y, x2, y2,
1, // Visible
"Position", // desc
1, // root
NULL, // no container
xpWidgetClass_MainWindow);
XPSetWidgetProperty(PositionWidget, xpProperty_MainWindowHasCloseBoxes, 1);
PositionWindow = XPCreateWidget(x+50, y-50, x2-50, y2+50,
1, // Visible
"", // desc
0, // root
PositionWidget,
xpWidgetClass_SubWindow);
XPSetWidgetProperty(PositionWindow, xpProperty_SubWindowType, xpSubWindowStyle_SubWindow);
for (Item=0; Item<MAX_ITEMS-3; Item++)
{
PositionText[Item] = XPCreateWidget(x+60, y-(70 + (Item*30)), x+115, y-(92 + (Item*30)),
1, // Visible
DataRefDesc[Item],// desc
0, // root
PositionWidget,
xpWidgetClass_Caption);
sprintf(buffer, "%f", HACKFLOAT(FloatValue[Item]));
PositionEdit[Item] = XPCreateWidget(x+120, y-(70 + (Item*30)), x+210, y-(92 + (Item*30)),
1, buffer, 0, PositionWidget,
xpWidgetClass_TextField);
XPSetWidgetProperty(PositionEdit[Item], xpProperty_TextFieldType, xpTextEntryField);
UpArrow[Item] = XPCreateWidget(x+212, y-(66 + (Item*30)), x+224, y-(81 + (Item*30)),
1, "", 0, PositionWidget,
xpWidgetClass_Button);
XPSetWidgetProperty(UpArrow[Item], xpProperty_ButtonType, xpLittleUpArrow);
DownArrow[Item] = XPCreateWidget(x+212, y-(81 + (Item*30)), x+224, y-(96 + (Item*30)),
1, "", 0, PositionWidget,
xpWidgetClass_Button);
XPSetWidgetProperty(DownArrow[Item], xpProperty_ButtonType, xpLittleDownArrow);
}
PositionApplyButton = XPCreateWidget(x+50, y-310, x+140, y-332,
1, "Apply Data", 0, PositionWidget,
xpWidgetClass_Button);
XPSetWidgetProperty(PositionApplyButton, xpProperty_ButtonType, xpPushButton);
LatLonRefApplyButton = XPCreateWidget(x+145, y-310, x+240, y-332,
1, "Apply LatLonRef", 0, PositionWidget,
xpWidgetClass_Button);
XPSetWidgetProperty(LatLonRefApplyButton, xpProperty_ButtonType, xpPushButton);
for (Item=0; Item<3; Item++)
{
Position2Text[Item] = XPCreateWidget(x+60, y-(350 + (Item*30)), x+115, y-(372 + (Item*30)),
1, // Visible
Description[Item],// desc
0, // root
PositionWidget,
xpWidgetClass_Caption);
sprintf(buffer, "%lf", HACKFLOAT(DoubleValue[Item]));
Position2Edit[Item] = XPCreateWidget(x+120, y-(350 + (Item*30)), x+210, y-(372 + (Item*30)),
1, buffer, 0, PositionWidget,
xpWidgetClass_TextField);
XPSetWidgetProperty(PositionEdit[Item], xpProperty_TextFieldType, xpTextEntryField);
}
LatLonAltApplyButton = XPCreateWidget(x+70, y-440, x+220, y-462,
1, "Apply LatLonAlt", 0, PositionWidget,
xpWidgetClass_Button);
XPSetWidgetProperty(LatLonAltApplyButton, xpProperty_ButtonType, xpPushButton);
ReloadSceneryButton = XPCreateWidget(x+70, y-465, x+220, y-487,
1, "Reload Scenery", 0, PositionWidget,
xpWidgetClass_Button);
XPSetWidgetProperty(ReloadSceneryButton, xpProperty_ButtonType, xpPushButton);
XPAddWidgetCallback(PositionWidget, PositionHandler);
}
int PositionHandler(
XPWidgetMessage inMessage,
XPWidgetID inWidget,
intptr_t inParam1,
intptr_t inParam2)
{
float FloatValue[MAX_ITEMS];
char buffer[512];
int Item;
for (Item=0; Item<MAX_ITEMS; Item++)
FloatValue[Item] = XPLMGetDataf(gPositionDataRef[Item]);
if (inMessage == xpMessage_CloseButtonPushed)
{
if (MenuItem1 == 1)
{
XPHideWidget(PositionWidget);
}
return 1;
}
if (inMessage == xpMsg_PushButtonPressed)
{
if (inParam1 == (intptr_t)PositionApplyButton)
{
ApplyValues();
return 1;
}
if (inParam1 == (intptr_t)LatLonRefApplyButton)
{
ApplyLatLonRefValues();
return 1;
}
if (inParam1 == (intptr_t)LatLonAltApplyButton)
{
ApplyLatLonAltValues();
return 1;
}
if (inParam1 == (intptr_t)ReloadSceneryButton)
{
XPLMReloadScenery();
return 1;
}
for (Item=0; Item<MAX_ITEMS-3; Item++)
{
if (inParam1 == (intptr_t)UpArrow[Item])
{
FloatValue[Item] += 1.0;
sprintf(buffer, "%f", HACKFLOAT(FloatValue[Item]));
XPSetWidgetDescriptor(PositionEdit[Item], buffer);
XPLMSetDataf(gPositionDataRef[Item], FloatValue[Item]);
return 1;
}
}
for (Item=0; Item<MAX_ITEMS-3; Item++)
{
if (inParam1 == (intptr_t)DownArrow[Item])
{
FloatValue[Item] -= 1.0;
sprintf(buffer, "%f", HACKFLOAT(FloatValue[Item]));
XPSetWidgetDescriptor(PositionEdit[Item], buffer);
XPLMSetDataf(gPositionDataRef[Item], FloatValue[Item]);
return 1;
}
}
}
return 0;
}
void ApplyValues(void)
{
char buffer[512];
for (int Item=0; Item<MAX_ITEMS-3; Item++)
{
XPGetWidgetDescriptor(PositionEdit[Item], buffer, 512);
XPLMSetDataf(gPositionDataRef[Item], atof(buffer));
}
}
void ApplyLatLonRefValues(void)
{
float FloatValue;
char buffer[512];
XPGetWidgetDescriptor(PositionEdit[3], buffer, 512);
FloatValue = atof(buffer);
XPLMSetDataf(gPositionDataRef[3], FloatValue);
XPGetWidgetDescriptor(PositionEdit[4], buffer, 512);
FloatValue = atof(buffer);
XPLMSetDataf(gPositionDataRef[4], FloatValue);
}
void ApplyLatLonAltValues(void)
{
float FloatValue[3];
double DoubleValue[3];
char buffer[512];
int Item;
// This gets the lat/lon/alt from the widget text fields
for (Item=0; Item<3; Item++)
{
XPGetWidgetDescriptor(Position2Edit[Item], buffer, 512);
FloatValue[Item] = atof(buffer);
}
/// Lat, Lon, Alt, X, Y, Z
XPLMWorldToLocal(FloatValue[0], FloatValue[1], FloatValue[2] / 3.28, &DoubleValue[0], &DoubleValue[1], &DoubleValue[2]);
for (Item=0; Item<3; Item++)
{
// This writes out the lat/lon/alt from the widget text fields back to the datarefs
XPLMSetDataf(gPositionDataRef[Item+8], FloatValue[Item]);
// This writes out the x,y,z datarefs after conversion from lat/lon/alt back to the datarefs
XPLMSetDataf(gPositionDataRef[Item], DoubleValue[Item]);
}
ApplyLatLonRefValues();
}
Hi, I have copied this plugin to visual studio 2017 and after adding libraries and other paths I tried to compile it. Here is a message:
‘void XPAddWidgetCallback(XPWidgetID,XPWidgetFunc_t)’: cannot convert argument 2 from ‘int (__cdecl*)(XPWidgetMessage,XPWidgetID,intptr_t,intptr_t)’ to ‘XPWidgetFunc_t’
I have no idea what to do and how to solve this issue.
Just so others know, in order to fix this error for X-Plane 11 64-bit, all you need to do is to replace the SDK subfolder in this example package with the official SDK v3, which is 64 bit compatible. The problem is to do with the fact that the sample was updated for the 64-bit, but the included SDK was not.
This may be untimely since it has been a few months since the original question…
But I was able to compile in Visual Studio 2017 by correcting the error line (line # 254 in positon.cpp)
as follows:
XPAddWidgetCallback(PositionWidget, (XPWidgetFunc_t) PositionHandler);
I also had to add the library path from the SDK (e.g. C:…\X-Plane SDK\SDK\Libraries\Win) to the project properties to get it to link.
I tried to post a reply to this once already, hopefully this doesn’t end up as a duplicate but I don’t see my reply so I will try once more….
It may be a little late since its been a couple of months since the question was posted – but I was able to successfully compile this example in Visual Studio 2017 by changing the error line (line 264 in position.cpp) as follows:
XPAddWidgetCallback(PositionWidget, (XPWidgetFunc_t) PositionHandler);
I also had to add a path to the SDK libraries in order to get the project to link (i.e. to complete the build)
e.g. C:…..\SDK\Libraries\Win\XPLM_64.lib
(See project properties menu, linker category, general sub-category, additional directories entry.)