Featured post

February 2022 update: Dynamic data definitions

It’s been a busy month, but mostly in my day job. As you may know, I work as a software architect and developer by day, but that is mostly in Java. (Gasp!) Nevertheless, I did manage to get some important refactoring work done, which was caused by my promise to take a look at my C++ code for generating gauges on the Saitek Flight Instrument Panel. The thing is, data is shown on gauges using scripting, using a stack-oriented language, which is actually used a lot more than you might know. (more later) Lockheed Martin’s Prepar3D added to this the possibility to use LUA, but the important upshot is that you need to parse or even run those scripts to find out which variables you need to ask from the simulator.

I started out with the static alternative, using annotated fields and properties, which CsSiMConnect scans using Reflection. Now we need to be able to add variables “by hand,” which means we can try to find commonality between those two different approaches. The last thing we should do is give up and explicitly expose the convoluted “SimConnect_AddToDataDefinition” approach.

Continue reading
Advertisement

Update: Sending Events and other changes

I have been pretty busy these past days, although admittedly not all on CsSimConnect. That said, there are a number of major changes and additions:

  • Solution structure-wise, I bit the bullet and split off the “InterOp” DLL project. This project kept giving me headaches due to the simulator dependencies, which don’t exist in all the C# projects. There is now a “CsSimConnectInterOp.sln” solution file with a single project. (with the same name) I’ll clean up the original project so we’re back to two configurations: “Debug” and “Release”. The InterOp solution has the full six, two for P3Dv4, P3Dv5, and MSFS 2020 each. The configuration names are re-arranged so their names start with “Debug” or “Release”, because that apparently is something the tools check for.
  • I started a “CsSimConnectUIComponents” project to collect useful UI components and view-models, so eventually only that one and any Windows applications will contain WPF dependencies.
  • Similarly, a new library “SimScanner” will contain everything that has to do with interacting with the installed simulators. If it works as intended, this project will get all remaining Windows dependencies. All other projects should be .Net Core compliant, and as such should be able to run on macOS or Linux. Jim Rees’s (aka Dragonlaird) MSFS SDK would then become relevant to base a new InterOp implementation on. The SimScanner library contains a first implementation of an add-on scanner, and should allow you to e.g. build a list of all installed scenery. A Bgl sub-namespace will get the code to read BGL files so you could do things like building lists of airports or parkings. Another thing I’d like to add here is a scanner for aircraft models.
  • Two small testers: BglReader will open a Bgl file and attempt to read it. It currently is able to read airport ICAO codes. ListAddOns will build a complete list of all addons installed in Prepar3D. From here we can collect all installed Scenery or Aircraft.
  • A working UI app is “AutoPilotController”, which allows you to set some basic auto-pilot things while seeing a list of all aircraft flying. This is targeted at group flights, but was my testcase for sending events.
Continue reading

Dev Update: Choosing and Linking DLLs

On the MSFS 2020 forum site I noticed an interesting discussion in the SDK/SimConnect area, about which SimConnect DLL to use for cross-simulator development. Now I was kind of assuming I would be able to choose one as well but, just like these guys, had to conclude there are issues when you try to use the Prepar3D SimConnect library for MSFS or vice versa. So the discussion also went on about trying to link your application with both, which is not easy, especially if you want to use a managed DLL. (This discussion was about the managed SimConnect API) Microsoft puts everything in the “Microsoft.FlightSimulator” namespace, while Lockheed Martin uses “LockheedMartin.Prepar3D“. If you want to support both, you cannot even use the fact that they have classes and enums with the same layout, and have to resort the that old rule that states you can solve any problem with an extra level of indirection.

Continue reading

Development Update: The Flow of a Data Stream

So yesterday I showed how I want to see data requests from the end-to-end perspective, using “attributes” to decorate a class’ fields with the information needed to send a request. I ended with how this works out at the point of usage. My test UI now contains something like the following:

private void TestGetSimState()
{
    var mgr = RequestManager.Instance;
    log.Info("The simulator is {0}.",
             mgr.RequestSystemState(SystemState.Sim)
                .Get()
                .AsBoolean() ? "Running" : "Stopped");

    AircraftData data = mgr.RequestData<AircraftData>()
                           .Get();
    log.Info("Currently selected aircraft is '{0}'.", data.Title);

    log.Info("Starting stream");
    mgr.RequestData<AircraftData>(ObjectDataPeriod.PerSecond, onlyWhenChanged: true)
       .Subscribe((AircraftData data) => log.Info("[stream] Currently selected aircraft is '{0}'.", data.Title));
}

The first request is one for the SystemState, which tells us if the user is in control of the aircraft or in a UI dialog. The second request uses the annotated AircraftData class to request the currently selected aircraft, but the third is new. The third asks for the aircraft information every second, but only if it changed. This results in a stream, and we subscribe a lambda to it to tell us every time the user changes the aircraft, and what the new choice is.

Continue reading

Starting a new (and improved)SimConnect ClassLibrary for .Net

Hi!

I have been experimenting with SimConnect for quite a while now, mostly in C++, first with FSX, then a lot more with Prepar3D. However, the API is kind of stuck in C era conventions. Using inheritance on structs and references instead of pointers won’t get you out of things like DWORDSABYSMAL_ALL_UPPERCASE constants, and Hungarian notation (for those who don’t know that term: it means you prefix identifiers with mangled types, like “lpsz” and “dw”) which was very helpful when IDEs weren’t there to tell you what an identifier is for. The extensive use of pointers and unsafe types is also a definite worry. These problems were solved and given better alternatives a long time ago, so time to move on.

Continue reading