Using a Nasal file with a joystick: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
mNo edit summary
m (Introduction/background info doesn't need a heading)
Line 1: Line 1:
== Background ==
Sometimes the code for a button is quite complicated. Not only does it make your xml file larger and more difficult to go through, but writing the code in a dedicated Nasal file cane be a lot easier. There are things which are just easier that way. You may also have come across an example in the forums which you want to use, and you don't know how to do it.
Sometimes the code for a button is quite complicated. Not only does it make your xml file larger and more difficult to go through, but writing the code in a dedicated Nasal file cane be a lot easier. There are things which are just easier that way. You may also have come across an example in the forums which you want to use, and you don't know how to do it.


Whatever your reason for using a Nasal file, this is how to implement the Nasal file approach. Part 2, expands the idea and shows you just why it is easier.
Whatever your reason for using a Nasal file, this is how to implement the Nasal file approach. Part 2, expands the idea and shows you just why it is easier.


==  Getting Started ==
==  Getting Started ==

Revision as of 00:48, 10 September 2013

Sometimes the code for a button is quite complicated. Not only does it make your xml file larger and more difficult to go through, but writing the code in a dedicated Nasal file cane be a lot easier. There are things which are just easier that way. You may also have come across an example in the forums which you want to use, and you don't know how to do it.

Whatever your reason for using a Nasal file, this is how to implement the Nasal file approach. Part 2, expands the idea and shows you just why it is easier.

Getting Started

You are going to put your Nasal file in the same folder as your joystick's xml file. You need to choose a suitable name for the file. If your joystick is a KungFu ABC123 you could safely name the file abc123.nas. If, however, you have a Saitek yoke, you don't want to name the file yoke.nas, because in the Saitek folder is a Pro Flight Yoke and a Cessna Yoke, so you want to be more specific. Call the file cessnayoke.nas or proflightyoke.nas'

The name you choose is visible everywhere in FG, so make sure you choose something unique.

Notice that there are no capital letters.

So open up your favourite text-editor, create a new file, and save it in your joystick's folder with the chosen filename. Don't forget that the extension must be .nas, and make sure your editor doesn't make it .nas.txt.


Changes to your joystick's xml file

Save a copy of your xml file in a safe place, one that you will remember.

For the sake of this exercise we will assume that you have a KungFu ABC123 joystick. So your nasal file is abc123.nas.

Open the xml file.

At the top, just after all the <name> entries, add this:

  <nasal>
    <script>
      ## begin of custom section
      var modulename = "abc123"; # customize this according to the namespace used
      var module_path = "/Input/Joysticks/KungFu/abc123.nas"; # customize this according to the file name/path
      ## end of custom section

      var is_loaded = func (name) contains(globals,name);

      if (!is_loaded(modulename)) {
        io.load_nasal(getprop("/sim/fg-root") ~ module_path);
      }
  
      abc123.initABC123(); # customize init routine
    </script>
  </nasal>

The if (!contains... bit (if not contains) makes sure that the nas file is loaded only once.

The abc123.initABC123 cals an initialise routine in the nas file. We haven't created it yet. Notice the abc123. This tells FG which nas file to use. The initABC123 is which routine in that nas file to call. The () is because it is a function.

Save your xml file and open the nas file.


Adding routines to the nas file

We have just told the xml file to call initABC123, so we better add it to the nas file.

At the top of the file add

  var initABC123 = func() {
  }

Every new thing in Nasal starts with var. That is followed by its name (initABC123). Then we must assign it to something. In this case it is a function, so we write = func(). If you want to pass a value to the function (we aren't here), you give a name to the value between the brackets, and place the value to pass between the brackets in the xml file. The { and } mark the start and end of the function (what it does.) It doesn't currently do anything, so there is nothing between them.

Now we need to make at least one button call a function in the nas file. Let's assume you have a button labelled D on your joystick. So we will have a function called buttonD. If it is the only red button, you could call the function redButton.

So we add

  var buttonD = func() {
  }

Once again, it doesn't do anything yet.

Save the nas file and open the xml file. Go to where the D button is handled.

Between the <binding> and </binding> we add our call to the nas file. We get

  <binding>
    <command>nasal</command>
    <script>abc123.buttonD()</script>
  </binding>

Now, when button D is pressed, it will call the function buttonD in abc123.nas. You just need to put the correct code in the function.


To make your nas file a bit more use-friendly, open it and at right at the top add

print("Loading abc123.nas");

Now, when you run FG, along with all the other info in the "black window" you will see Loading abc123.nas when the joystick xml file loads. This not only confirms that it has loaded, but if you have a parse error in your nas file it will be reported, and you can fix it.


Notes

This article does not supply any coding for actions, it is just to get you started. A sort of template. See Part 2 for more details.


When naming Nasal functions, the convention is to use camel coding. That is, the first word in the name starts with a lower-case letter, all subsequent words star with an upper-case letter. The can be no spaces in the name. If you want to separate words use an underscore (_).


So valid names would be startDividingByThree, start_Dividing_By_Three, adjRadioFrequency.