~alexandre-hardy/linuxjoymap/linuxjoymap

« back to all changes in this revision

Viewing changes to doc/program.tex

  • Committer: Alexandre Hardy
  • Date: 2009-07-17 09:20:57 UTC
  • Revision ID: ah@zenwalk-20090717092057-oxa4o16isawqa7ue
Initial creation of project

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
\documentclass{article}
 
2
\def\pipe{$|$}
 
3
\title{Joystick Mapper for Linux -- Programming Guide}
 
4
\author{Alexandre Hardy}
 
5
\parindent=0cm
 
6
\begin{document}
 
7
\maketitle
 
8
This document describes programming language used by the
 
9
joystick mapping software. The driver creates a new joystick
 
10
device that can be mapped with the normal joystick mapping
 
11
software. To use the programming language effectively
 
12
the virtual joystick device must be mapped to some joystick
 
13
button or axis. The virtual joystick device is indicated
 
14
by a vendor id of {\tt 0x00ff} and a product id of {\tt 0x0000}.\\
 
15
 
 
16
At each execution cycle, the program is executed from the
 
17
beginning until termination (in sequence) or a maximum number of instructions
 
18
has been executed (to prevent the driver from looping indefinitely).
 
19
The exception to this rule is {\tt threads} described in
 
20
section \ref{sec:thread}.\\
 
21
 
 
22
Comments are indicated by a hash (\#) and continue to the end of the line.
 
23
 
 
24
We now describe the basic components of a program.
 
25
 
 
26
\section{Variables}
 
27
All variables in the programming language are 32-bit integers.
 
28
These variables can be used to store results from calculations
 
29
and can represent button values or axis values. A new variable 
 
30
is declared with the {\tt var} statement:
 
31
\begin{center}
 
32
        {\tt var} {\it variable\_name};
 
33
\end{center}
 
34
where {\it variable\_name} is any identifier that begins with a letter
 
35
followed by letters, digits or the underscore. Variable names
 
36
are case-sensitive. These variables can be used for any purpose.
 
37
Variables are allocated to registers in the virtual machine. Since
 
38
there are 256 such registers, only 256 variables can be declared
 
39
in addition to the predefined variables.\\
 
40
 
 
41
Arrays can be declared as follows
 
42
\begin{center}
 
43
        {\tt var} {\it variable\_name}{\tt [{\it constant}]};
 
44
\end{center}
 
45
The size of the array must be constant. Each element of the array
 
46
is assigned to one register. Registers can be used up very 
 
47
quickly by declaring arrays! Arrays are 0 based, that is the
 
48
first index of any array is 0.\\
 
49
 
 
50
There are a few predefined variables that have a special meaning. These
 
51
variables are described in the following sections.
 
52
 
 
53
\subsection{{\tt firstscan}}
 
54
The {\tt firstscan} variable is set to 1 if this is the
 
55
first time the program is executed, and 0 otherwise. This
 
56
variable can be used to decide when to initialize program
 
57
variables.
 
58
 
 
59
\subsection{{\tt clocktick}}
 
60
The {\tt clocktick} variable is set to 1 if the program
 
61
is executed as a result of a timer event, or 0 if the
 
62
program is executed due to some other event (such as
 
63
a joystick button being pressed).
 
64
 
 
65
\subsection{{\tt timestamp}}
 
66
\label{sec:timestamp}
 
67
The {\tt timestamp} variable indicates the time since first
 
68
execution of the script measured in milliseconds. This variable can be used to
 
69
queue statements based on time. Examples of use include
 
70
the {\tt delay} statement (section \ref{sec:delay}).
 
71
 
 
72
\subsection{{\tt currentmode}}
 
73
The {\tt currentmode} variable is defined by the
 
74
program to provide state referring to a mode of
 
75
operation. The variable is completely controlled
 
76
by the user and may be used for any purpose.
 
77
Unlike general variables, this variable is
 
78
accessible from all {\tt threads} (see section \ref{sec:thread}).
 
79
 
 
80
\subsection{{\tt js}}
 
81
The {\tt js} variables give access to the current state of
 
82
joysticks attached to the system. There are 16 {\tt js}
 
83
variables, namely {\tt js0} through {\tt js15} that
 
84
provide access to a maximum of 16 joysticks. The joysticks
 
85
are numbered according to the specification in the
 
86
current mapping configuration file. That is, the joystick
 
87
numbers are explicitly assigned when the joystick is
 
88
mapped. Each {\tt js} variable has two fields:
 
89
\begin{itemize}
 
90
        \item An {\tt a} field that is an array of integers.
 
91
                Each element provides the current position
 
92
                of that axis of that joystick.
 
93
                For example {\tt js0.a[1]}, refers to
 
94
                the second axis of the joystick designated
 
95
                as 0~in the configuration file.
 
96
        \item A {\tt b} field that is an array of integers.
 
97
                Each element provides the current button status 
 
98
                of that button of that joystick.
 
99
                For example {\tt js1.b[3]}, refers to
 
100
                the fourth button of the joystick designated
 
101
                as 1~in the configuration file. The value is
 
102
                1 for a depressed button and 0 otherwise.
 
103
\end{itemize}
 
104
 
 
105
\subsection{{\tt a}}
 
106
The variable {\tt a} is an array of integers specifying the
 
107
position of the virtual axis of the virtual joystick 
 
108
created by the program. For example the
 
109
statement
 
110
\begin{center}
 
111
        {\tt a[1]=10;}
 
112
\end{center}
 
113
reports that the second axis of the virtual program joystick
 
114
is in position 10. The variable may also be read.
 
115
 
 
116
\subsection{{\tt b}}
 
117
The {\tt b} variable is an array of integers indicating
 
118
whether a virtual button on the virtual program joystick 
 
119
is depressed or not. For example, to indicate that
 
120
the first button on the virtual joystick is
 
121
depressed, we write
 
122
\begin{center}
 
123
        {\tt b[0]=1;}
 
124
\end{center}
 
125
and to indicate (at a later time) that the button is released
 
126
we write
 
127
\begin{center}
 
128
        {\tt b[0]=0;}
 
129
\end{center}
 
130
This variable may also be read.
 
131
 
 
132
\section{Operators}
 
133
Operators are used to build expressions 
 
134
to perform some calculation. The operators
 
135
are very similar to C operators with some
 
136
minor differences. Operators take constants,
 
137
variables, array elements or other expressions as parameters.
 
138
\subsection{Arithmetic operators}
 
139
The arithmetic operators are as follows:
 
140
\begin{itemize}
 
141
        \item Unary +, eg. $+v$.
 
142
        \item Unary -, eg. $-v$.
 
143
        \item Binary + eg. $v_1+v_2$.
 
144
        \item Binary - eg. $v_1+v_2$.
 
145
        \item Binary $\ast$ eg. $v_1\ast v_2$.
 
146
        \item Binary / -- integer division. eg. $v_1/v_2$.
 
147
        \item Binary \% -- integer remainder. eg. $v_1\%v_2$.
 
148
                This function is not implemented with
 
149
                primitive instructions and is implemented as
 
150
                $a\%b=a-(a/b)\ast b$.
 
151
\end{itemize}
 
152
 
 
153
\subsection{Boolean operators}
 
154
Boolean operators allow certain conditions to be tested.
 
155
The result is an integer indicating the truth of the
 
156
statement. 0 is taken to mean {\it false}, and anything
 
157
else is taken to mean {\it true}. Thus integer values (variables,
 
158
results from a calculation) are also boolean values.
 
159
\begin{itemize}
 
160
        \item {\tt a==b}: true if integer {\tt a} is equal to integer {\tt b}, false otherwise.
 
161
        \item {\tt a!=b}: true if integer {\tt a} is NOT equal to integer {\tt b}, false otherwise.
 
162
        \item {\tt a<b}: true if integer {\tt a} is less than integer {\tt b}, false otherwise.
 
163
        \item {\tt a>b}: true if integer {\tt a} is greater than integer {\tt b}, false otherwise.
 
164
        \item {\tt a<=b}: true if integer {\tt a} is less than or equal to integer {\tt b}, false otherwise.
 
165
        \item {\tt a>=b}: true if integer {\tt a} is greater than or equal to integer {\tt b}, false otherwise.
 
166
        \item {\tt a\&\&b}: true if {\tt a} is true and {\tt b} is true, false otherwise.
 
167
        \item {\tt a\pipe\pipe b}: true if {\tt a} is true or {\tt b} is true, false otherwise.
 
168
        \item {\tt !a}: true if {\tt a} is false, false otherwise.
 
169
\end{itemize}
 
170
\subsection{Precedence}
 
171
Unary operators have the highest precedence. 
 
172
The precedence of binary operators is similar to C.
 
173
The precedence from highest to lowest is:
 
174
\begin{itemize}
 
175
        \item \&\& and  \pipe\pipe
 
176
        \item $\ast$, / and \%
 
177
        \item + and -
 
178
        \item {\tt ==, !=, <=, >=, <}  and {\tt >}
 
179
\end{itemize}
 
180
 
 
181
\section{Program statements}
 
182
All statements are terminated by a semi-colon, except the
 
183
statement block.
 
184
\subsection{Assignment}
 
185
Assignment is the most commonly used statement.
 
186
An example of assignment is 
 
187
\begin{center}
 
188
        {\tt currentmode=1;}
 
189
\end{center}
 
190
This sets the variable currentmode to have the value 1. Be careful
 
191
not to confuse the assignment operator = with the boolean equality 
 
192
test ==.
 
193
A few shorthand notations exist for some common assignment operations:
 
194
\begin{itemize}
 
195
        \item {\tt a++} $\rightarrow$ {\tt a=a+1;}
 
196
        \item {\tt a--} $\rightarrow$ {\tt a=a-1;}
 
197
        \item {\tt a+=b} $\rightarrow$ {\tt a=a+b;}
 
198
        \item {\tt a-=b} $\rightarrow$ {\tt a=a-b;}
 
199
        \item {\tt a*=b} $\rightarrow$ {\tt a=a*b;}
 
200
        \item {\tt a/=b} $\rightarrow$ {\tt a=a/b;}
 
201
\end{itemize}
 
202
\subsection{Statement blocks}
 
203
If several statements need to be combined into a unit,
 
204
a statement block can be created as follows:
 
205
\begin{center}
 
206
        \parbox{5cm}{
 
207
        {\tt \{\\
 
208
                \strut\ \ \ \ $statement_1$;\\
 
209
                \strut\ \ \ \ $statement_2$;\\
 
210
                \strut\ \ \ \ $statement_3$;\\
 
211
                \strut\ \ \ \ \vdots\\
 
212
                \strut\ \ \ \ $statement_n$;\\
 
213
        \} }
 
214
        }
 
215
\end{center}
 
216
\subsection{{\tt if}}
 
217
An {\tt if} statement has the form
 
218
\begin{center}
 
219
        {\tt if ({\it condition}) {\it statement}}
 
220
\end{center}
 
221
If the {\it statement} is a simple statement, then it is terminated
 
222
by a semi-colon. If it is a block statement, then no semi-colon 
 
223
is necessary.\\
 
224
 
 
225
If the expression {\it condition} evaluates to 0 then the
 
226
{\it statement} is not executed, otherwise the {\it statement}
 
227
is executed. It is also possible to specify to alternatives
 
228
as in
 
229
\begin{center}
 
230
        {\tt if ({\it condition}) {$statement_1$}} else $statement_2$
 
231
\end{center}
 
232
where $statement_2$ is executed if {\it condition} evaluates
 
233
to 0, otherwise $statement_1$ is executed.
 
234
 
 
235
\subsection{{\tt while}}
 
236
A {\tt while} loop has the form
 
237
\begin{center}
 
238
        {\tt while ({\it condition}) {\it statement};}
 
239
\end{center}
 
240
As long as {\it condition} evaluates to a non-zero value
 
241
{\it statement} will be executed. The {\it condition}
 
242
is evaluated before the {\it statement} is executed
 
243
and is tested directly before the first (possible)
 
244
execution, and directly after execution of {\it statement}.
 
245
If {\it condition} evaluates to 0, then the loop
 
246
is terminated.
 
247
\subsection{{\tt signal}}
 
248
The {\tt signal} statement has the form
 
249
\begin{center}
 
250
        {\tt signal({\it expression});}
 
251
\end{center}
 
252
This statement sends the result of expression
 
253
to the mapper device (the device used to program the joystick)
 
254
to be relayed to a client program. This can be
 
255
used to trigger events outside of the kernel
 
256
space. For example, the joystick could
 
257
be reprogrammed by the client program based
 
258
on the signal sent, or a particular program such
 
259
as an e-mail client or multimedia player could be executed.
 
260
\subsection{{\tt press}}
 
261
The {\tt press} statement allows keypresses to be sent
 
262
directly to the driver. {\tt press} has
 
263
the form
 
264
\begin{center}
 
265
        {\tt press("{\it key}");}
 
266
\end{center}
 
267
where {\it key} is one of the constants listed in {\tt keys.txt}.
 
268
{\tt press} sends a key pressed event to the driver.
 
269
\subsection{{\tt release}}
 
270
The {\tt release} statement allows key release events to be sent
 
271
directly to the driver. {\tt release} has
 
272
the form
 
273
\begin{center}
 
274
        {\tt release("{\it key}");}
 
275
\end{center}
 
276
where {\it key} is one of the constants listed in {\tt keys.txt}.
 
277
{\tt release} sends a key released event to the driver.
 
278
\subsection{{\tt thread}}
 
279
\label{sec:thread}
 
280
{\tt Threads} are threads of execution in the sense that each thread
 
281
will remember which statement was executing during the last execution
 
282
of this thread. Thus threads maintain state information in terms
 
283
of an instruction pointer and a collection of registers. {\tt Threads}
 
284
do not imply concurrent execution in any way whatsoever! The {\tt thread}
 
285
statement declares a thread with independent state, as well as
 
286
indicating that the thread must be executed at this point. The
 
287
main program will stop executing until execution of this thread completes
 
288
or the thread yields. If the thread halts, then the state information
 
289
of the thread is reset. If the thread yields, then the thread will
 
290
stop execution and save the instruction pointer so that the 
 
291
thread can be resumed later. The first time the thread is executed (or after 
 
292
the last halt), the current registers are stored in the state
 
293
of the thread and the instruction pointer is set to the
 
294
first instruction (statement) of the thread. Thereafter (until the next halt), the thread will use
 
295
its own copy of the registers (except for special registers such as {\tt timestamp}
 
296
and {\tt currentmode}). If the thread was not halted, then the instruction
 
297
pointer will be used to resume execution of the thread.\\
 
298
 
 
299
The thread statement has the form
 
300
\begin{center}
 
301
        {\tt thread statements;}
 
302
\end{center}
 
303
The statement declares a new thread to the compiler. The compiler will also 
 
304
generate instructions to begin execution of the thread (suspending execution
 
305
of the main program until the thread has halted or yielded).
 
306
Each thread is allocated a unique thread number. The maximum number of threads
 
307
in a program is 8. However, an alternative declaration
 
308
\begin{center}
 
309
        {\tt thread {\it name} statements;}
 
310
\end{center}
 
311
can be used to provide a specific name to a thread. All threads in the
 
312
program with the same name will share the same thread number, thus increasing
 
313
the potential number of threads. If there are two or more such threads, then
 
314
the programmer is declaring to the compiler that only one such
 
315
thread will NOT be in the halted state at any time.
 
316
\subsection{{\tt delay}}
 
317
\label{sec:delay}
 
318
The {\tt delay} statement is only valid within a
 
319
{\tt thread} statement. The {\tt delay} statement has the form
 
320
\begin{center}
 
321
        {\tt delay({\it expression});}
 
322
\end{center}
 
323
This statement will delay the executing {\tt thread} {\it expression} milliseconds 
 
324
(see {\tt timestamp} in section \ref{sec:timestamp}). The mechanism used
 
325
to delay this period of time is a check of the amount of time delayed so
 
326
far, followed by a yield if the required time has not elapsed.
 
327
The thread will resume execution at this statement the next time
 
328
it is executed if the required time has not elapsed. Note that
 
329
the expression is reevaluated every time the delay is checked.
 
330
 
 
331
\subsection{{\tt wait}}
 
332
The {\tt wait} statement is only valid within a
 
333
{\tt thread} statement. The {\tt wait} statement has
 
334
the form 
 
335
\begin{center}
 
336
        {\tt wait({\it condition});}
 
337
\end{center}
 
338
This statement halts the executing thread until {\it condition} becomes
 
339
true (that is non-zero). The {\tt wait} statement is implemented
 
340
by a yield if {\it condition} is false, which returns control to the
 
341
calling thread. The thread will resume execution at this statement
 
342
the next time it is executed.
 
343
 
 
344
\subsection{{\tt halt}}
 
345
The halt statement has the form
 
346
\begin{center}
 
347
        {\tt halt;}
 
348
\end{center}
 
349
and halts execution of the current thread or the main program.
 
350
Every program must halt. The compiler automatically adds a {\tt halt}
 
351
statement to the end of any program to ensure that the
 
352
program will halt.\\
 
353
 
 
354
It is also possible to halt a specific thread (possibly different to the current one) with
 
355
the statement
 
356
\begin{center}
 
357
        {\tt halt {\it name};}
 
358
\end{center}
 
359
\section{Examples}
 
360
A few examples of programs are presented in this section.
 
361
In most of the examples it is necessary to provide a mapping
 
362
from the virtual joystick to a real joystick, or keyboard events.
 
363
\subsection{Toe Brakes}
 
364
Some flight simulators support toe brakes in the form of buttons
 
365
or keypresses, but do not support an axis for toe brakes. If this
 
366
is the case, we can use the toe brake axis on a set of rudder pedals
 
367
to simulate joystick button or key pressed. Assume that the
 
368
rudder pedals have been designated as joystick 2, and that the
 
369
toe brake axes are axes 0 and 1. The program to convert the
 
370
axis positions to button presses is:
 
371
\begin{verbatim}
 
372
     b[0]=(js2.a[0]>128);
 
373
     b[1]=(js2.a[1]>128);
 
374
\end{verbatim}
 
375
Remember that {\tt b} is the array of buttons for the
 
376
virtual joystick, and that boolean and integer expressions
 
377
are interchangeable. The typical range for any axis is 0--255,
 
378
hence the choice of comparison to 128.
 
379
The program's virtual joystick buttons should then be mapped
 
380
to real joystick buttons, or to key presses.
 
381
 
 
382
\subsection{Car Accelerator and Brakes}
 
383
Most rudder pedals have to separate axes for the left and
 
384
right toe brake, but car simulators tend to use only one joystick 
 
385
axis for both acceleration and braking. Assume the same setup
 
386
as above with axis 0 to be used for the brake, and
 
387
axis 1 to be used for the accelerator. The two axes can be mapped
 
388
to one axis with the program 
 
389
\begin{verbatim}
 
390
     var val; 
 
391
     #get a positive value for acceleration
 
392
     # >128 indicates acceleration
 
393
     val=js2.a[1]/2+128;     
 
394
     #produce a braking value
 
395
     # <128 indicates brakes
 
396
     # we need to reverse the sense of the axis
 
397
     val-=js2.a[0]/2;     
 
398
     a[0]=val;
 
399
     #note that accelerating and braking at 
 
400
     # the same time results in no action
 
401
     # but cannot be resolved here
 
402
\end{verbatim}
 
403
\subsection{Delayed Release of Countermeasures}
 
404
In modern combat flight simulators it is necessary to 
 
405
drop countermeasures such as flares or chaff to confuse
 
406
the seeker heads of missiles launched at the aircraft.
 
407
In such a situation it is standard practice to
 
408
release several countermeasures with a delay between
 
409
the release of each one. A thread should be used to
 
410
achieve this, so that other conditions may be checked
 
411
and other actions followed despite the presence
 
412
of countermeasures.
 
413
\begin{verbatim}
 
414
     var i;
 
415
     thread {
 
416
          if (js0.b[5]) {
 
417
               i=5;
 
418
               while (i>0) {
 
419
                    b[0]=1;
 
420
                    delay(2);
 
421
                    b[0]=0;
 
422
                    delay(2000);
 
423
                    i--;
 
424
               }
 
425
          }
 
426
     }
 
427
\end{verbatim}
 
428
This code will trigger the release of 5 countermeasures 
 
429
with a delay of 2 seconds between each countermeasure. Countermeasures
 
430
will be launched as soon as button number 5 of joystick 0
 
431
is pressed. They will continue to be launched even if the
 
432
button is immediately released.
 
433
 
 
434
\subsection{Trimming}
 
435
It is sometimes necessary to trim the controls of an aircraft
 
436
so that straight and level flight can be maintained with
 
437
the joystick in a central position. The trim position may
 
438
change due to changes in air speed or other factors.
 
439
The program below trims the joystick according to the current
 
440
joystick position.
 
441
\begin{verbatim}
 
442
     var trimx;
 
443
     var trimy;
 
444
     # the original values of trimx and trimy
 
445
     var ox, oy;
 
446
     if (firstscan) {
 
447
          #center position is zero
 
448
          trimx=128;
 
449
          trimy=128;
 
450
          ox=128;
 
451
          oy=128;
 
452
     }
 
453
     #check for trimming button pressed
 
454
     if (js0.b[5]) {
 
455
          trimx=128-js0.a[0]+ox;
 
456
          trimy=128-js0.a[1]+oy;
 
457
     } else {
 
458
          ox=trimx;
 
459
          oy=trimy;
 
460
     }
 
461
     #check for reset button pressed
 
462
     if (js0.b[6]) {
 
463
          #reset center position is zero
 
464
          trimx=128;
 
465
          trimy=128;
 
466
          ox=128;
 
467
          oy=128;
 
468
     } 
 
469
     a[0]=js0.a[0]-trimx+128;
 
470
     a[1]=js0.a[1]-trimy+128;
 
471
\end{verbatim}
 
472
 
 
473
\subsection{Waiting for Release of a Button}
 
474
Assume you want to launch exactly one missile
 
475
with a button press, and the simulation software
 
476
launches missiles in sequence according to
 
477
whether the button is depressed or not.
 
478
\begin{verbatim}
 
479
     thread {
 
480
          #wait for first press of the button
 
481
          wait(js0.b[1]);
 
482
          #wait for release 
 
483
          wait(!js0.b[1]);
 
484
          #press virtual button
 
485
          b[0]=1;
 
486
          #and release after 1 second
 
487
          delay(1000);
 
488
          b[0]=0;
 
489
     }
 
490
\end{verbatim}
 
491
Due to the input driver system it should be possible
 
492
to omit the delay, both the press and release should
 
493
be reported. However, the simulation software
 
494
may not work in entirely the same way. 
 
495
 
 
496
\end{document}