Advanced EPL  by    Martin "Pogo" Ingold
6

  Getting started with advanced EPL files 

Now that you've mastered the simple files, you probably want to move on and get the most out of your equipment.

The hardest part is to decide which button should do what. If you got that, the EPL file isn't that hard to do anymore. Let's look at some features you can use for your program.
 

  • Joystickbutton under Windows
  • Pressing a key
  • Keyhits with Control or Shift pressed
  • Using flags
  • The #include command
  • Repeating a buttonpress
  • The Delay command
  • Setmap function
  • Control which buttons to scan
  • Working with Variables

  • Joystickbutton and Windows
    One of the difficulties you may experience is that you don't have a joystickbutton for your Windows calibration routine. What do you do without a joystickbutton? You need one or you won't be able to calibrate your joystick. What you need to do in this case is mapping one of your EPIC buttons to a joystickbutton. In most games is the joystickbutton 0 used for firing your gun or something like this. That's good, because you only have to map your EPIC button as joystickbutton and it will automatically fire your gun (as for example in Falcon4).

    Let's write the code for this:

    :ButtonXXon
    {

    Buttonpress(0)

    }
    :ButtonXXoff
    {
    Buttonrelease(0)

    }
    Definebutton(XX,on,ButtonXXon)
    Definebutton(XX,off,ButtonXXoff)

    That's all you need to do. Now you have a normal joystickbutton which you can use for the calibration process.


    Pressing a key
    What if you want to drop that big, laserguided GBU-24 Paveway bomb? You would have to press the key just at the right moment, when the FCC (Fire Control Computer) would give the releasing impulse. Hmmm....not very neat! Don't worry.... it's much more simple than you might think. EPL has a statement that is called "keypress". When you use this statement in your code, the key is pressed (and will remain so) until you "unpress" it with the "keyrelease" statement. Of course, you can also use this statement to have a "G" instead of a "g". Just remember, you must release the key in your code. In our example, you will have to write a procedure for buttonreleasement.

    Note:

    I'm only writing the changes, not the whole code.
     
    :Releaseordonance
    {

    Keypress(Enter)

    }
    :Releaseoff
    {
    Keyrelease(Enter)

    }

    Definebutton(XX,on,Releaseordonance)
    Definebutton(XX,off,Releaseoff)

    That's it! It's really not very difficult once you understand how EPIC "thinks"


    Typing with Shift or/and Control keys
    If you have different commands at the same key and the only difference between them is that one command is executed with, e.g., a "g" and the other command with "G". To do this is quite easy.

    Let's assume you want to write the word "Good".
     
    :Buttonpress
    {

    Shifthit(G)
    Keyhit(o o d)

    }

    This will be your output:

    Good

    So far so good ;). But what if you want to write "GOOD"? You guessed it, you will have to press (and hold) the Shift-key.
     
    :Holdkey
    {

    keypress(LSHIFT)
    keyhit(G O O D)
    keyrelease(LSHIFT)

    }

    It's easy to do and it is effective. The important part here is that you must release the key! If you forget to release a key, your program is going to react unpredictable and surely not how you want it to.


    Flags
    Flags are very useful if the function of your switch or button is dependant on the setting of another button/switch.

    Example:

    You don't want that your ordonance is released when the Master-arm switch is in the off or simulate position.

    Flags provide an easy way to make this possible. To use flags, you first need to define and initiallize them. The following line defines a flag with the name "Masterarm"

    Flag(Masterarm,false)

    You can either Set or Clear a flag. Obviously, we would use Setflag(Masterarm) Clearflag(Masterarm) in our example.

    The "false" behind the name of the flag simply means that the flag is cleared (or not set). If you write "true", the flag is set. This is one initialization procedure that you can use, or you can use the one in the code below.

    Note:

    If you use this initialization procedure, you don't need to "Clear" the flag with an :init procedure!

    Before you use the flags you defined, you should initialize them. This way, you exactly know the state of each flag when you load your program.

    Let's write the code that does what we just talked about:
     
    #Define FASTSCAN 0
    Definemodule(0,FASTSCAN,0,7)

    Flag(Masterarm)

    :Init
    {

    Clearflag(Masterarm)

    }

    Note:

    The Init procedure is executed each time you load the EPL file into the EPIC buffer. You don't need to do anything specific to have it executed.

    Now we will include this flag into a simple program. We want the code to be the following: If the Master-arm switch is set to "armed", the ordonance will be released. If the Master-arm switch is set to "off" or "simulate" the gear should be extended/retracted (I know I know... this doesn't make any sense, but it's just an example).
     
    #Define FASTSCAN 0 
    Definemodule(0,FASTSCAN,0,7) 
    Flag(Masterarm,false) 
    :Releaseordonance 
    if(Masterarm) 
    Keyhit(Enter) 
    else 
    Keyhit(g) 
    }

    That's it. Simple huh? You should be able to examine the program by yourself and you should understand what the different statements do.


    #Include
    Another nice feature is the #include command. This allows you to put your code into parts, which are easy to overlook. For example, you can write a file for your joystick, one for your output module, one for your MFD buttons..... and so on.

    Then you write a new file in which you combine all these files. The #include command acts as if you would have written the whole code that you include at the place of your #include command. Here's an example of my main EPL file. This makes it easier to track down errors, and gives a better overview.


    Repeating your Buttonpress
    If you constantly want to repeat the character that your button generates while you are pressing it, the EPL compiler know a command called ifactive(). You have to write something like the following:
    :Repeat
    {
    Keyhit(a)
    Delay(100)
    ifactive(1) jump Repeat

    }

    The Delay() command is required. Without it the loop would run too fast and would fill your EPIC buffer in less then 1ms!

    The value between the brackets is multiplied by 20ms, the above example would pause your loop for 2 seconds (2000ms).


    Setmap
    What if your throttle is not recognized by your flightsimulation, despite you calibrated it correctly under Windows? If you encounter this problem, the throttles analog channel isn't identical with the channel that your simulation is checking for throttle inputs. For example, Falcon4 is expecting throttle inputs thru channel 3. While you create your Joystick-configuration (using Joystick.exe) you should make a note which input channels your devices use. My TQS makes its inputs using analog channel 6. If I don't modify this channel, I won't be able to use it in Falcon4. What you need to do is to map your default analog channel to another.

    The following code maps analog channel 6 to analog channel 3:
     
    :init
    {

    Setmap(3,6)

    }

    You should place this statement in the init procedure because you want that the mapping is done when you load your joystickfile.


    Scanning
    If you want to control if a button should perform any action, EPL has two functions that allow you to do that: Enablescan and Disablescan.

    Example:

    You don't want to release chaff or flares when the arm-switch of this panel is in the off position. If you write your code using the common method, your buttons perform its functions when they are pressed, regardless of the position of the arm-switch. We're writing a small code now that keeps your buttons from doing anything when the arm-switch is in the off position.

    We assume that the chaff is no.1, flares no.2 and the arm-switch is wired as button no.3
     
    :init
    {

    Disablescan(1)
    Disablescan(2)

    }
    :Armon
    {
    Enablescan(1)
    Enablescan(2)

    }
    :Armoff
    {
    Disablescan(1)
    Disablescan(2)

    }

    Definebutton(3,on,Armon)
    Definebutton(3,off,Armoff)

    Write a procedure for each button to perform when it becomes active, as you did before.

    If you now press one of the buttons, nothing will happen. But if button 3 is set to on, the :Armon procedure is executed and the buttons become active and perform they're function when they are pressed. If you set the arm switch to off, the buttons are also "turned off".


    Variables
    EPIC provides access to 255 variables. Each variable can hold a value between 0 and 255. Variables are very useful and the best way to explain what they can be used for is when you look at the following example:

    You have a warning light that should illuminate when you are out of Flares. Assume your plane has 25 Flares. How would you get the warning light to illuminate when you're out of flares?

    The easiest way is to work with variables. In the beginning of your code you define a new variable and set it's start value to the number of Flares available. Each time you press the "release-Flare" button, you subtract a value of 1 from your variable. The only thing left for you to do is to check if the variable has yet reached 0.

    We're going to write a code that presses a "g" when you pressed a specific button 3 times.
    Var (ThreeCount,2)
     
    :Buttondown 
    Ifvar(ThreeCount,EQU,0) 
    Keyhit(g) 
    delay(3) 
    Setvar(ThreeCount,2) 
    else 
    Subvar(ThreeCount,1) 
    }

    Definebutton(XX,on,Buttondown)
    If you press the button 3 times, you'll see a "g" appearing on your screen (DOS mode). I think we should take a close look to what we've just written:
     
    Var(ThreeCount,2)

    Here you define a new variable with the name ThreeCount and initialize it with a value of 2. Hmmm.... you might think now that we want to execute the procedure when the button is pressed 3 times, and not only 2 times. You need to know here that the value of the variable is set to 2 when you press it for the first time. So it is 2-1-0 which is 3 buttonpresses.

    Note:

    You should always initiate a new variable with a value, even if it is 0. A variable that is not initialized is a so called "dangerous variable" because you don't know it's value and the computer doesn't know it either. It might be possible that your program does not behave as you want it to, it can even crash your application.
     
    Ifvar(ThreeCount,EQU,0)

    With this statement you check for a specific condition. IF your variable is EQUAL to 0, then

    Keyhit(g)
    Set variablevalue back to 2
    Note to the Ifvar statement:

    Of course, you can do anything you can do with "normal" EPL, for example use the Disable scan function if you want to disable your button here.

    You can check your variable for different conditions, which are listed in the table below:

    What to check 
    Designation 
    Example
    Equal to  EQU  Ifvar(ThreeCount,EQU,0) 
    Not Equal to  NEQ  Ifvar(ThreeCount,NEQ,0) 
    Greater than  GT  Ifvar(ThreeCount,GT,2) 
    Less than  LT  Ifvar(ThreeCount,LT,1) 
    Ok, now we made sure that the button does what we want if the variable has a specific value. But what should EPIC do if the variable doesn't meet the conditions you specified?

    For this case you need an else statement. You can also read it like this:

    If ThreeCount is NOT 0 then (your statement here)

     
    Another table for the calculations you can do using EPL:
    What to do 
    Designation 
    Example
    Assign a new value to your variable  Setvar  Setvar(ThreeCount,2) 
    Add a specific value to the variable  Addvar  Addvar(ThreeCount,5) 
    Subtract a specific value from the variable  Subvar  Subvar(ThreeCount,5) 
    Another note needs to be made here:

    You should not do too many calculations in EPL, as calculations take a long time by EPIC to be done.

    That's all that needs to be said here. I know it's a bit confusing if you work with variables for the first time, but once you understand how to use them they become very useful.
     
     

    Back
    Top