WASM GAUGES

WASM (C/C++) gauges can be developed for Microsoft Flight Simulator with the Microsoft Flight Simulator Platform Toolset which is installed at the same time as the SDK itself (see the Additional Tools and Web Assembly pages for more information). In this short tutorial we'll quickly take you through the main steps required to create a WASM module to be used as part of the instrumentation of an aircraft.

 

 

Creating A New Gauge For Your Project

The Microsoft Flight Simulator SDK includes a number of templates that you can - and should - use to create your WASM modules. You can get these by starting Visual Studio, selecting Create A New Project, and on the templates screen search for MSFS:

 

The three available templates are:

  • MSFS WASM Gauge Demo: This template contains three demo gauges using a minimum of code. This is the same sample that was used for the GaugeAircraft Sample Project.
  • MSFS WASM Module: This is the base template that should be used in the creation of all WASM gauges.
  • MSFS WASM Static Library: This is a template that can be used to create a WASM static library for future WASM modules to link to.

 

After selecting the MSFS WASM Module template, you will be presented with the following basic project, which we'll be editing:

#include <stdio.h>
#include "[MODULE_NAME]_Module.h"
extern "C" MODULE_EXPORT void test(void)
{
	// TODO
}

 

Visual Studio Project Properties

The VS Properties Window For A WASM Module

When creating your WASM projects, most of the project settings will be the same as for a standard C++ project, however there are some things that should be set up with specific values, which we'll outline here:

 

  • Configuration Properties: These can be left with their default values.
  • C/C++: In this section you have the following properties which may need editing:
    • General - Debug Information Format: This must be set as //clang:-g. It should be set automatically, but it is worth checking.
    • General - Warning Level: Set this field to Level 3, and check your warning regularly, as clang will tell you if you do something wrong.
    • General - Multi-processor Compilation: Use this field to speed up your compilation time.
      VS Properties Multi Processor Compilation Settings
    • Optimization: When debugging you should set everything to false/disabled/no. For release, we recommend that you set Optimization at Maximum Optimization (Favor Speed) (/O2). Note that with the latest SDK update, we automatically optimize modules which have a value in Optimization field (/clang:-O3), and no optimization means it is debuggable. The others fields can also be set as you require.
  • Linker: In the Debugging section you want to set it to "Generate Debug Info (/DEBUG)" when you are testing and debugging the module, but then for release, set it to "No".

 

 

Editing The WASM Module Project

Now you've initialised the new WASM project and setup Visual Studio, you'll need to edit the source code to include the minimum header files - supplied by the SDK - to create the module. You can find all the available files that can be included from the following SDK location: 

<root>\MSFS SDK\WASM\include\MSFS

Location Of The MSFS.h File

These different API's are all documented here:

 

The following API's are the bare minimum that you will normally want to include when creating a new gauge:

#include <MSFS/MSFS.h>
#include <MSFS/MSFS_Core.h>
#include <MSFS/MSFS_Render.h>
#include <MSFS/Legacy/gauges.h>

 

After setting the includes, you can then create a callback for your gauge as follows:

extern "C" {
    MSFS_CALLBACK bool [MODULE_NAME]_gauge_callback(FsContext ctx, int service_id, void* pData)
    {
        switch (service_id)
        {
            // further code here ...
        }
        return false;
    }
}

 

 

Adding The Gauge To Your Aircraft

Once you have created the gauge, you need to be able to add it to your aircraft and to test it. This means that you should already have created an aircraft package (as explained here: Creating The Project), and after building the WASM module from Visual Studio, you will want to save it beside the panel.cfg file in the PackageSources directory, as shown in the following image taken from the Gauge Aircraft Sample:

The Location For Saving The WASM Module

Once you have built the module and saved it to the appropriate location, you need to tell the aircraft to reference it. This is done in the panel.cfg, under the  [VCockpitN] header, something like this:

[VCockpit01]
size_mm=1024,768
pixel_size=1024,768
texture=TEXTURE
background_color=0,0,255
htmlgauge00=WasmInstrument/WasmInstrument.html?wasm_module=<MODULENAME>.wasm&wasm_gauge=<GAUGENAME>, 0, 0, 1024, 768, <OPTIONAL PARAMETER STRING>

The important thing to note here is that all WASM modules will need a [VCockpitN] definition, and the path (defined by the htmlgauge00 parameter) will always take the same prefixed format:

WasmInstrument/WasmInstrument.html?wasm_module=

 

When you have the file in the correct location, you can go ahead and build the package (as explained here). Once built, you will need to restart the flight to see the module in the simulation. Note that this is the case for every edition you make to the WASM code - afterwards it will need exported, built, and the flight restarted.

 

 

Events Received By The Gauge Callback

Once the gauge has been loaded by Microsoft Flight Simulator, the following events are sent to the callback function so they can be intercepted and acted on (if required):

 

  • PANEL_SERVICE_PRE_INSTALL: sent before the gauge is installed. The pData parameter points to a sGaugeInstallData structure:
    • The iSizeX member gives the width of the gauge bitmap.
    • The iSizeY member gives the height of the gauge bitmap.
    • The strParameters member gives the optional parameter string.
  • PANEL_SERVICE_POST_INSTALL: sent after the gauge has been installed. The pData parameter points to a sGaugePostInstallData structure:
    • The ctx member is a pointer to the FsContext used by the gauge (it is the same as the ctx parameter provided to the callback function).
  • PANEL_SERVICE_PRE_INITIALIZE: sent before the gauge is initialized. The pData parameter is null.
  • PANEL_SERVICE_POST_INITIALIZE: sent after the gauge has been initialized. The pData parameter is null.
  • PANEL_SERVICE_PRE_UPDATE: sent before the gauge is updated. The pData parameter is null.
  • PANEL_SERVICE_POST_UPDATE: sent after the gauge has been updated. The pData parameter is null.
  • PANEL_SERVICE_PRE_DRAW: sent before the gauge is drawn. The pData parameter points to a sGaugeDrawData structure:
    • The mx member gives the X-coordinate of the mouse in texture space.
    • The my member gives the Y-coordinate of the mouse in texture space.
    • The t member gives the absolute simulation time.
    • The dt member gives the time elapsed since last frame.
    • The winWidth member gives the width of the gauge bitmap.
    • The winHeight member gives the height of the gauge bitmap.
    • The fbWidth member gives the width of the gauge bitmap.
    • The fbHeight member gives the height of the gauge bitmap.
  • PANEL_SERVICE_POST_DRAW: sent after the gauge has been drawn. The pData parameter points to a sGaugeDrawData structure (see above).
  • PANEL_SERVICE_PRE_KILL: sent before the gauge is deleted. The pData parameter is null.
  • PANEL_SERVICE_POST_KILL: sent after the gauge has been deleted. The pData parameter is null.

 

 

Handling Mouse Events

It may be that you also need your gauge to deal with the input from users, and in this case you will need to add in mouse events. Mouse events are forwarded to your gauge through a mouse callback that is defined as follows:

extern "C" {
    MSFS_CALLBACK void <GAUGENAME>_mouse_callback(float fX, float fY, unsigned int iFlags)
    {
        ...
    }
}

 

The parameters in this callback are as follows:

  • The fX parameter gives the X-coordinate of the mouse in texture space.
  • The fY parameter gives the Y-coordinate of the mouse in texture space.
  • The iFlags parameter is a combination of the various MOUSE_* flags defined in gauges.h. Supported flags are:
    • MOUSE_MOVE: the mouse cursor has moved.
    • MOUSE_LEFTDRAG: left button down.
    • MOUSE_RIGHTDRAG: right button down.
    • MOUSE_MIDDLEDRAG: middle button down.
    • MOUSE_LEFTRELEASE: left button up.
    • MOUSE_RIGHTRELEASE: right button up.
    • MOUSE_MIDDLERELEASE: middle button up.
    • MOUSE_LEFTSINGLE: left button click (sent after a down/up sequence).
    • MOUSE_RIGHTSINGLE: right button click (sent after a down/up sequence).
    • MOUSE_MIDDLESINGLE: middle button click (sent after a down/up sequence).
    • MOUSE_LEFTDOUBLE: left button click (sent after two consecutive clicks).
    • MOUSE_MIDDLEDOUBLE: middle button click (sent after two consecutive clicks).
    • MOUSE_WHEEL_UP: wheel moved up.
    • MOUSE_WHEEL_DOWN: wheel moved down.

 

 

Debugging

It's inevitable that while you build and test your WASM module, you will encounter bugs that you will need to fix. The list below outlines the basic steps that you need to be able to follow to correctly debug things:

  • Open your project in Visual Studio.
  • Build it and copy the WebAssembly module to the panel folder of your SimObject.
  • Launch Microsoft Flight Simulator.
  • When the game is running, use the Debug > Attach to process command of Visual Studio.
  • In the processes list, select Microsoft Flight Simulator.exe and press the Attach button.
  • Once in the main menu, open your project.
  • Build the package.
  • Launch a flight with your SimObject.
  • Once the game has loaded your SimObject, the breakpoints set in the project become active and you can step into your code.

 

Please also see the section on Known Issues And Limitations for further information to help with debugging.