629 lines
27 KiB
C

#ifndef _XPLMMap_h_
#define _XPLMMap_h_
/*
* Copyright 2005-2012 Sandy Barbour and Ben Supnik All rights reserved. See
* license.txt for usage. X-Plane SDK Version: 2.1.1
*
*/
/***************************************************************************
* XPLMMap
***************************************************************************/
/*
* This API allows you to create new layers within X-Plane maps. Your layers
* can draw arbitrary OpenGL, but they conveniently also have access to
* X-Plane's built-in icon and label drawing functions.
*
* As of X-Plane 11, map drawing happens in three stages:
*
* 1. backgrounds and "fill,"
* 2. icons, and
* 3. labels.
*
* Thus, all background drawing gets layered beneath all icons, which likewise
* get layered beneath all labels. Within each stage, the map obeys a
* consistent layer ordering, such that "fill" layers (layers that cover a
* large amount of map area, like the terrain and clouds) appear beneath
* "markings" layers (like airport icons). This ensures that layers with fine
* details don't get obscured by layers with larger details.
*
* The XPLM map API reflects both aspects of this draw layering: you can
* register a layer as providing either markings or fill, and X-Plane will
* draw your fill layers beneath your markings layers (regardless of
* registration order). Likewise, you are guaranteed that your layer's icons
* (added from within an icon callback) will go above your layer's OpenGL
* drawing, and your labels will go above your icons.
*
* The XPLM guarantees that all plugin-created fill layers go on top of all
* native X-Plane fill layers, and all plugin-created markings layers go on
* top of all X-Plane markings layers (with the exception of the aircraft
* icons). It also guarantees that the draw order of your own plugin's layers
* will be consistent. But, for layers created by different plugins, the only
* guarantee is that we will draw all of one plugin's layers of each type
* (fill, then markings), then all of the others'; we don't guarantee which
* plugin's fill and markings layers go on top of the other's.
*
* As of X-Plane 11, maps use true cartographic projections for their drawing,
* and different maps may use different projections. For that reason, all
* drawing calls include an opaque handle for the projection you should use to
* do the drawing. Any time you would draw at a particular latitude/longitude,
* you'll need to ask the projection to translate that position into "map
* coordinates." (Note that the projection is guaranteed not to change between
* calls to your prepare-cache hook, so if you cache your map coordinates
* ahead of time, there's no need to re-project them when you actually draw.)
*
* In addition to mapping normal latitude/longitude locations into map
* coordinates, the projection APIs also let you know the current heading for
* north. (Since X-Plane 11 maps can rotate to match the heading of the user's
* aircraft, it's not safe to assume that north is at zero degrees rotation.)
*
*/
#include "XPLMDefs.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(XPLM300)
/***************************************************************************
* DRAWING CALLBACKS
***************************************************************************/
/*
* When you create a new map layer (using XPLMCreateMapLayer), you can provide
* any or all of these callbacks. They allow you to insert your own OpenGL
* drawing, text labels, and icons into the X-Plane map at the appropriate
* places, allowing your layer to behave as similarly to X-Plane's built-in
* layers as possible.
*
*/
/*
* XPLMMapLayerID
*
* This is an opaque handle for a plugin-created map layer. Pass it to the map
* drawing APIs from an appropriate callback to draw in the layer you created.
*
*/
typedef void * XPLMMapLayerID;
/*
* XPLMMapProjectionID
*
* This is an opaque handle for a map projection. Pass it to the projection
* APIs to translate between map coordinates and latitude/longitudes.
*
*/
typedef void * XPLMMapProjectionID;
/*
* XPLMMapStyle
*
* Indicates the visual style being drawn by the map. In X-Plane, the user can
* choose between a number of map types, and different map types may have use
* a different visual representation for the same elements (for instance, the
* visual style of the terrain layer changes drastically between the VFR and
* IFR layers), or certain layers may be disabled entirely in some map types
* (e.g., localizers are only visible in the IFR low-enroute style).
*
*/
enum {
xplm_MapStyle_VFR_Sectional = 0,
xplm_MapStyle_IFR_LowEnroute = 1,
xplm_MapStyle_IFR_HighEnroute = 2,
};
typedef int XPLMMapStyle;
/*
* XPLMMapDrawingCallback_f
*
* This is the OpenGL map drawing callback for plugin-created map layers. You
* can perform arbitrary OpenGL drawing from this callback, with one
* exception: changes to the Z-buffer are not permitted, and will result in
* map drawing errors.
*
* All drawing done from within this callback appears beneath all built-in
* X-Plane icons and labels, but above the built-in "fill" layers (layers
* providing major details, like terrain and water). Note, however, that the
* relative ordering between the drawing callbacks of different plugins is not
* guaranteed.
*
*/
typedef void (* XPLMMapDrawingCallback_f)(
XPLMMapLayerID inLayer,
const float * inMapBoundsLeftTopRightBottom,
float zoomRatio,
float mapUnitsPerUserInterfaceUnit,
XPLMMapStyle mapStyle,
XPLMMapProjectionID projection,
void * inRefcon);
/*
* XPLMMapIconDrawingCallback_f
*
* This is the icon drawing callback that enables plugin-created map layers to
* draw icons using X-Plane's built-in icon drawing functionality. You can
* request an arbitrary number of PNG icons to be drawn via
* XPLMDrawMapIconFromSheet() from within this callback, but you may not
* perform any OpenGL drawing here.
*
* Icons enqueued by this function will appear above all OpenGL drawing
* (performed by your optional XPLMMapDrawingCallback_f), and above all
* built-in X-Plane map icons of the same layer type ("fill" or "markings," as
* determined by the XPLMMapLayerType in your XPLMCreateMapLayer_t). Note,
* however, that the relative ordering between the drawing callbacks of
* different plugins is not guaranteed.
*
*/
typedef void (* XPLMMapIconDrawingCallback_f)(
XPLMMapLayerID inLayer,
const float * inMapBoundsLeftTopRightBottom,
float zoomRatio,
float mapUnitsPerUserInterfaceUnit,
XPLMMapStyle mapStyle,
XPLMMapProjectionID projection,
void * inRefcon);
/*
* XPLMMapLabelDrawingCallback_f
*
* This is the label drawing callback that enables plugin-created map layers
* to draw text labels using X-Plane's built-in labeling functionality. You
* can request an arbitrary number of text labels to be drawn via
* XPLMDrawMapLabel() from within this callback, but you may not perform any
* OpenGL drawing here.
*
* Labels enqueued by this function will appear above all OpenGL drawing
* (performed by your optional XPLMMapDrawingCallback_f), and above all
* built-in map icons and labels of the same layer type ("fill" or "markings,"
* as determined by the XPLMMapLayerType in your XPLMCreateMapLayer_t). Note,
* however, that the relative ordering between the drawing callbacks of
* different plugins is not guaranteed.
*
*/
typedef void (* XPLMMapLabelDrawingCallback_f)(
XPLMMapLayerID inLayer,
const float * inMapBoundsLeftTopRightBottom,
float zoomRatio,
float mapUnitsPerUserInterfaceUnit,
XPLMMapStyle mapStyle,
XPLMMapProjectionID projection,
void * inRefcon);
#endif /* XPLM300 */
#if defined(XPLM300)
/***************************************************************************
* LAYER MANAGEMENT CALLBACKS
***************************************************************************/
/*
* These are various "bookkeeping" callbacks that your map layer can receive
* (if you provide the callback in your XPLMCreateMapLayer_t). They allow you
* to manage the lifecycle of your layer, as well as cache any
* computationally-intensive preparation you might need for drawing.
*
*/
/*
* XPLMMapPrepareCacheCallback_f
*
* A callback used to allow you to cache whatever information your layer needs
* to draw in the current map area.
*
* This is called each time the map's total bounds change. This is typically
* triggered by new DSFs being loaded, such that X-Plane discards old,
* now-distant DSFs and pulls in new ones. At that point, the available bounds
* of the map also change to match the new DSF area.
*
* By caching just the information you need to draw in this area, your future
* draw calls can be made faster, since you'll be able to simply "splat" your
* precomputed information each frame.
*
* We guarantee that the map projection will not change between successive
* prepare cache calls, nor will any draw call give you bounds outside these
* total map bounds. So, if you cache the projected map coordinates of all the
* items you might want to draw in the total map area, you can be guaranteed
* that no draw call will be asked to do any new work.
*
*/
typedef void (* XPLMMapPrepareCacheCallback_f)(
XPLMMapLayerID inLayer,
const float * inTotalMapBoundsLeftTopRightBottom,
XPLMMapProjectionID projection,
void * inRefcon);
/*
* XPLMMapWillBeDeletedCallback_f
*
* Called just before your map layer gets deleted. Because SDK-created map
* layers have the same lifetime as the X-Plane map that contains them, if the
* map gets unloaded from memory, your layer will too.
*
*/
typedef void (* XPLMMapWillBeDeletedCallback_f)(
XPLMMapLayerID inLayer,
void * inRefcon);
#endif /* XPLM300 */
#if defined(XPLM300)
/***************************************************************************
* MAP LAYER CREATION AND DESTRUCTION
***************************************************************************/
/*
* Enables the creation of new map layers. Layers are created for a particular
* instance of the X-Plane map. For instance, if you want your layer to appear
* in both the normal map interface and the Instructor Operator Station (IOS),
* you would need two separate calls to XPLMCreateMapLayer(), with two
* different values for your XPLMCreateMapLayer_t::layer_name.
*
* Your layer's lifetime will be determined by the lifetime of the map it is
* created in. If the map is destroyed (on the X-Plane side), your layer will
* be too, and you'll receive a callback to your
* XPLMMapWillBeDeletedCallback_f.
*
*/
/*
* XPLMMapLayerType
*
* Indicates the type of map layer you are creating. Fill layers will always
* be drawn beneath markings layers.
*
*/
enum {
/* A layer that draws "fill" graphics, like weather patterns, terrain, etc. *
* Fill layers frequently cover a large portion of the visible map area. */
xplm_MapLayer_Fill = 0,
/* A layer that provides markings for particular map features, like NAVAIDs, *
* airports, etc. Even dense markings layers cover a small portion of the *
* total map area. */
xplm_MapLayer_Markings = 1,
};
typedef int XPLMMapLayerType;
/* Globally unique identifier for X-Plane's Map window, used as the *
* mapToCreateLayerIn parameter in XPLMCreateMapLayer_t */
#define XPLM_MAP_USER_INTERFACE "XPLM_MAP_USER_INTERFACE"
/* Globally unique identifier for X-Plane's Instructor Operator Station *
* window, used as the mapToCreateLayerIn parameter in XPLMCreateMapLayer_t */
#define XPLM_MAP_IOS "XPLM_MAP_IOS"
/*
* XPLMCreateMapLayer_t
*
* This structure defines all of the parameters used to create a map layer
* using XPLMCreateMapLayer. The structure will be expanded in future SDK APIs
* to include more features. Always set the structSize member to the size of
* your struct in bytes!
*
* Each layer must be associated with exactly one map instance in X-Plane.
* That map, and that map alone, will call your callbacks. Likewise, when that
* map is deleted, your layer will be as well.
*
*/
typedef struct {
/* Used to inform XPLMCreateMapLayer() of the SDK version you compiled *
* against; should always be set to sizeof(XPLMCreateMapLayer_t) */
int structSize;
/* Globally unique string identifying the map you want this layer to appear *
* in. As of XPLM300, this is limited to one of XPLM_MAP_USER_INTERFACE or *
* XPLM_MAP_IOS */
const char * mapToCreateLayerIn;
/* The type of layer you are creating, used to determine draw order (all *
* plugin-created markings layers are drawn above all plugin-created fill *
* layers) */
XPLMMapLayerType layerType;
/* Optional callback to inform you this layer is being deleted (due to its *
* owning map being destroyed) */
XPLMMapWillBeDeletedCallback_f willBeDeletedCallback;
/* Optional callback you want to use to prepare your draw cache when the map *
* bounds change (set to NULL if you don't want this callback) */
XPLMMapPrepareCacheCallback_f prepCacheCallback;
/* Optional callback you want to use for arbitrary OpenGL drawing, which goes *
* beneath all icons in the map's layering system (set to NULL if you don't *
* want this callback) */
XPLMMapDrawingCallback_f drawCallback;
/* Optional callback you want to use for drawing icons, which go above all *
* built-in X-Plane icons (except the aircraft) in the map's layering system *
* (set to NULL if you don't want this callback) */
XPLMMapIconDrawingCallback_f iconCallback;
/* Optional callback you want to use for drawing map labels, which go above *
* all built-in X-Plane icons and labels (except those of aircraft) in the *
* map's layering system (set to NULL if you don't want this callback) */
XPLMMapLabelDrawingCallback_f labelCallback;
/* True if you want a checkbox to be created in the map UI to toggle this *
* layer on and off; false if the layer should simply always be enabled */
int showUiToggle;
/* Short label to use for this layer in the user interface */
const char * layerName;
/* A reference to arbitrary data that will be passed to your callbacks */
void * refcon;
} XPLMCreateMapLayer_t;
/*
* XPLMCreateMapLayer
*
* This routine creates a new map layer. You pass in an XPLMCreateMapLayer_t
* structure with all of the fields set in. You must set the structSize of
* the structure to the size of the actual structure you used.
*
* Returns NULL if the layer creation failed. This happens most frequently
* because the map you specified in your
* XPLMCreateMapLayer_t::mapToCreateLayerIn field doesn't exist (that is, if
* XPLMMapExists() returns 0 for the specified map). You can use
* XPLMRegisterMapCreationHook() to get a notification each time a new map is
* opened in X-Plane, at which time you can create layers in it.
*
*/
XPLM_API XPLMMapLayerID XPLMCreateMapLayer(
XPLMCreateMapLayer_t * inParams);
/*
* XPLMDestroyMapLayer
*
* Destroys a map layer you created (calling your
* XPLMMapWillBeDeletedCallback_f if applicable). Returns true if a deletion
* took place.
*
*/
XPLM_API int XPLMDestroyMapLayer(
XPLMMapLayerID inLayer);
/*
* XPLMMapCreatedCallback_f
*
* A callback to notify your plugin that a new map has been created in
* X-Plane. This is the best time to add a custom map layer using
* XPLMCreateMapLayer().
*
* No OpenGL drawing is permitted within this callback.
*
*/
typedef void (* XPLMMapCreatedCallback_f)(
const char * mapIdentifier,
void * refcon);
/*
* XPLMRegisterMapCreationHook
*
* Registers your callback to receive a notification each time a new map is
* constructed in X-Plane. This callback is the best time to add your custom
* map layer using XPLMCreateMapLayer().
*
* Note that you will not be notified about any maps that already exist---you
* can use XPLMMapExists() to check for maps that were created previously.
*
*/
XPLM_API void XPLMRegisterMapCreationHook(
XPLMMapCreatedCallback_f callback,
void * refcon);
/*
* XPLMMapExists
*
* Returns 1 if the map with the specified identifier already exists in
* X-Plane. In that case, you can safely call XPLMCreateMapLayer() specifying
* that your layer should be added to that map.
*
*/
XPLM_API int XPLMMapExists(
const char * mapIdentifier);
#endif /* XPLM300 */
#if defined(XPLM300)
/***************************************************************************
* MAP DRAWING
***************************************************************************/
/*
* These APIs are only valid from within a map drawing callback (one of
* XPLMIconDrawingCallback_t or XPLMMapLabelDrawingCallback_f). Your drawing
* callbacks are registered when you create a new map layer as part of your
* XPLMCreateMapLayer_t. The functions here hook into X-Plane's built-in map
* drawing functionality for icons and labels, so that you get a consistent
* style with the rest of the X-Plane map.
*
* Note that the X-Plane 11 map introduces a strict ordering: layers of type
* xplm_MapLayer_Fill get drawn beneath all xplm_MapLayer_Markings layers.
* Likewise, all OpenGL drawing (performed in your layer's
* XPLMMapDrawingCallback_f) will appear beneath any icons and labels you
* draw.
*
*/
/*
* XPLMMapOrientation
*
* Indicates whether a map element should be match its rotation to the map
* itself, or to the user interface. For instance, the map itself may be
* rotated such that "up" matches the user's aircraft, but you may want to
* draw a text label such that it is always rotated zero degrees relative to
* the user's perspective. In that case, you would have it draw with UI
* orientation.
*
*/
enum {
/* Orient such that a 0 degree rotation matches the map's north */
xplm_MapOrientation_Map = 0,
/* Orient such that a 0 degree rotation is "up" relative to the user interface*/
xplm_MapOrientation_UI = 1,
};
typedef int XPLMMapOrientation;
/*
* XPLMDrawMapIconFromSheet
*
* Enables plugin-created map layers to draw PNG icons using X-Plane's
* built-in icon drawing functionality. Only valid from within an
* XPLMIconDrawingCallback_t (but you can request an arbitrary number of icons
* to be drawn from within your callback).
*
* X-Plane will automatically manage the memory for your texture so that it
* only has to be loaded from disk once as long as you continue drawing it
* per-frame. (When you stop drawing it, the memory may purged in a "garbage
* collection" pass, require a load from disk in the future.)
*
* Instead of having X-Plane draw a full PNG, this method allows you to use UV
* coordinates to request a portion of the image to be drawn. This allows you
* to use a single texture load (of an icon sheet, for example) to draw many
* icons. Doing so is much more efficient than drawing a dozen different small
* PNGs.
*
* The UV coordinates used here treat the texture you load as being comprised
* of a number of identically sized "cells." You specify the width and height
* in cells (ds and dt, respectively), as well as the coordinates within the
* cell grid for the sub-image you'd like to draw.
*
* Note that you can use different ds and dt values in subsequent calls with
* the same texture sheet. This enables you to use icons of different sizes in
* the same sheet if you arrange them properly in the PNG.
*
* This function is only valid from within an XPLMIconDrawingCallback_t (but
* you can request an arbitrary number of icons to be drawn from within your
* callback).
*
*/
XPLM_API void XPLMDrawMapIconFromSheet(
XPLMMapLayerID layer,
const char * inPngPath,
int s,
int t,
int ds,
int dt,
float mapX,
float mapY,
XPLMMapOrientation orientation,
float rotationDegrees,
float mapWidth);
/*
* XPLMDrawMapLabel
*
* Enables plugin-created map layers to draw text labels using X-Plane's
* built-in labeling functionality. Only valid from within an
* XPLMMapLabelDrawingCallback_f (but you can request an arbitrary number of
* text labels to be drawn from within your callback).
*
*/
XPLM_API void XPLMDrawMapLabel(
XPLMMapLayerID layer,
const char * inText,
float mapX,
float mapY,
XPLMMapOrientation orientation,
float rotationDegrees);
#endif /* XPLM300 */
#if defined(XPLM300)
/***************************************************************************
* MAP PROJECTIONS
***************************************************************************/
/*
* As of X-Plane 11, the map draws using true cartographic projections, and
* different maps may use different projections. Thus, to draw at a particular
* latitude and longitude, you must first transform your real-world
* coordinates into map coordinates.
*
* The map projection is also responsible for giving you the current scale of
* the map. That is, the projection can tell you how many map units correspond
* to 1 meter at a given point.
*
* Finally, the map projection can give you the current rotation of the map.
* Since X-Plane 11 maps can rotate to match the heading of the aircraft, the
* map's rotation can potentially change every frame.
*
*/
/*
* XPLMMapProject
*
* Projects a latitude/longitude into map coordinates. This is the inverse of
* XPLMMapUnproject().
*
* Only valid from within a map layer callback (one of
* XPLMMapPrepareCacheCallback_f, XPLMMapDrawingCallback_f,
* XPLMMapIconDrawingCallback_f, or XPLMMapLabelDrawingCallback_f.)
*
*/
XPLM_API void XPLMMapProject(
XPLMMapProjectionID projection,
double latitude,
double longitude,
float * outX,
float * outY);
/*
* XPLMMapUnproject
*
* Transforms map coordinates back into a latitude and longitude. This is the
* inverse of XPLMMapProject().
*
* Only valid from within a map layer callback (one of
* XPLMMapPrepareCacheCallback_f, XPLMMapDrawingCallback_f,
* XPLMMapIconDrawingCallback_f, or XPLMMapLabelDrawingCallback_f.)
*
*/
XPLM_API void XPLMMapUnproject(
XPLMMapProjectionID projection,
float mapX,
float mapY,
double * outLatitude,
double * outLongitude);
/*
* XPLMMapScaleMeter
*
* Returns the number of map units that correspond to a distance of one meter
* at a given set of map coordinates.
*
* Only valid from within a map layer callback (one of
* XPLMMapPrepareCacheCallback_f, XPLMMapDrawingCallback_f,
* XPLMMapIconDrawingCallback_f, or XPLMMapLabelDrawingCallback_f.)
*
*/
XPLM_API float XPLMMapScaleMeter(
XPLMMapProjectionID projection,
float mapX,
float mapY);
/*
* XPLMMapGetNorthHeading
*
* Returns the heading (in degrees clockwise) from the positive Y axis in the
* cartesian mapping coordinate system to true north at the point passed in.
* You can use it as a clockwise rotational offset to align icons and other
* 2-d drawing with true north on the map, compensating for rotations in the
* map due to projection.
*
* Only valid from within a map layer callback (one of
* XPLMMapPrepareCacheCallback_f, XPLMMapDrawingCallback_f,
* XPLMMapIconDrawingCallback_f, or XPLMMapLabelDrawingCallback_f.)
*
*/
XPLM_API float XPLMMapGetNorthHeading(
XPLMMapProjectionID projection,
float mapX,
float mapY);
#endif /* XPLM300 */
#ifdef __cplusplus
}
#endif
#endif