Outils pour utilisateurs

Outils du site


agi-game:specifications-resources

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
Dernière révisionLes deux révisions suivantes
agi-game:specifications-resources [2021/05/24 14:47] – [The header] frateragi-game:specifications-resources [2021/05/24 15:30] – [AGI Specifications Resources : Logic resources] frater
Ligne 1: Ligne 1:
-====== Logic resources ======+====== AGI Specifications Resources : Logic resources ======
  
-===== Introduction =====+==== Introduction ====
  
 At the heart of Sierra's Adventure Game Interpreter is the logic file. At the heart of Sierra's Adventure Game Interpreter is the logic file.
Ligne 250: Ligne 250:
 |  B6      | adj.ego.move.to.xy  |  0            |        |                               | |  B6      | adj.ego.move.to.xy  |  0            |        |                               |
  
 +===== Logic resource format =====
  
-<span id="LogicFormat"></span> 
- 
-==Logic resource format== 
  
 ==== The header ==== ==== The header ====
  
-The header of each logic script is seven bytes in length for games +The header of each logic script is seven bytes in length for games before 1988. After this date compression seems to have been introduced and the header was subsequently altered. This compression will be
-before 1988. After this date compression seems to have been introduced +
-and the header was subsequently altered. This compression will be+
 discussed at a later stage. discussed at a later stage.
  
-{| border="1"  cellspacing="0" cellpadding="5" +Offset   ^ Command                                       ^ 
-|-  +| 0-1      | Signature (0x12--0x34)                        
-Offset +| 2        | Vol number that the resource is contained in  
-Command +| 3-4      | Length of the resource without the header     
-|-  +| 5-6      | Offset of logic code message section          |
-| 0-1 +
-| Signature (0x12--0x34) +
-| +
-  +
-| Vol number that the resource is contained in +
-| +
-| 3-4 +
-| Length of the resource without the header +
-| +
-| 5-6 +
-| Offset of logic code message section +
-|}+
  
-All text that can be printed to the screen from within a logic script +All text that can be printed to the screen from within a logic script is stored in an encrypted form at the end of the logic script.
-is stored in an encrypted form at the end of the logic script.+
  
 Example: KQ1. Room 2. Example: KQ1. Room 2.
  
 +<code>
  12 34    Signature  12 34    Signature
  01       vol.1  01       vol.1
  5F 06    Length = 0x065F  5F 06    Length = 0x065F
  BA 02    Text start = 0x02BA  BA 02    Text start = 0x02BA
 +</code>
  
-===Opcodes=== +==== Opcodes === 
-The logic code section starts immediately after the header and +The logic code section starts immediately after the header and continues until the start of the message section has been reached. There are three sets of codes used in a logic script. Most codes will have between one and seven arguments inclusive. This is discussed later on. 
-continues until the start of the message section has been reached. There +The first set of codes is the AGI commands themselves listed in the previous tables, and they have the range 0x00--0xB6.
-are three sets of codes used in a logic script. Most codes will have +
-between one and seven arguments inclusive. This is discussed later on. +
-The first set of codes is the AGI commands themselves listed in +
-[[AGI/Specifications/Resources#action-commands|  Table 6-2]], and they have the range 0x00--0xB6.+
  
 The second set of codes is as follows: The second set of codes is as follows:
  
-{| border="1"  cellspacing="0" cellpadding="5" +^ Code  Command               ^ 
-! Code +| FF    **if**                
-Command +| FE    **else** or **goto**  
-|-  +| FD    **not**               
-| FF +| FC    **or**                |
-'''if''' +
-| +
-| FE +
-'''else''' or '''goto''' +
-| +
-| FD +
-'''not''' +
-| +
-| FC +
-'''or''' +
-|}+
  
-At present these are the only high value codes encountered. The +At present these are the only high value codes encountered. The //if// and //or// codes are like brackets, i.e. the code will be at the start and the end of the section of codes that it refers to. The following example will illustrate this:
-'''if''' and '''or''' codes are like brackets, i.e. the code +
-will be at the start and the end of the section of codes that it refers +
-to. The following example will illustrate this:+
  
 Example: KQ1, Room 2. Example: KQ1, Room 2.
  
 +<code C>
    FF      'if' conditions start.    FF      'if' conditions start.
    07      07 = isset    07      07 = isset
    05      05 = flag 5    05      05 = flag 5
    FF      'if' conditions close.    FF      'if' conditions close.
 +</code>
  
 The above translates to: The above translates to:
  
-<code type="C++">+<code C>
 if (isset(5)) if (isset(5))
 </code> </code>
  
-which tests whether flag number 5 is set. The 0xFF effectively switches +which tests whether flag number 5 is set. The 0xFF effectively switches the interpreter into a condition checking mode which leads us to the set of codes listed in tables
-the interpreter into a condition checking mode which leads us to the +
-set of codes listed in [[AGI/Specifications/Resources#test-commands|  Table 6-1]]+
  
 +<code>
  0x00 - 0x12    Condition codes.  0x00 - 0x12    Condition codes.
 +</code>
  
-When the interpreter encounters a 0xFF it will then interpret the +When the interpreter encounters a 0xFF it will then interpret the following code values as being in the condition code range until it encounters the next 0xFF which switches it back into normal AGI command 
-following code values as being in the condition code range until it +mode. The two bytes immediately following the second 0xFF determine how many bytes this //if// statement lasts for before the //if// is ended.  When the second 0xFF is encountered the interpreter, be it
-encounters the next 0xFF which switches it back into normal AGI command +
-mode. The two bytes immediately following the second 0xFF determine how +
-many bytes this '''if''' statement lasts for before the '''if''' +
-is ended.  When the second 0xFF is encountered the interpreter, be it+
 us or the machine, does three things: us or the machine, does three things:
  
-#Reads in the following two bytes. +  - Reads in the following two bytes. 
-#Opens a bracket. +  Opens a bracket. 
-#Switches to AGI command mode.+  Switches to AGI command mode.
  
 Example: KQ1, Room 2. Example: KQ1, Room 2.
  
-<code type="C++">+<code C>
  
 FF 07 05 FF    if (isset(5)) FF 07 05 FF    if (isset(5))
Ligne 366: Ligne 331:
 </code> </code>
  
-===The '''else''' command and more on brackets=== +==== The **else** command and more on brackets ===
-The '''else''' statement will always continue after an + 
-'''if''' bracket block. This next feature is important and has +The **else** statement will always continue after an **if** bracket block. This next feature is important and has caused a number of hassles in the past. When an **else** statement follows an **if**, then the bracket distance given after the **if** statement //will be three bytes longer// (this is a consequence of the way the interpreter handles **if** and **else** codes which is discussed later).
-caused a number of hassles in the past. When an '''else''' +
-statement follows an '''if''', then the bracket distance given +
-after the '''if''' statement ''will be three bytes +
-longer'' (this is a consequence of the way the interpreter handles +
-'''if''' and '''else''' codes which is discussed later).+
  
 Here's an example: Here's an example:
  
-<code type="C++">+<code C>
 if (isset(231)) {                          FF 07 E7 FF 05 00 if (isset(231)) {                          FF 07 E7 FF 05 00
     printf("The door is already open.");   65 0F     printf("The door is already open.");   65 0F
Ligne 392: Ligne 352:
 </code> </code>
  
-Usually you would expect the bracket distance to be 0x0002 but in the 
-above case it is clearly 0x0005 which illustrates the difference 
-between a straight '''if''' statement and an '''if..else''' 
-structure. The situation is the same for nested '''if..else''' 
-structures. 
  
-The '''else''' statements themselves are a lot like '''if''' +Usually you would expect the bracket distance to be 0x0002 but in the above case it is clearly 0x0005 which illustrates the difference between a straight **if** statement and an **if..else** structure. The situation is the same for nested **if..else** structures. 
-statements except that they're test condition is given after the 0xFE + 
-code but is instead the inverse of the condition given by the above +The **else** statements themselves are a lot like **if** statements except that they're test condition is given after the 0xFE code but is instead the inverse of the condition given by the above **if** statement. Only the bracket distance is given after the 0xFE code and then the AGI command clock that the **else** statement encompasses. 
-'''if''' statement. Only the bracket distance is given after the + 
-0xFE code and then the AGI command clock that the '''else''' +==== Test conditions ====
-statement encompasses.+
  
-===Test conditions=== 
 Conditions can be one of the following types: Conditions can be one of the following types:
  
 +<code>
  FF 07 05 FF                         One condition tested, ie. isset(5)  FF 07 05 FF                         One condition tested, ie. isset(5)
  FF FD 07 05 FF                      One condition NOTed, ie. !isset(5)  FF FD 07 05 FF                      One condition NOTed, ie. !isset(5)
Ligne 413: Ligne 367:
  FF FC 07 05 07 06 FC FF             Multiple conditions ORed.  FF FC 07 05 07 06 FC FF             Multiple conditions ORed.
  FF FC 07 06 07 06 FC FD 07 08 FF    Combination.  FF FC 07 06 07 06 FC FD 07 08 FF    Combination.
 +</code>
  
 These conditions translate to: These conditions translate to:
  
-<code type="C++">+<code C>
 if (isset(5)) if (isset(5))
 if (!isset(5)) if (!isset(5))
Ligne 424: Ligne 379:
 </code> </code>
  
-If multiple boolean expressions are grouped together, then there +If multiple boolean expressions are grouped together, then there respective values are ANDed together. If multiple boolean expressions are grouped together and then surrounded by a pair of 0xFC codes, then
-respective values are ANDed together. If multiple boolean expressions +
-are grouped together and then surrounded by a pair of 0xFC codes, then+
 their values are ORed together. their values are ORed together.
  
-The 0xFD code only applies to the following condition code whose +The 0xFD code only applies to the following condition code whose boolean value it inverts.
-boolean value it inverts.+
  
-===Arguments=== +==== Arguments ==== 
-You may well be asking how the interpreter knows how many arguments +You may well be asking how the interpreter knows how many arguments each code has and what type of argument each argument is. This information is stored in ''agidata.ovl'' in the MS-DOS version.  
-each code has and what type of argument each argument is. This +Inside this file there is a table which contains four bytes for each AGI command and condition code. These four bytes are interpreted as follows:
-information is stored in <tt>agidata.ovl</tt> in the MS-DOS version. +
-Inside this file there is a table which contains four bytes for each +
-AGI command and condition code. These four bytes are interpreted as +
-follows:+
  
-{| border="1"  cellspacing="0" cellpadding="5" +Offset   ^ Description                     ^ 
-|-  +| 0-1      | Pointer to implementation code  
-Offset +| 2        | Number of arguments             
-Description +| 3        | Type of arguments               |
-|-  +
-| 0-1 +
-| Pointer to implementation code +
-| +
-  +
-| Number of arguments +
-| +
-  +
-| Type of arguments +
-|}+
  
 The type of arguments value is interpreted as follows: The type of arguments value is interpreted as follows:
  
 +<code>
  Bit        7                               0  Bit        7                               0
  command( arg1, arg2, arg3, arg4, arg5, arg6, arg7); (unknown)  command( arg1, arg2, arg3, arg4, arg5, arg6, arg7); (unknown)
 +</code>
  
-If the bit is set, argument is interpreted as a variable; otherwise +If the bit is set, argument is interpreted as a variable; otherwise the argument is interpreted as a number. It is unknown what bit 0 does since no AGI command or AGI condition code has more than seven arguments.
-the argument is interpreted as a number. It is unknown what bit 0 does +
-since no AGI command or AGI condition code has more than seven arguments.+
  
 Examples: Examples:
  
-*0x80 Says that the commands first argument is a variable. +  * 0x80 Says that the commands first argument is a variable. 
-*0x60 Says that the second and third arguments are variable numbers.+  * 0x60 Says that the second and third arguments are variable numbers.
  
-===The messages section=== +==== The messages section ===
-The messages section of a logic script contains all the strings that can + 
-be displayed by that logic script. These strings are encrypted by +The messages section of a logic script contains all the strings that can be displayed by that logic script. These strings are encrypted by xor'ing every eleven bytes with the string "Avis Durgan".
-xor'ing every eleven bytes with the string "Avis Durgan".+
  
 Example: KQ1, Room 2. Example: KQ1, Room 2.
  
-<code type="C++">+<code C>
 if (said(look, alligators)) if (said(look, alligators))
 { {
Ligne 485: Ligne 422:
 In the above example, the print statement is represented as: In the above example, the print statement is represented as:
  
 +<code>
  65 08  65 08
 +</code>
  
-The 0x08 is the number given to the string and corresponds to its +The 0x08 is the number given to the string and corresponds to its position in the list of strings at the end of the logic script. 
-position in the list of strings at the end of the logic script.+
 The format of the message section is as follows: The format of the message section is as follows:
  
-{| border="1"  cellspacing="0" cellpadding="5" +Offset   ^ Description                                                                                                                                                  ^ 
-|-  +| 0        | Number of messages                                                                                                                                           
-Offset +| 1-2      | Pointer to the end of the messages                                                                                                                           
-Description +| 3-4      | Array of message pointers                                                                                                                                    
-|-  +| ...      | Array of message pointers                                                                                                                                    
-|   +| ?        | Start of the text data. From this point the messages are encrypted with Avis Durgan (in their unencrypted form, each message is separated by a 0x00 value)   |
-| Number of messages +
-| +
-| 1-2 +
-| Pointer to the end of the messages +
-| +
-| 3-4 +
-| Array of message pointers +
-| +
-| ... +
-| Array of message pointers +
-| +
-  +
-| Start of the text data. From this point the messages are encrypted with Avis Durgan (in their unencrypted form, each message is separated by a 0x00 value) +
-|}+
  
-===Implementation=== +==== Implementation ==== 
-The implementation for each AGI statement is found in the <tt>agi</tt>/ +The implementation for each AGI statement is found in the //agi//file. This is the AGI interpreter itself. The data in the ''agidata.ovl'' file is used to find the start of the implementation for an AGI statement. Below are a couple of examples:
-file. This is the AGI interpreter itself. The data in the +
-<tt>agidata.ovl</tt> file is used to find the start of the +
-implementation for an AGI statement. Below are a couple of examples:+
  
 Example: MH2, equaln. Example: MH2, equaln.
  
-<code type="ASM">+<code asm>
 ;equaln   (eg.   if (work = 3)   ) ;equaln   (eg.   if (work = 3)   )
 0D71 AC            LODSB                       ;get variable number 0D71 AC            LODSB                       ;get variable number
Ligne 535: Ligne 456:
 Example: MH2, equalv. Example: MH2, equalv.
  
-<code type="ASM">+<code asm>
 ;equalv  (eg.   if (work = maxwork)   ) ;equalv  (eg.   if (work = maxwork)   )
 0D82 AC            LODSB                       ;get first var number 0D82 AC            LODSB                       ;get first var number
Ligne 550: Ligne 471:
 </code> </code>
  
-These two examples show the difference between how numbers and +These two examples show the difference between how numbers and variables are dealt with. In the case of a variable, the variables number is used as an index into the table of variable values to get the value which is being tested. It appears that the variable table is at offset 0x0009 in the data segment.
-variables are dealt with. In the case of a variable, the variables +
-number is used as an index into the table of variable values to get +
-the value which is being tested. It appears that the variable table is +
-at offset 0x0009 in the data segment.+
  
-===How the interpreter handles the code=== +==== How the interpreter handles the code ==== 
-The following 8086 assembly language code is the actual code from +The following 8086 assembly language code is the actual code from the MS-DOS version of Manhunter: San Francisco. There are some calls to routines which aren't displayed. Take my word for it that they do what the comment says. For those of you who can't follow whats going on, I'll explain the interpretation in steps after the code block.
-the MS-DOS version of Manhunter: San Francisco. There are some calls +
-to routines which aren't displayed. Take my word for it that they do +
-what the comment says. For those of you who can't follow whats going +
-on, I'll explain the interpretation in steps after the code block.+
  
-<code type="ASM">+<code asm>
 ;Decoding a LOGIC file. ;Decoding a LOGIC file.
 1E6C:2EF2 56            PUSH  SI 1E6C:2EF2 56            PUSH  SI
Ligne 668: Ligne 581:
 1E6C:2FA4 EBDE          JMP   2F84 1E6C:2FA4 EBDE          JMP   2F84
 1E6C:2FA6 AD            LODSW 1E6C:2FA6 AD            LODSW
-1E6C:2FA7 03F0          ADD   SI,AX         ;Skip over if (includes 3 else byte +1E6C:2FA7 03F0          ADD   SI,AX         ;Skip over if (includes 3 else bytes)
-s)+
 1E6C:2FA9 E954FF        JMP   2F00 1E6C:2FA9 E954FF        JMP   2F00
 </code> </code>
  
-''Situation 1.'' Every logic script starts in normal AGI command +//Situation 1.// 
-execution mode. In this routine, if the code is below 0xFC, then it is +Every logic script starts in normal AGI command execution mode. In this routine, if the code is below 0xFC, then it is presumed to be an AGI command. It will then call the main command execution routine which will jump to the relevant routine for the specific command using the jump table stored in ''agidata.ovl''.  
-presumed to be an AGI command. It will then call the main command +The command is performed and it returns to the main execution routine where it loops back to the top and deals with the next code in the logic file.
-execution routine which will jump to the relevant routine for the +
-specific command using the jump table stored in <tt>agidata.ovl</tt>+
-The command is performed and it returns to the main execution routine +
-where it loops back to the top and deals with the next code in the +
-logic file.+
  
-''Situation 2.'' +//Situation 2.// 
-If the code is an 0xFF code, then if jumps to the '''if''' +If the code is an 0xFF code, then if jumps to the **if** statement handler. In this routine is basically assesses whether the whole test condition evaluates to true or to false. It does this by treating each test separately and calling the relevant test command routines using the jump table in the ''agidata.ovl'' file. Each test command routine will return a value in //AL/which says whether it is true or not. Depending on the NOTs and ORs, the whole expression is evaluated. If at any stage during the evaluation the routine decides that the expression will be false, it exits to another routine which skips the rest of the **if** statement and then adds the two byte word following the closing 0xFF code to the execution pointer. This usually has the affect of jumping over the **if** block of code. If the **if** handler gets to the ending 0xFF then it knows the expression is true simply because it hasn't exited out of the routine yet. At this stage it jumps over the two bytes following the closing 0xFF and then goes back to executing straight AGI commands.
-statement handler. In this routine is basically assesses whether the +
-whole test condition evaluates to true or to false. It does this by +
-treating each test separately and calling the relevant test command +
-routines using the jump table in the <tt>agidata.ovl</tt> file. +
-Each test command routine will return a value in <tt>AL</tt> which +
-says whether it is true or not. Depending on the NOTs and ORs, the +
-whole expression is evaluated. If at any stage during the evaluation +
-the routine decides that the expression will be false, it exits to +
-another routine which skips the rest of the '''if''' statement +
-and then adds the two byte word following the closing 0xFF code to +
-the execution pointer. This usually has the affect of jumping over +
-the '''if''' block of code. If the '''if''' handler gets +
-to the ending 0xFF then it knows the expression is true simply because +
-it hasn't exited out of the routine yet. At this stage it jumps over +
-the two bytes following the closing 0xFF and then goes back to +
-executing straight AGI commands.+
  
-''/Situation 3.'' If in the normal execution of AGI commands, +//Situation 3.// 
-the code 0xFE is encountered, a very simple action takes place. The +If in the normal execution of AGI commands, the code 0xFE is encountered, a very simple action takes place. The two bytes which follow form a 16-bit twos complement value which is added to execution pointer. This is all it does. Previously we said that the 0xFE code stood for the **else** statement which is in actual fact correct for over 90% of the time, but the small number of other occurrences are best described as **goto** statements. 
-two bytes which follow form a 16-bit twos complement value which is +If you're confused by this, the following example will probably explain things.
-added to execution pointer. This is all it does. Previously we said +
-that the 0xFE code stood for the '''else''' statement which is +
-in actual fact correct for over 90% of the time, but the small number +
-of other occurrences are best described as '''goto''' statements. +
-If you're confused by this, the following example will probably explain +
-things.+
  
 Example: Example:
  
-<code type="C++">+<code C>
 if (said( open, door)) { if (said( open, door)) {
     // first block of AGI statements     // first block of AGI statements
Ligne 722: Ligne 607:
 </code> </code>
  
-The above example is how the original coder would have written the AGI +The above example is how the original coder would have written the AGI code. If we now look at the following example, it is not hard to see that it would achieve the same thing.
-code. If we now look at the following example, it is not hard to see +
-that it would achieve the same thing.+
  
-<code type="C++">+<code C>
 if (!said( open, door)) goto label1; if (!said( open, door)) goto label1;
     // first block of AGI statements     // first block of AGI statements
Ligne 737: Ligne 620:
 </code> </code>
  
-This is exactly how all '''if'''s and '''else'''s are +This is exactly how all **if**s and **else**s are implemented in the logic code. The **if** statement is a conditional branch where the branch is taken if the condition is not met, while the **else** statement is a nonconditional jump. If a 0xFE code appears in the middle of some AGI code and wasn't actually originally coded as an **else**, then it was most likely a **goto** statement. 
-implemented in the logic code. The '''if''' statement is a + 
-conditional branch where the branch is taken if the condition is +==== The **said** test command ====
-not met, while the '''else''' statement is a nonconditional +
-jump. If a 0xFE code appears in the middle of some AGI code and +
-wasn't actually originally coded as an '''else''', then it was +
-most likely a '''goto''' statement.+
  
-===The <tt>said</tt> test command=== 
 The above assembly language code does raise a very important point. The above assembly language code does raise a very important point.
-The '''said''' command can have a variable number of arguments. Its +The **said** command can have a variable number of arguments. Its code is 0x0E, and the byte following this byte gives the number of two byte words that follow as parameters.
-code is 0x0E, and the byte following this byte gives the number of +
-two byte words that follow as parameters.+
  
 Examples: Examples:
  
-<code type="C++">+<code C>
 if (said(marble))                          FF 0E 01 1E 01 FF if (said(marble))                          FF 0E 01 1E 01 FF
 if (said( open, door))                     FF 0E 02 37 02 73 00 FF if (said( open, door))                     FF 0E 02 37 02 73 00 FF
 </code> </code>
  
-In the above examples, the values 0x011E, 0x0237, and 0x0073 are just +In the above examples, the values 0x011E, 0x0237, and 0x0073 are just random word numbers that could stand for the words given.
-random word numbers that could stand for the words given.+
  
-===Inner loops=== +==== Inner loops ==== 
-At first I almost totally discarded the existence of loops in the AGI +At first I almost totally discarded the existence of loops in the AGI code because it seemed to me that execution of the logic script continually looped. Loop code like "while", "do..while", and "for" statements wouldn't be needed because you could just use a variable to increment with each pass and an **if** statement to test the value of the variable and take action if it was withing the desired range.
-code because it seemed to me that execution of the logic script +
-continually looped. Loop code like "while", "do..while", and "for" +
-statements wouldn't be needed because you could just use a variable to +
-increment with each pass and an '''if''' statement to test the +
-value of the variable and take action if it was withing the desired range.+
  
 Example: Example:
  
-<code type="C++">+<code C>
 if (greatern(30, 45) && lessn(30, 55)) { if (greatern(30, 45) && lessn(30, 55)) {
     print("You're in the hot zone!");     print("You're in the hot zone!");
Ligne 778: Ligne 648:
 </code> </code>
  
-I have found evidence of this sort of thing taking place which means +I have found evidence of this sort of thing taking place which means that they must loop over continuously. I don't know whether this is something that the interpreter does itself or whether it is part of 
-that they must loop over continuously. I don't know whether this is +the AGI code, e.g. at the end of one logic script it calls another which then calls the first one again. With the existence of the conditional branching and unconditional branching nature of the **if** and 
-something that the interpreter does itself or whether it is part of +**else** statement, it is easy to see that some of the structures such as "do..while" can infact be coded into logic scripts.
-the AGI code, e.g. at the end of one logic script it calls another which +
-then calls the first one again. With the existence of the conditional +
-branching and unconditional branching nature of the '''if''' and +
-'''else''' statement, it is easy to see that some of the +
-structures such as "do..while" can infact be coded into logic scripts.+
  
 Example: Example:
  
-<code type="C++">+<code C>
 FF FD 0D FF 03 00 FE F7 FF FF FD 0D FF 03 00 FE F7 FF
  
Ligne 796: Ligne 661:
 </code> </code>
  
-The above translation is a simple one which is taken from SQ2. The +The above translation is a simple one which is taken from SQ2. The value 0xFFF7 is the twos complement notation for -9 which is the exact branching value to take the execution back to the start of the **if** 
-value 0xFFF7 is the twos complement notation for -9 which is the exact +statement. If the above example had AGI code between the 0x00 and the 0xFE, then there would be code within the brackets of the "do..while" structure. I don't know whether the original AGI coders used these 
-branching value to take the execution back to the start of the '''if''' +statements or used **goto** statements to achieve the same result.
-statement. If the above example had AGI code between the 0x00 and the +
-0xFE, then there would be code within the brackets of the "do..while" +
-structure. I don't know whether the original AGI coders used these +
-statements or used '''goto''' statements to achieve the same result.+
  
agi-game/specifications-resources.txt · Dernière modification : 2023/04/13 09:50 de frater