Sample: SDK.FlightMap.cpp
//Copyright (c) Microsoft Corporation. All rights reserved. // SDK.FlightMap.c // Set up gauge header char flightmap_gauge_name[] = GAUGE_NAME; extern PELEMENT_HEADER flightmap_list; extern MOUSERECT flightmap_rect[]; GAUGE_CALLBACK FlightMapCallback; GAUGE_HEADER_FS700(GAUGE_W, flightmap_gauge_name, &flightmap;_list, flightmap_rect, FlightMapCallback, 0, 0, 0); ///////////////////////////////////////////////////////////////////////////// FAILURE_RECORD flightmap_fail[] = { {FAIL_SYSTEM_ELECTRICAL_AVIONICS, FAIL_ACTION_NO_DRAW}, {FAIL_NONE, FAIL_ACTION_NONE} }; #define MAP_LEFT_BORDER 25 #define MAP_TOP_BORDER 35 MAKE_STATIC ( flightmap_image, BMP_FLIGHT_MAP_BLANK, NULL, NULL, IMAGE_USE_ERASE|IMAGE_USE_BRIGHT|IMAGE_CREATE_DIBSECTION, 0, MAP_LEFT_BORDER, MAP_TOP_BORDER ) PELEMENT_HEADER flightmap_next[] = { &flightmap;_image.header, NULL }; MAKE_STATIC ( flightmap_background, BMP_FLIGHT_MAP_BACKGROUND, flightmap_next, NULL, IMAGE_USE_TRANSPARENCY, 0, 0,0 ) PELEMENT_HEADER flightmap_list = &flightmap;_background.header; ///////////////////////////////////////////////////////////////////////////// static FLOAT64 FSAPI GPSARG_Get_GroundSpeed (FLOAT64 number, ID id, PCSTRINGZ string, MODULE_VAR *source_var, PGAUGEHDR gauge); static FLOAT64 FSAPI GPSARG_Get_Track (FLOAT64 number, ID id, PCSTRINGZ string, MODULE_VAR *source_var, PGAUGEHDR gauge); static FLOAT64 FSAPI GPSARG_Get_WP_Distance (FLOAT64 number, ID id, PCSTRINGZ string, MODULE_VAR *source_var, PGAUGEHDR gauge); static PCSTRINGZ FSAPI GPSARG_Get_WP_ID (FLOAT64 number, ID id, PCSTRINGZ string, MODULE_VAR *source_var, PGAUGEHDR gauge); static MOUSE_FUNCTION AddNewWaypoint; MOUSE_TOOLTIP_ARGS (GPS_Args) MOUSE_TOOLTIP_ARG (MODULE_VAR_NONE, 0, NULL, NULL, NULL, GPSARG_Get_GroundSpeed, NULL, NULL) MOUSE_TOOLTIP_ARG (MODULE_VAR_NONE, 0, NULL, NULL, NULL, GPSARG_Get_Track, NULL, NULL) MOUSE_TOOLTIP_ARG (MODULE_VAR_NONE, 0, NULL, NULL, NULL, NULL, NULL, GPSARG_Get_WP_ID) MOUSE_TOOLTIP_ARG (MODULE_VAR_NONE, 0, NULL, NULL, NULL, GPSARG_Get_WP_Distance, NULL, NULL) MOUSE_TOOLTIP_ARGS_END MOUSE_BEGIN( flightmap_rect, HELP_NONE, 0, 0 ) MOUSE_TOOLTIP_TEXT_STRING ("Ground Speed: %1!d! knots, Track: %2!d!???, Next Waypoint: %3!s!, Distance: %4!.1f! nm", GPS_Args) MOUSE_CHILD_FUNCT (MAP_LEFT_BORDER, MAP_TOP_BORDER, 230, 259, CURSOR_HAND, MOUSE_LEFTSINGLE, AddNewWaypoint) MOUSE_END #include <math.h> #include "gps_info.h" static GPS_INFO* gpsinfo = NULL; static GPS_INFO* gpsrequest = NULL; static POINT ScalePoint (PLATLONALT llaRef, PLATLONALT llaPoint, FLOAT64 fRefDirection, FLOAT64 dx, FLOAT64 dy); void FSAPI FlightMapCallback ( PGAUGEHDR pgauge, SINT32 service_id, UINT32 extra_data ) { switch (service_id) { case PANEL_SERVICE_PRE_DRAW: { PELEMENT_STATIC_IMAGE pelement = (PELEMENT_STATIC_IMAGE)(pgauge->elements_list[0]->next_element[0]); if (!gpsinfo) { MODULE_VAR var; initialize_var_by_name (&var;, GPS_INFO_PANEL_VARIABLE_NAME); gpsinfo = (GPS_INFO*)var.var_ptr; } if (pelement) { HDC hdc = pelement->hdc; PIXPOINT dim = pelement->image_data.final->dim; if (hdc) { FLOAT64 dx = dim.x / 230.0; FLOAT64 dy = dim.y / 259.0; INT cx = (INT)(115 * dx); INT cy = (INT)(130 * dy); // clear background SelectObject (hdc, GetStockObject (BLACK_BRUSH)); SelectObject (hdc, GetStockObject (WHITE_PEN)); Rectangle (hdc, 0, 0, dim.x, dim.y); // draw aircraft symbol { static POINT AircraftShape[] = { { 0, -6}, { 2, -5}, { 2, -2}, { 6, 0}, { 6, 2}, { 2, 1}, { 2, 4}, { 4, 4}, { 4, 6}, {-4, 6}, {-4, 4}, {-2, 4}, {-2, 1}, {-6, 2}, {-6, 0}, {-2, -2}, {-2, -5}, }; INT lPoints = sizeof (AircraftShape)/sizeof (POINT); POINT ResizedShape[sizeof (AircraftShape)/sizeof (POINT)]; int i; for (i = 0; i < lPoints; i++) { ResizedShape[i].x = (INT)(AircraftShape[i].x * dx) + cx; ResizedShape[i].y = (INT)(AircraftShape[i].y * dy) + cy; } SelectObject (hdc, GetStockObject (WHITE_BRUSH)); SelectObject (hdc, GetStockObject (WHITE_PEN)); Polygon (hdc, ResizedShape, lPoints); } // draw waypoints if (gpsinfo && gpsinfo->dwSize >= sizeof (GPS_INFO)) { int i; POINT prevp; for (i = 0; i < gpsinfo->lWpCounts; i++) { if (gpsinfo->pWpData && gpsinfo->pWpData[i].dwSize == sizeof (GPS_WP_INFO)) { POINT p = ScalePoint (&gpsinfo;->vPosition, &gpsinfo;->pWpData[i].vPosition, gpsinfo->dGroundHeading, dx, dy); p.x += cx; p.y += cy; if (gpsinfo->lNextWp == i) SelectObject (hdc, GetStockObject (WHITE_BRUSH)); else SelectObject (hdc, GetStockObject (HOLLOW_BRUSH)); SelectObject (hdc, GetStockObject (WHITE_PEN)); Ellipse (hdc, p.x - 5, p.y - 5, p.x + 5, p.y + 5); if (i > 0) { MoveToEx (hdc, prevp.x, prevp.y, NULL); LineTo (hdc, p.x, p.y); } prevp = p; } } } SET_OFF_SCREEN (pelement); } } } break; } } __inline SIF48 SUB_SIF48_SIF48 (const SIF48 a, const SIF48 b) { SIF48 r; r.i64 = a.i64 - b.i64; return r; } __inline SIF48 ADD_SIF48_SIF48 (const SIF48 a, const SIF48 b) { SIF48 r; r.i64 = a.i64 + b.i64; return(r); } __inline ANGL48 SUB_ANGL48_ANGL48 (const ANGL48 a, const ANGL48 b) { ANGL48 r; r.i64 = a.i64 - b.i64; return r; } __inline ANGL48 ADD_ANGL48_ANGL48 (const ANGL48 a, const ANGL48 b) { ANGL48 r; r.i64 = a.i64 + b.i64; return r; } __inline FLOAT64 ANGL48_TO_FLOAT64 (const ANGL48 angl48) { return (FLOAT64)(SINT64)(angl48.i64 & ~0xFFFF) * (1/4294967296.0); } __inline ANGL48 FLOAT64_TO_ANGL48 (const FLOAT64 angle) { ANGL48 r; r.i64 = (SINT64)(angle * 4294967296.0); return r; } __inline FLOAT64 SIF48_TO_FLOAT64 (const SIF48 sif48) { return (FLOAT64)(sif48.i64 & ~0xFFFF) * (1/4294967296.0); } __inline SIF48 FLOAT64_TO_SIF48 (FLOAT64 number) { SIF48 r; r.i64 = (SINT64)(number * 4294967296.0); return r; } __inline FLOAT64 ANGL48_TO_DEGREES (const ANGL48 angle) { return ANGL48_TO_FLOAT64(angle) * (360.0 / (65536.0 * 65536.0)); } __inline ANGL48 DEGREES_TO_ANGL48 (const FLOAT64 angle) { return FLOAT64_TO_ANGL48(angle * ((65536.0 * 65536.0) / 360.0)); } __inline FLOAT64 LON_DEG_TO_METERS_AT_LAT_RAD (FLOAT64 dDeltaLonAngle, FLOAT64 dCurLatRad) { return dDeltaLonAngle * (40075000.0 / 360) * cos(dCurLatRad); } __inline FLOAT64 METERS_TO_LON_DEG_AT_LAT_RAD (FLOAT64 dDeltaLonAngle, FLOAT64 dCurLatRad) { return dDeltaLonAngle * (360 / 40075000.0) / cos(dCurLatRad); } __inline FLOAT64 LAT_METERS48_TO_RADIANS (SIF48 sif48Lat) { return (FLOAT64)(SINT64)(sif48Lat.i64 & ~0xFFFF) * ((1.0 / (40007000.0/(3.14159265358*2))) * (1/4294967296.0)); } __inline FLOAT64 LAT_RADIANS_TO_METERS48 (SIF48 sif48Lat) { return (FLOAT64)(SINT64)(sif48Lat.i64 & ~0xFFFF) * ((1.0 / (40007000.0/(3.14159265358*2))) * (1/4294967296.0)); } #define SCALE_MAP_FACTOR 0.005 static POINT ScalePoint (PLATLONALT llaRef, PLATLONALT llaPoint, FLOAT64 fRefDirection, FLOAT64 dx, FLOAT64 dy) { ANGL48 anglDiff = SUB_ANGL48_ANGL48 (llaPoint->lon, llaRef->lon ); FLOAT64 fDeltaLonDeg = ANGL48_TO_DEGREES (anglDiff ); FLOAT64 fLatRad = LAT_METERS48_TO_RADIANS (llaRef->lat) ; FLOAT64 fLOMeters = LON_DEG_TO_METERS_AT_LAT_RAD (fDeltaLonDeg, fLatRad ); FLOAT64 fLAMeters = SIF48_TO_FLOAT64 (SUB_SIF48_SIF48 (llaPoint->lat, llaRef->lat)); FLOAT64 fSin = sin (fRefDirection); FLOAT64 fCos = cos (fRefDirection); FLOAT64 fX = fLOMeters * fCos - fLAMeters * fSin; FLOAT64 fY = -fLOMeters * fSin - fLAMeters * fCos; INT lX = (INT) (fX * dx * SCALE_MAP_FACTOR); INT lY = (INT) (fY * dy * SCALE_MAP_FACTOR); POINT result = { lX, lY }; return result; } static FLOAT64 FSAPI GPSARG_Get_GroundSpeed (FLOAT64 number, ID id, PCSTRINGZ string, MODULE_VAR *source_var, PGAUGEHDR gauge) { if (gpsinfo && gpsinfo->dwSize >= sizeof (GPS_INFO)) return gpsinfo->dGroundSpeed * 1.943844; else return 0; } static FLOAT64 FSAPI GPSARG_Get_Track (FLOAT64 number, ID id, PCSTRINGZ string, MODULE_VAR *source_var, PGAUGEHDR gauge) { if (gpsinfo && gpsinfo->dwSize >= sizeof (GPS_INFO)) return gpsinfo->dGroundTrack * 57.295780; else return 0; } static FLOAT64 FSAPI GPSARG_Get_WP_Distance (FLOAT64 number, ID id, PCSTRINGZ string, MODULE_VAR *source_var, PGAUGEHDR gauge) { if (gpsinfo && gpsinfo->dwSize >= sizeof (GPS_INFO) && gpsinfo->bIsActiveWaypoint) return gpsinfo->dWpDistance * 0.000539957; else return 0; } static PCSTRINGZ FSAPI GPSARG_Get_WP_ID (FLOAT64 number, ID id, PCSTRINGZ string, MODULE_VAR *source_var, PGAUGEHDR gauge) { if (gpsinfo && gpsinfo->dwSize >= sizeof (GPS_INFO) && gpsinfo->bIsActiveWaypoint && gpsinfo->lNextWp < gpsinfo->lWpCounts && gpsinfo->lNextWp >= 0 && gpsinfo->pWpData != NULL && gpsinfo->pWpData[gpsinfo->lNextWp].dwSize == sizeof (GPS_WP_INFO)) return gpsinfo->pWpData[gpsinfo->lNextWp].szName; else return "---"; } static BOOL FSAPI AddNewWaypoint (PPIXPOINT pPoint, FLAGS32 flags) { FLOAT64 lX = pPoint->x / GAUGEHDR_FOR_MOUSE_CALLBACK (pPoint)->x_adjust - 115.0; FLOAT64 lY = pPoint->y / GAUGEHDR_FOR_MOUSE_CALLBACK (pPoint)->y_adjust - 130.0; if (!gpsinfo) { MODULE_VAR var; initialize_var_by_name (&var;, GPS_INFO_PANEL_VARIABLE_NAME); gpsinfo = (GPS_INFO*)var.var_ptr; } if (!gpsrequest) { MODULE_VAR var; initialize_var_by_name (&var;, GPS_REQUEST_PANEL_VARIABLE_NAME); gpsrequest = (GPS_INFO*)var.var_ptr; } if (gpsinfo && gpsrequest && gpsinfo->pWpData && gpsrequest->pWpData && gpsinfo->lWpCounts >= 2) { UINT32 i; gpsrequest->dwUpdateRequest = 2; gpsrequest->vPosition = gpsinfo->vPosition; gpsrequest->bIsFlightPlanAvailable = TRUE; gpsrequest->bIsDirectTo = FALSE; gpsrequest->lNextWp = gpsinfo->lNextWp; gpsrequest->lWpCounts = gpsinfo->lWpCounts; for (i = 0; i < gpsinfo->lWpCounts; i++) { gpsrequest->pWpData[i] = gpsinfo->pWpData[i]; } if (gpsrequest->lWpCounts < MAX_GPS_WAYPOINTS) { UINT32 i = gpsrequest->lWpCounts++; gpsrequest->pWpData[i].dwSize = sizeof (GPS_WP_INFO); { FLOAT64 fX = lX / SCALE_MAP_FACTOR; FLOAT64 fY = lY / SCALE_MAP_FACTOR; FLOAT64 fSin = sin (gpsinfo->dGroundHeading); FLOAT64 fCos = cos (gpsinfo->dGroundHeading); FLOAT64 fLOMeters = fX * fCos + fY * fSin; FLOAT64 fLAMeters = fX * fSin - fY * fCos; FLOAT64 fLatRad = LAT_METERS48_TO_RADIANS (gpsinfo->vPosition.lat); FLOAT64 fDeltaLonDeg = METERS_TO_LON_DEG_AT_LAT_RAD (fLOMeters, fLatRad ); ANGL48 anglDiff = DEGREES_TO_ANGL48 (fDeltaLonDeg); LATLONALT v; v.lon = ADD_ANGL48_ANGL48 (gpsinfo->vPosition.lon, anglDiff); v.lat = ADD_SIF48_SIF48 (gpsinfo->vPosition.lat, FLOAT64_TO_SIF48 (fLAMeters)); v.alt = FLOAT64_TO_SIF48 (gpsrequest->pWpData[i-1].dAltitude); gpsrequest->pWpData[i].vPosition = v; } gpsrequest->pWpData[i].dHeading = gpsrequest->pWpData[i-1].dHeading; gpsrequest->pWpData[i].dSpeed = gpsrequest->pWpData[i-1].dSpeed; gpsrequest->pWpData[i].dAltitude = gpsrequest->pWpData[i-1].dAltitude; strcpy_s(gpsrequest->pWpData[i].szName, "???"); } } return FALSE; } ///////////////////////////////////////////////////////////////////////////// #undef MAP_LEFT_BORDER #undef MAP_TOP_BORDER #undef SCALE_MAP_FACTOR #undef GAUGE_NAME #undef GAUGEHDR_VAR_NAME #undef GAUGE_W |