Open main menu

Difference between revisions of "AGI/Specifications/Logic"

Syntax highlighing
m (→‎Other commands: adding agi256 note)
(Syntax highlighing)
Line 10: Line 10:
Normal action commands are specified by the command name followed by brackets which contain the arguments, separated by commas. A semicolon is placed after the brackets. The brackets are required even if there are no arguments. The arguments given must have the correct prefix for that type of argument as explained later in this document (this is to make sure the programmer does not use a var, for example, when they think they are using a flag).
Normal action commands are specified by the command name followed by brackets which contain the arguments, separated by commas. A semicolon is placed after the brackets. The brackets are required even if there are no arguments. The arguments given must have the correct prefix for that type of argument as explained later in this document (this is to make sure the programmer does not use a var, for example, when they think they are using a flag).


<syntax type="C++">
     assign.v(v50,0);
     assign.v(v50,0);
     program.control();
     program.control();
</syntax>


Multiple commands may be placed on the one line:
Multiple commands may be placed on the one line:


    reset(f6); reset(f7);
<syntax type="C++">
  reset(f6); reset(f7);
</syntax>


Substitutions for the following action commands are available:
Substitutions for the following action commands are available:


<syntax type="C++">
     increment(v30);      v30++;
     increment(v30);      v30++;
     decrement(v30);      v30--;
     decrement(v30);      v30--;
Line 34: Line 39:
     lindirectv(v30,v32);  *v30 = v32;
     lindirectv(v30,v32);  *v30 = v32;
     rindirect(v30,v32);  v30 = *v32;
     rindirect(v30,v32);  v30 = *v32;
</syntax>


===if structures and test commands===
===if structures and test commands===
Line 39: Line 45:
An if structure looks like this:
An if structure looks like this:


<syntax type="C++">
     if (<test commands>) {
     if (<test commands>) {
         <action commands>
         <action commands>
     }
     }
</syntax>


or like this :
or like this :


<syntax type="C++">
     if (<test commands>) {
     if (<test commands>) {
         <action commands>
         <action commands>
Line 51: Line 60:
       <more action commands>
       <more action commands>
     }
     }
</syntax>


Carriage returns are not necessary:
Carriage returns are not necessary:


<syntax type="C++">
     if (<test commands>) { <action Commands> } else { <more action commands> }
     if (<test commands>) { <action Commands> } else { <more action commands> }
</syntax>


Test commands are coded like action commands except there is no semicolon. They are separated by && or || for AND or OR.
Test commands are coded like action commands except there is no semicolon. They are separated by && or || for AND or OR.


<syntax type="C++">
     if (isset(f5) &&
     if (isset(f5) &&
         greatern(v5,6)) { ......
         greatern(v5,6)) { ......
</syntax>


Again, carriage returns are not necessary within the if statement:
Again, carriage returns are not necessary within the if statement:


<syntax type="C++">
     if (lessn(v5,6) && (greatern(v5,2)) { .......
     if (lessn(v5,6) && (greatern(v5,2)) { .......


     if (isset(f90) && equalv(v32,v34)
     if (isset(f90) && equalv(v32,v34)
         && greatern(v34,20)) { .......
         && greatern(v34,20)) { .......
</syntax>


A ! placed in front of a command signifies a NOT.
A ! placed in front of a command signifies a NOT.


<syntax type="C++">
     if (!isset(f7)) {
     if (!isset(f7)) {
       ......
       ......
</syntax>


Boolean expressions are not necessarily simplified so they must follow the rules set down by the file format. If test commands are to be ORred together, they must be placed in brackets.
Boolean expressions are not necessarily simplified so they must follow the rules set down by the file format. If test commands are to be ORred together, they must be placed in brackets.


<syntax type="C++">
     if ((isset(f1) || isset(f2)) {
     if ((isset(f1) || isset(f2)) {
       ......
       ......
Line 81: Line 100:
       ......
       ......


     if (isset(1) || (isset(2) && isset(3))) {    is NOT legal
     if (isset(1) || (isset(2) && isset(3))) {    // is NOT legal
</syntax>


Depending on the compiler, simplification of boolean expressions may be supported, so the above may not apply in all cases (although if these are rules are followed then the logic will work with all compilers).
Depending on the compiler, simplification of boolean expressions may be supported, so the above may not apply in all cases (although if these are rules are followed then the logic will work with all compilers).
Line 87: Line 107:
Substitutions for the following test commands are available:
Substitutions for the following test commands are available:


<syntax type="C++">
     equaln(v30,4)        v30 == 4
     equaln(v30,4)        v30 == 4
     equalv(v30,v32)      v30 == v32
     equalv(v30,v32)      v30 == v32
Line 99: Line 120:
     !lessn(v30,4)        v30 >= 4
     !lessn(v30,4)        v30 >= 4
     !lessv(v30,v32)      v30 >= v32
     !lessv(v30,v32)      v30 >= v32
</syntax>


Also, flags can be tested for by just using the name of the flag:
Also, flags can be tested for by just using the name of the flag:


<syntax type="C++">
     if (f6) { .....
     if (f6) { .....


     if (v7 > 0 && !f6) { .....
     if (v7 > 0 && !f6) { .....
</syntax>


===Argument types===
===Argument types===
Line 128: Line 152:
Compilers can enforce type checking, so that the programmer must use the correct prefix for an argument so that they know they are using the right type. Decoders should display arguments with the right type.
Compilers can enforce type checking, so that the programmer must use the correct prefix for an argument so that they know they are using the right type. Decoders should display arguments with the right type.


<syntax type="C++">
     move.obj(so4,80,120,2,f66);
     move.obj(so4,80,120,2,f66);
     if (obj.in.box(so2,30,60,120,40)) { .....
     if (obj.in.box(so2,30,60,120,40)) { .....
</syntax>


A complete list of the commands and their argument types is available as part of AGI Specs.
A complete list of the commands and their argument types is available as part of AGI Specs.
Line 135: Line 161:
Messages and inventory items may be given in either numerical text format:
Messages and inventory items may be given in either numerical text format:


<syntax type="C++">
     print("He's not here.");
     print("He's not here.");
     print(m12);
     print(m12);
     if (has("Jetpack")) { .....
     if (has("Jetpack")) { .....
     if (has(io9)) { .....
     if (has(io9)) { .....
</syntax>


Messages can also be split over multiple lines:
Messages can also be split over multiple lines:


<syntax type="C++">
     print("This message is split "
     print("This message is split "
           "over multiple lines.");
           "over multiple lines.");
</syntax>


Quote marks must be used around messages and object names. This is important because some messages or object names may contain brackets or commas, which could confuse the compiler. This is also the case for the said command which will be described shortly.
Quote marks must be used around messages and object names. This is important because some messages or object names may contain brackets or commas, which could confuse the compiler. This is also the case for the said command which will be described shortly.


<syntax type="C++">
     if (has("Buckazoid(s)")) { .....        // no ambiguity here about where
     if (has("Buckazoid(s)")) { .....        // no ambiguity here about where
                                             // the argument ends
                                             // the argument ends
</syntax>


The said test command uses different parameters to all the other commands. Where as the others use 8 bit arguments (0--255), said takes 16 bit arguments (0--65535). Also, the number of arguments in a said command can vary. The numbers given in the arguments are the word group numbers from the words.tok file.
The said test command uses different parameters to all the other commands. Where as the others use 8 bit arguments (0--255), said takes 16 bit arguments (0--65535). Also, the number of arguments in a said command can vary. The numbers given in the arguments are the word group numbers from the words.tok file.


<syntax type="C++">
     if (said(4,80)) { .....
     if (said(4,80)) { .....
</syntax>


Words can also be given in place of the numbers:
Words can also be given in place of the numbers:


<syntax type="C++">
     if (said("look")) { .....
     if (said("look")) { .....
     if (said("open","door")) { .....
     if (said("open","door")) { .....
</syntax>


Quote marks must also be used around the words.
Quote marks must also be used around the words.
Line 165: Line 201:
Labels are given like this:
Labels are given like this:


<syntax type="C++">
     Label1:
     Label1:
</syntax>


The label name can contain letters, numbers, and the characters "_" and ".". No spaces are allowed.
The label name can contain letters, numbers, and the characters "_" and ".". No spaces are allowed.
Line 171: Line 209:
The goto command takes one parameter, the name of a label.
The goto command takes one parameter, the name of a label.


<syntax type="C++">
     goto(Label1);
     goto(Label1);
</syntax>


===Comments===
===Comments===
Line 177: Line 217:
There are three ways that comments can be used.
There are three ways that comments can be used.


<syntax type="C++">
     // Rest of line is ignored
     // Rest of line is ignored
     [  Rest of line is ignored
     [  Rest of line is ignored
     /* Text between these are ignored */
     /* Text between these are ignored */
</syntax>


The /*...*/ can be nested:
The /*...*/ can be nested:


<syntax type="C++">
     /* comment start
     /* comment start
       print("Hello");    // won't be run
       print("Hello");    // won't be run
Line 190: Line 233:
       print("Hey!");    // won't be run, still inside comments
       print("Hey!");    // won't be run, still inside comments
     */                  // uncomments
     */                  // uncomments
</syntax>


===Defines===
===Defines===
Line 195: Line 239:
To give vars, flags etc. proper names the #define command is used. The name of the define is given followed by the define value:
To give vars, flags etc. proper names the #define command is used. The name of the define is given followed by the define value:


<syntax type="C++">
     #define ego o0
     #define ego o0
     #define room_descr "This is a large hall with tall pillars down each side."
     #define room_descr "This is a large hall with tall pillars down each side."
</syntax>


Then the define name can be used in place of the define value:
Then the define name can be used in place of the define value:


<syntax type="C++">
     draw(ego);
     draw(ego);
     print(room_descr);
     print(room_descr);
</syntax>


Define names can only be used in arguments of commands (including gotos and the v0 == 3 type syntax), although some compilers may allow you to use them anywhere.
Define names can only be used in arguments of commands (including gotos and the v0 == 3 type syntax), although some compilers may allow you to use them anywhere.
Line 213: Line 261:
You can include another file in your logic source code by using the #include command:
You can include another file in your logic source code by using the #include command:


<syntax type="C++">
     #include "file.txt"
     #include "file.txt"
</syntax>


When the compiler encounters the above line, it will replace it with the contents of file.txt.
When the compiler encounters the above line, it will replace it with the contents of file.txt.
Line 222: Line 272:
In some cases you may want to assign a specific number to a message so you can refer to it in other places. This is done by using the #message command, followed by the number of the message then the message itself:
In some cases you may want to assign a specific number to a message so you can refer to it in other places. This is done by using the #message command, followed by the number of the message then the message itself:


<syntax type="C++">
     #message 4 "You can't do that now."
     #message 4 "You can't do that now."
</syntax>


Then you can give the message number as the parameter in commands:
Then you can give the message number as the parameter in commands:


<syntax type="C++">
     print(m4);
     print(m4);
</syntax>


Or embed the message in commands as normal and the number you assigned to it before will be used:
Or embed the message in commands as normal and the number you assigned to it before will be used:


<syntax type="C++">
     print("You can't do that now.");
     print("You can't do that now.");
</syntax>


#message can be used anywhere in the file, so you do not have to set the message before you use it.
#message can be used anywhere in the file, so you do not have to set the message before you use it.
Line 788: Line 844:




<syntax type="C++">
     load.pic(n);
     load.pic(n);
     draw.pic(n);
     draw.pic(n);
Line 793: Line 850:
     ...
     ...
     show.pic();
     show.pic();
</syntax>


     Any other order may crash the interpreter without any diagnostic messages.
     Any other order may crash the interpreter without any diagnostic messages.
Line 1,190: Line 1,248:
From the book:
From the book:


<pre>animate.obj( smoke);
<syntax type="C++">
ignore.horizon( smoke);
animate.obj(smoke);
set.view( smoke, v.fish.cabin);
ignore.horizon(smoke);
set.loop( smoke, 1);
set.view(smoke, v.fish.cabin);
ignore.blocks( smoke);
set.loop(smoke, 1);
position( smoke, 95, 16);
ignore.blocks(smoke);
position(smoke, 95, 16);
work = 3;
work = 3;
step.time( smoke, work);
step.time(smoke, work);
cycle.time( smoke, work);
cycle.time(smoke, work);
draw( smoke);</pre>
draw(smoke);
</syntax>


From the game:
From the game:


<pre>animate.obj(7);
<syntax type="C++">
animate.obj(7);
ignore.horizon(7);
ignore.horizon(7);
set.view(7, 114);
set.view(7, 114);
set.loop(7, 1);
set.loop(7, 1);
ignore.objs(7);                [ These two lines have been added.
ignore.objs(7);                // These two lines have been added.
set.priority(7, 5);            [
set.priority(7, 5);            //
ignore.blocks(7);
ignore.blocks(7);
position(7, 95, 16);
position(7, 95, 16);
assignn(152, 3);              [ Equivalent to 'work = 3;'
assignn(152, 3);              // Equivalent to 'work = 3;'
step.time(7, 152);
step.time(7, 152);
cycle.time(7, 152);
cycle.time(7, 152);
draw(7);</pre>
draw(7);
</syntax>


Opening the door
Opening the door
Line 1,220: Line 1,282:
From the book:
From the book:


<pre>if (said( open, door)) {    [ must be close enough
<syntax type="C++">
if (said( open, door)) {    // must be close enough
   if (posn( ego, 86, 120, 106, 133)) {
   if (posn( ego, 86, 120, 106, 133)) {
     if (!night) {
     if (!night) {
       if ( door.open) {
       if ( door.open) {
         print("The door is already open. . .
         print("The door is already open. . .");
       }
       }
       else {
       else {
Line 1,234: Line 1,297:
     }
     }
     else {
     else {
       print("You can't -- it's locked...
       print("You can't -- it's locked...");
     }
     }
   }
   }
Line 1,240: Line 1,303:
     set( notCloseEnough);
     set( notCloseEnough);
   }
   }
}</pre>
}
</syntax>


From the game:
From the game:


<pre>if (said(OPEN, DOOR||DOORS||DOORWAY||DOORWAYS)) {
<syntax type="C++">
if (said(OPEN, DOOR||DOORS||DOORWAY||DOORWAYS)) {
   if (posn(0, 86, 120, 106, 133)) {
   if (posn(0, 86, 120, 106, 133)) {
     if (!isset(38)) {
     if (!isset(38)) {
Line 1,268: Line 1,333:
     set(113);
     set(113);
   }
   }
}</pre>
}
</syntax>


===Unlocking the door===
===Unlocking the door===
Line 1,274: Line 1,340:
From the book:
From the book:


<pre>if (said( unlock, door)) {    [must be close enough
<syntax type="C++">
if (said( unlock, door)) {    // must be close enough
   if (posn( ego, 86, 120, 106, 133)) {
   if (posn( ego, 86, 120, 106, 133)) {
     if (!night) {
     if (!night) {
       print("The door is already unlocked. . .
       print("The door is already unlocked. . .");
     }
     }
     else {
     else {
       printf("You can't, it's locked. . .
       printf("You can't, it's locked. . .");
     }
     }
   }
   }
Line 1,286: Line 1,353:
     set( notCloseEnough);
     set( notCloseEnough);
   }
   }
}</pre>
}
</syntax>


From the game:
From the game:


<pre>if (said(UNLATCH||UNLOCK, DOOR||DOORS||DOORWAY||DOORWAYS)) {
<syntax type="C++">
if (said(UNLATCH||UNLOCK, DOOR||DOORS||DOORWAY||DOORWAYS)) {
   if (posn(0, 86, 120, 106, 133)) {
   if (posn(0, 86, 120, 106, 133)) {
     if (!isset(38)) {
     if (!isset(38)) {
Line 1,303: Line 1,372:
     set(113);
     set(113);
   }
   }
}</pre>
}
</syntax>


===Knocking on the door===
===Knocking on the door===
Line 1,309: Line 1,379:
From the book:
From the book:


<pre>if ((said( knock, at, door) || said( knock) ||
<syntax type="C++">
if ((said( knock, at, door) || said( knock) ||
     said( knock, on, door) || said( knock, door)) {
     said( knock, on, door) || said( knock, door)) {
   if (posn( ego, 86, 120, 106, 133)) {
   if (posn( ego, 86, 120, 106, 133)) {
     if (!night) {
     if (!night) {
       print("You knock on the door. . .
       print("You knock on the door. . .
             a woman says. . .
             a woman says. . .");
     }
     }
     else {
     else {
       printf("You knock on the. . .
       printf("You knock on the. . .
               a man calls out. . .
               a man calls out. . .");
     }
     }
   }
   }
Line 1,324: Line 1,395:
     set( notCloseEnough);
     set( notCloseEnough);
   }
   }
}</pre>
}
</syntax>


From the game:
From the game:


<pre>if (said(BANG||KNOCK||RAP||TAP) ||
<syntax type="C++">
if (said(BANG||KNOCK||RAP||TAP) ||
     said(BANG||KNOCK||RAP||TAP, DOOR||DOORS||DOORWAY||DOORWAYS)) {
     said(BANG||KNOCK||RAP||TAP, DOOR||DOORS||DOORWAY||DOORWAYS)) {
   if (posn(0, 86, 120, 106, 133)) {
   if (posn(0, 86, 120, 106, 133)) {
Line 1,344: Line 1,417:
     set(113);
     set(113);
   }
   }
}</pre>
}
</syntax>


Fall rocks
Fall rocks
Line 1,350: Line 1,424:
From the book:
From the book:


<pre>if (hit.special) {
<syntax type="C++">
if (hit.special) {
   if ((rf2 || rf3 || rf4)) {
   if ((rf2 || rf3 || rf4)) {
     reset(hit.special);
     reset(hit.special);
Line 1,395: Line 1,470:
     }
     }
   }
   }
}</pre>
}
</syntax>


From the game:
From the game:


<pre>if (isset(3)) {    [ hit.special
<syntax type="C++">
   if (isset(222) || isset(223) || isset(224)) {    [ rf2, rf3, rf4
if (isset(3)) {    [ hit.special
   if (isset(222) || isset(223) || isset(224)) {    // rf2, rf3, rf4
     reset(3);
     reset(3);
     sound(51, 154);
     sound(51, 154);
Line 1,447: Line 1,524:
     }
     }
   }
   }
}</pre>
}
</syntax>