Cual - Cuyo Animation Language
==============================

Cual is the main language used to describe the animations in cuyo. It's
the stuff between the << >> brackets in the xxx.ld files.



How it works
------------

Each blob has its own "program" which does the drawing and the
animation stuff. The program code of every blob of one kind is the
same, but each blob has its own instance of the program (that is, own
variables).

A simple blob program consists of one (main) procedure, which is executed
once in each game step and which is responsible for drawing the blob.
(There are 10 game steps per second.) The program has to draw the blob each
time, even if nothing has changed. (However, there's an internal routine
which checks if the same is drawn as in the last step and which then
supresses the drawing.)

There may be other procedures associated to a kind of blob, which are
executed at special events, for example when a falling blob lands.
In contrast to the main program, these event handlers are not allowed to
draw anything. See section "event handlers" for a list of existing events.

The name of the main procedure is the name of the kind of the blob. Normally,
that name is the word listed after "pics="; but if that "word" contains a dot, only the part before the dot makes up the name. (E. g. with "pics=redblob.xpm,greenblob.xpm", the names are "redblob" and "greenblob".)

The name of an event handler procedure is the name of the kind, followed
by a dot, followed by the event name. (E.g. "redblob.land" for the landing
event of the redblob from above.)




Definitions
-----------

Between the << >>, a list of definitions of variables and procedures is expected:

<procname> = <code> ;      Defines a "procedure".

var <varname1> = <def1>, <varname2> = <def2>, ... ;
                           Defines variables with default values.
                           The default value can be omitted (together
                           with the "=" before it). Then, the default
                           value is zero. The default value is not only
                           the value of the variable at the beginning;
                           See section about variables and constants.


Code
----

A code fragment can be one of the following:
  { <code>; <code>; ...}   Executes one command after the other
  <code>, <code>, ...      This is useful for simple animations.
                           Executes exactly one of the commands:
                           In the n-th call, the n-th command is
                           executed. When the last command has been
                           executed, the next time the first one is
                           executed again. However, if one of the
                           commands is "busy" (see section about
                           busieness), this one will be executed until
                           it stops being busy, and only after that,
                           the next command will be executed.
  <procname>               Executes procname
  busy                     Does nothing except being busy. (See section
                           busieness.)
  <varname> = <expr>       Sets the variable. See section "Variables
                           and constants" for details.
  The same with +=, -=, *=, /=, %=  Does the expected thing.
  [ <varname> = <expr> ] <code>     Sets the variable, executes <code>
                                    and resets the variable to the old
                                    value.
  <number>                 Set the Variable file to that number. (You
                           could also write "file = <number>" instead.)
  <letter>                 Set the Variable pos to n, where n is:
                           A: 0, B: 1, ..., Z: 25, a: 26, ..., z: 51
                           (The same as "pos = <number>".)
  *                        Draw the icon specified by the variables
                           file and pos. May also draw only a part
                           of the icon, if specified by the variable qu
                           (see section about variables and constants).
  switch {
    <expr1> <arrow> <code1> ;
    <expr2> <arrow> <code2> ;
    ...
  }                        If you use "->" as arrows, it does the same
                           as the following c code:
                             if (<expr1>) code1;
                             else if (<expr2>) code2;
                             ...
                           The last <expr> may be omitted to get an
                           else part without further condition.
                           Instead of the "->" arrow, you can also use
                           "=>". Once the code after such an arrow is
                           executed, it will be executed every subsequent
                           time without testing any of the condition
                           expressions, as long as it is "busy". More
                           details see below.
  bonus(<expr>)            The player get <expr> bonus points.
  message(<String>)        The string is displayed (blinking) on the players#
                           side. To be used together with bonus(...).
  

There's a shortcut for drawing: You may omit the ";" between
a number, a letter and the "*".


Expressions
-----------

The only data type in cual is int. Bools are represented by 0 and 1,
like in c. (And any number other than 0 is interpreted as true, if
a boolean is expected.)

Of course, variables, constants and numbers are expressions, and
you can use parentheses. There are the following operators:

The following operators do exacly the same as in c (listed here
by precedence):
||                           Boolean or
&&                           Boolean and
==, !=, <, >, <=, >=         Comparision
!                            Boolean not
+, -
*, /, %

%% Insert precedence of special operators.


The following special operators exist:
<expr> == <number1> .. <number2>   Is true, if <expr> lies between the
                                   two numbers. You may also omit one of
                                   the numbers. (Then, it does the same
                                   as <= resp. >=)
<number1> : <number2>              Is true (that is, 1) with probability
                                   number1/number2
<Sequence of six/eight 0,1,?>      Is true if the sequence fits to the
                                   neighbour pattern of the blob. That is:
                                   Look at the neighbour blob above
                                   this one. If it's the same kind, write a
                                   "1", else a "0". Do the same thing for
                                   the seven other neighbours, going
                                   clockwise (the five other neighbours,
				   if the level is in hex mode). This way,
				   you get the neighbour pattern.
                                   Fitting is defined in the obvious way.
				   Example: 1???0??? is true iff the
				   neighbour above this blob is of the
				   same kind and the blob below it is of
				   different kind.
				   Note that if some blob changes its kind
				   during a step, the expression will still
				   return the value it had at the beginning
				   of the step.
The following functions exist:
rnd(<expr>)        Returns a random value between 0 and <expr>-1



Variables and Constants
-----------------------

The following types of variables and constants exist:
- User defined variables (see section "Definitions"). At start of the level
  (or at the creation of the blob) the value is the default value you
  provided.
- System variables. These variables are always defined and have special
  meanings, e.g. file and pos. Some of them are read-only.
- Constants. Some of them depend on properties of the level, some are
  really constant.

Of each variable, there's one instance in each blob. Normally, you access
the instance in your own blob, but with the following syntax, you can access
variables of neighbour blops:
  <varname>@(<dx>, <dy>)
dx and dy are relative coordinates. This can be done for both, reading and
writing variables. It also works for system variables (but not for constants).
Be aware that dx and dy can't be expressions; they have to be fixed numbers.

In hex mode levels, for odd <dx>, <dy> has to be a "half integer", that
is a number ending in ".5". This is the only place in cual where there
are non-integers.

There's also one global instance of each variable. That one can be acessed by
  <variable>@
(without coordinates). See section "The Global Blob" for details.



Some details:

- Whenever you try to access a variable at a location which doesn't exist,
  you will get the default value.
- Changing a variable which doesn't exist does nothing.
- You will realize that the access of variables of other blobs could introduce
  a dependence of the order of execution of the blob codes.
  This dependence is almost eliminated by the following method:
  - Whenever you read a variable with "@", you will get the value it had
    *before* any of the blob codes has been executed in this step.
  - Whenever you write a variable with "@", the write operation is performed
    only *after* all blob codes have been exeduted in this step.
  This is true also if you access your one variables with "@(0,0)".
  So the only dependence of the execution order appears if two different
  blobs both write the same variable of one third blob.
  There's one exeption to that: The global blob (if it exists) is executed
  before all other blobs. (See section "The global Blob")


The system variables:
- file       Specifies the file number from which to take the icon that
             is drawn by "*". This variable is reset to 0 before each step.
- pos        Specifies the position in the file of the icon that is drawn
             by "*". This variable is reset to 0 before each step.
- kind       The kind of the blob. There are constants for the possible
             values of this variable.
             If you change the kind, you should be aware of two things:
	     - If you are using an expression like "001???01", it will
	       return the value it had *before* any of the blob codes
	       has been executed in this step.
	     - In the actual step, the program to draw the blob has already
	       been invoked (in fact, the program which changed this variable);
	       so in this step, the blob will still look like one of the old
	       kind.
- version    Only important for the "grass": Is set to the the number
             specified by the letter in the startdist. (A = 0, ..., z = 51).
- qu         Tells "*" which part of the icon to draw. It's possible to
             draw the whole icon, or only one of its quarters. If a quarter
             is drawn, you may specify which quarter to take and at which
             position to draw it independently. Use the constants.
             This variable is reset to "draw all" before each step.
- out1, out2 Set these Variables for debug output. The value will be printed
             on top of the blob.
             
The system read-only variables:
- turn       Is 1 resp. 2 if the blob is falling and just being turned
             by the user. (1 in the first turn step, 2 in the second one.)
             Be aware that if the user presses the turn key fast several
             times, some of these steps may be omitted. (Use the turn event
             to get a message once for each turn.)
- connect    Contains internal data. Will be removed. Probably.
- size       The size of the component of the blob. (That is, how many blobs
             are connected.)
- loc_x, loc_y   The absolute coordinates of the blob. (0,0) = top left corner
- loc_p          The player of the blob (1 or 2)
- falling    true, if the blob is falling. (Falling in the sense of steered
             by the user. Grey blobs are not falling in that sense.)
- players    The number of players.


The constants:

- Constants for qu:
  - Q_ALL                    Value for qu, which means "draw the complete
                             picture".
  - Q_TL, Q_TR, Q_BL, B_BR   Values for qu. "TL" means draw top-left quarter,
                             etc. (See the "*" command in the Code section.)
  - Q_SRC_DST                SRC and DST may be TL, TR, BL, BR. Take quarter
                             SRC and draw it at position DST
			     
- Constants for kind and for change
  - <name of kind of blob>   For each kind of blob, there's one constant with
                             the name of that kind. Use it to check if a
			     blob is of that kind using "kind@(x,y) == aKind"
			     or to change to that kind using "change = aKind"
			     These constants do also exist for the grass kind,
			     the grey kind and, if existent, the empty kind.
  - nothing                  Is the same as the constant for the empty kind.
                             Is provided, because sometimes, you don't have
			     an empty kind, but you still need to test if a
			     blob is empty.
  - outside                  The value of kind if the coordinates are outside
                             of the game board.

Busieness
---------
(No, not Business ;-)

Busieness is a concept to make it easier to implement simple animated
sequences which are triggered by certain events. Each code fragment has an
internal state which tells if it is busy.
- Normal statements like assignments are never busy. A chain of commands
  separated by "," is busy as long as not all of the commands have been
  executed.
- <code1> ; <code2> is busy as long as at least one of <code1> and <code2>
  are busy.

Here's an example of how to use busieness for an animation which appears
at random intervals:

  switch {
    1/100 => {B*, C*, D*, E*};
    -> A*;
  };

This code fragment normally draws the icon at position A (0). But in each
step, with a probability of 1/100, an animation sequence consiting of icons
B, C, D and E is started. With a normal arrow ("->") after the "1/100",
after the step in which B has been drawn, the probability would be 99/100
that A is drawn again. But with the double arrow, the switch statement
won't switch back to A until the animation has terminated.

(Btw: It doesn't matter if there's a "->" or a "=>" before the "A*";
A* isn't busy anyway.)



The Global Blob
---------------

Apart from the normal blobs which you can see on screen, there's one global
blob (for the whole game, not one for each player), which, well, isn't really
a blob, but behaves a bit like it. It has
its own set of variables, and it can have a program which is run once every
step. To define such a global program, use "global=<code>". However, the global
variables do exist even if you don't define global code. See section
"Variables" on how to access them.
Note that the global blob is always executed before any of the normal blobs.




Event Handlers
--------------


The following events exist:
- init: Is called only once, when the blob gets into live.
- turn: Is called for falling blobs each time the user presses
  the turn key.
- land: Is called when the steered blob lands



The life of a blob
------------------

Normal blobs come into life at the beginning of the game, or they fall
into life, either as colored blobs, steered by the user or as grey blobs.
When a blob moves (by gravitiy or when rows go from one player to another),
it takes its variables with it. (That is, variables are not bound to a
specific location on screen.)
When a blob explodes, it does not stop existing, but it transforms into
an empty blob. That's important for the variables: The empty blob still
has all the variables set to the values they had before; it's just another
kind of blob. Empty blobs are everywhere where there's no other blob.
(However, the falling blobs steered by the user is in some sense "above"
everything else; there are empty blobs beneath them.

The life of an empty blob is different from the one of normal blobs. Empty
blobs are not affected by gravity, and they often start or stop existing.
For example, when a single grey blob is falling down, the empty blob below
it stops existing when it comes and a new empty blob starts existeng above
it. However, there is one situation in which also empty blobs move: When
a row moves from one player to the other, and everything moves up resp. down,
the empty blobs move, too.




Where do I put the Cual code?
-----------------------------

Cual code can be defined in different sections of the .ld files:
- Outside of everything; that code is accessible for every level.
- In the section of a level.
- In the section of a kind.
This basically does what you expect. However, there's one thing you might want to know: Even if you define a variable inside a
kind, _every_ blob in that level will have that variable. The only effect
of defining the variable in the section of a kind is that this kind is the
only one which can access the variable.






Some Subleties
--------------

For experts: Is there a difference between the two following examples?

Example 1:
<<
myblob = {
  ...
  switch {
    myvar -> { 0A*; 1; A,B,C,D; *; 2A*};
          -> { 0B*; 1; A,B,C,D; *; 2B*};
  };
};
>>


Example 2:
<<
anim = {1; A,B,C,D; *};

myblob = {
  ...
  switch {
    myvar -> { 0A*; anim; 2A*};
          -> { 0B*; anim; 2B*};
  };
};
>>


Answer: Yes. The difference is what happens when myvar changes. In example 1,
the animation "A, B, C, D" will start at the beginning (because the two
animations are different ones); in example 2, the "same" animation is used
in both cases, so the animation will simply continue.

