Jump to content
The simFlight Network Forums

Recommended Posts

Posted

Pete,

I am developing a gauge which I want to read the present position.

I can read 8 bytes from offset 0x0560 into a SINT64 variable and process it in accordance with the instructions in the SDK into a FLOAT64 variable and this provides the Latitude fine.

However, when I try similar process with 8 bytes from 0x0568 for the longitude the result comes out as 0.nnnnn where

.nnnnn * 60 is the correct number of minutes for East Longitude,

and

60 - (.nnnnn * 60) is the correct number of minutes for West Longitude,

but in all cases the number of degrees is always 0 and the actual answer is always positive.

Any suggestions you have would be appreciated.

Trevor

Posted

However, when I try similar process with 8 bytes from 0x0568 for the longitude the result comes out as 0.nnnnn where

.nnnnn * 60 is the correct number of minutes for East Longitude,

and 60 - (.nnnnn * 60) is the correct number of minutes for West Longitude, but in all cases the number of degrees is always 0 and the actual answer is always positive.

Sorry, you evidently have an error, but I cannot diagnose it from here. The values are used in very many programs with no trouble at all, including for instance my own TrafficLook which uses them to calculate distance and bearing to the AI traffic it lists. Similarly, Project Magenta, Squawkbox, and all the weather programs to name but a few.

If you post a code snippet here I am sure someone can spot your error -- I am okay with C or C++ but other visitors know Visual Basic and some even Delphi, possibly.

Regards,

Pete

Posted

Pete,

Here goes with C code extracts.

From Gauge Heading declarations:

GAUGE_HEADER_FS700(GAUGE_W, display_gauge_name, &display_list, \

display_mouse_rect, display_cb, 0, 0, 0);

char chTime[3];

BOOL FS_read_ok;

FLOAT64 AC_Lat;

FLOAT64 AC_Long;

Callback function

void FSAPI display_cb(PGAUGEHDR pgauge, int service_id, \

UINT32 extra_data)

{

UINT32 dwResult;

SINT64 AC_Lat_int, AC_Long_int;

switch(service_id)

{

case PANEL_SERVICE_PRE_INSTALL:

break;

case PANEL_SERVICE_POST_INSTALL:

FSUIPC_Open(SIM_ANY,&dwResult);

break;

case PANEL_SERVICE_PRE_INITIALIZE:

break;

case PANEL_SERVICE_PRE_UPDATE:

FS_read_ok = TRUE;

if (!FSUIPC_Read(0x238, 3, chTime, &dwResult) ||

!FSUIPC_Read(0x560, 8, &AC_Lat_int, &dwResult) ||

!FSUIPC_Read(0x568, 8, &AC_Long_int, &dwResult) ||

!FSUIPC_Process(&dwResult))

FS_read_ok = FALSE;

else

{

AC_Lat = AC_Lat_int * 90 /( 10001750.0 * 65536 * 65536 );

AC_Long = AC_Long_int * 360 / (65536.0 * 65536 * 65536 * 65536);

}

break;

case PANEL_SERVICE_PRE_DRAW:

break;

case PANEL_SERVICE_PRE_KILL:

FSUIPC_Close();

break;

}

}

Lat display callback (Works fine N or S Lat)

FLOAT64 FSAPI lat_string_cb( PELEMENT_STRING pelement )

{

UINT32 deg;

float min;

char n_s;

if (FS_read_ok)

{

if (AC_Lat >= 0) n_s = 'N'; else

{

n_s = 'S';

AC_Lat = - AC_Lat;

}

deg = floor(AC_Lat);

min = ( AC_Lat - deg) * 60;

sprintf(pelement->string, "%c%2d*%6.3f",n_s, deg, min);

}

return 1.0;

}

Long display callback

FLOAT64 FSAPI long_string_cb( PELEMENT_STRING pelement )

{

UINT32 deg;

float min;

char e_w;

if (FS_read_ok)

{

if (AC_Long >= 0) e_w = 'E';

else

{

e_w = 'W';

AC_Long = - AC_Long;

}

deg = floor(AC_Long);

min = ( AC_Long - deg) * 60;

sprintf(pelement->string, "%c%03d*%6.3f",e_w, deg, min);

}

return 1.0;

}

For Ohakea AFB NZ E175*23.42' (From FS9 readout)

displays E000*23.421

For Vance AFB OK W97*55.39'

displays E000* 4.609

System is running WinXPpro

compilation using Visual Studio 6 IDE (VC98)

Trevor

Posted

From Gauge Heading declarations:

This is a gauge you are writing?

If so, this is wrong:

FSUIPC_Open(SIM_ANY,&dwResult);

You must use the module users interface (see separate ZIP in the SDK, and FSUIPC_Open2. Else your gauge will (a) only run on fully user registered copies of FSUIPC, and (b) possibly clash and fail if anyone else in FS is using the same EXTERNAL interface that you are!

On this:

AC_Lat = AC_Lat_int * 90 /( 10001750.0 * 65536 * 65536 );

AC_Long = AC_Long_int * 360 / (65536.0 * 65536 * 65536 * 65536);

I don't know how the compiler handles "SINT64" (ie __int64), but maybe the conversion to double float is not working well because of the mixture of floating and fixed values you are using. Try:

AC_Lat = (AC_Lat_int * 90.0) /( 10001750.0 * 65536.0 * 65536.0);

AC_Long = (AC_Long_int * 360.0) / (65536.0 * 65536.0 * 65536.0 * 65536.0);

just to make sure it is using floating point throughout. I added more parentheses to to make sure it is calculating things in the right order.

You could also use your debugger to se what is actually happening.

BTW, since you are writing a gauge, why not simply read the Lat/Long in floating point directly via the Gauge tokens PLANE_LATITUDE and PLANE_LONGITUDE? It seems a bit odd using the external application interface for FSUIPC to get stuff you can read directly inside FS!

Regards,

Pete

Posted

Pete,

Thank you, you nailed it.

The compiler performs all multiplications/divisions in FP if any of the terms is FP so the denominator terms worked fine with just the first term as a float and apparently AC_Lat_int*90 did not cause an integer overflow, but obviously AC_Long_int*360 was resulting in an integer overflow. Changing to (AC_Long_int*360.0) forced the calculation into FP and prevented the overflow.

I have found the module user section thank you.

I know if this was all I wanted, the token var would have provided the answer. However, this is just the first preliminary step in providing an Air-to-air radar using the AI tables, so I figured on using this as a "simpler ??" exploration of the UIPC interface, before diving into the AI tables.

Trevor.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.