Open main menu

Difference between revisions of "AGI/Specifications/Internals"

Wikify and fill in differences from SGML
(→‎Flag: -- Fix table)
(Wikify and fill in differences from SGML)
Line 167: Line 167:
<span id="tab-reserved-variables"></span>
<span id="tab-reserved-variables"></span>


{| border="1"
{| border="1"  cellspacing="0" cellpadding="5" align="center"
|+ '''Table 3-1. Reserved variables'''
|+ '''Table 3-1. Reserved variables'''
|-  
|-  
Line 192: Line 192:
|-  
|-  
| 6
| 6
| Direction of ego's motion
| Direction of ego's motion [[AGI/Specifications/Internals#fig-directions | Figure 3-2]]
|-  
|-  
| 7
| 7
Line 219: Line 219:
|-  
|-  
| 15
| 15
| Joystick sensitivity (if f8 == 1)
| Joystick sensitivity (if '''f8''' == 1)
|-  
|-  
| 16
| 16
Line 234: Line 234:
|-  
|-  
| 20
| 20
| Computer type (see table XX)
| Computer type (see [[AGI/Specifications/Internals#tab-computer-types | Table 3-3]])
|-  
|-  
| 21
| 21
| Message window timer (if f15 == 0, the window is automatically closed after 0.5 * v21 seconds)
| Message window timer (if '''f15''' == 0, the window is automatically closed after 0.5 * '''v21''' seconds)
|-  
|-  
| 22
| 22
| Sound type (see table XX)
| Sound type (see [[AGI/Specifications/Internals#tab-sound-types | Table 3-4]])
|-  
|-  
| 23
| 23
Line 252: Line 252:
|-  
|-  
| 26
| 26
| Monitor type (see table XX)
| Monitor type (see [[AGI/Specifications/Internals#tab-monitor-types | Table 3-5]])
|}
|}


<span id="tab-border-code"></span>
<span id="tab-border-code"></span>


{| border="1"
{| border="1"  cellspacing="0" cellpadding="5" align="center"
|+ '''Table 3-2. Border codes'''
|+ '''Table 3-2. Border codes'''
|-  
|-  
Line 278: Line 278:
| Left edge of the screen
| Left edge of the screen
|}
|}
<span id="fig-directions"></span>
'''Figure 3-2. Ego's directions'''
                            1
                        8  |  2
                        \  |  /
                          \ | /
                    7 ------------- 3      0 - the object
                          / | \                is motionless
                        /  |  \
                        6  |  4
                            5
<span id="tab-computer-types"></span>
{| border="1"  cellspacing="0" cellpadding="5" align="center"
|+ '''Table 3-3. Computer Types'''
|-
! Code
! Description
|-
| 0
| IBM-PC
|-
| 4
| Atari ST
|-
| 5
| Amiga
|-
| 7
| Apple IIGS
|-
| 20
| Amiga's Space Quest I (Version 1.2, AGI 2.082)
|}
<span id="tab-sound-types"></span>
{| border="1"  cellspacing="0" cellpadding="5" align="center"
|+ '''Table 3-4. Sound Types'''
|-
! Code
! Description
|-
| 0
| IBM-PC
|-
| 3
| Tandy (This value is also used by the Amiga AGI and Apple IIGS AGI)
|-
| 8
| Apple IIGS's Gold Rush! (Version 1.0M 1989-02-28 (CE), AGI 3.003) uses value 8
|}
<span id="tab-monitor-types"></span>
{| border="1"  cellspacing="0" cellpadding="5" align="center"
|+ '''Table 3-5. Monitor Types'''
|-
! Code
! Description
|-
| 0
| CGA (This value is also used by the Apple IIGS AGI)
|-
| 2
| Hercules
|-
| 3
| EGA (This value is also used by the Amiga AGI)
|-
| 0
| Amiga's King's Quest I (Version 1.0U, AGI 2.082) and Space Quest I (Version 1.2, AGI 2.082)
|-
| 0
| Amiga's Space Quest I (Version 1.2, AGI 2.082)
|}


==Flag==
==Flag==
Line 283: Line 367:
Flags are 1-bit boolean data types whose value can be either 1 or 0
Flags are 1-bit boolean data types whose value can be either 1 or 0
(true or false). There are 256 flags numbered from 0 to 255. The
(true or false). There are 256 flags numbered from 0 to 255. The
first 16 flags (listed in [[AGI/Specifications/Internals#tab-reserved-flags | Table 3-3]] are
first 16 flags (listed in [[AGI/Specifications/Internals#tab-reserved-flags | Table 3-6]] are
reserved by the interpreter for internal use. On the interpreter startup,
reserved by the interpreter for internal use. On the interpreter startup,
all flags are set to 0.
all flags are set to 0.
Line 290: Line 374:




{|  border="1"
{|  border="1"  cellspacing="0" cellpadding="5" align="center"
|+ Table 3-3. Reserved flags
|+ Table 3-6. Reserved flags
|-  
|-  
! Flag
! Flag
Line 380: Line 464:
In fact the interpreter calls its usage of the VIEW resource "objects". An object is one usage of a VIEW resource. It is essentially an entry in the object table (or VIEW table/VIEW list). Many objects can use the same VIEW resource for its appearance which can be seen in KQ1 and BC with the crocodile filled moats.
In fact the interpreter calls its usage of the VIEW resource "objects". An object is one usage of a VIEW resource. It is essentially an entry in the object table (or VIEW table/VIEW list). Many objects can use the same VIEW resource for its appearance which can be seen in KQ1 and BC with the crocodile filled moats.


So when an AGI command has an object as a parameter to it, the value of the parameter is an index number into a table of objects that the interpreter is currently controlling.
When an AGI command has an object as a parameter to it, the value of the parameter is an index number into a table of objects that the interpreter is currently controlling.


==Message==
==Message==
Line 393: Line 477:


Therefore messages in logic.0 can be displayed by any LOGIC in this way.
Therefore messages in logic.0 can be displayed by any LOGIC in this way.
<!-- XXXXXXX -->
<span id="Variables"></span>
=Variables used by the interpreter=
On interpreter startup all variables are set to 0.
* 0 - Current room number (parameter new_room cmd), initially 0.
* 1 - Previous room number.
* 2 - Code of the border touched by Ego:
** 0 - Touched nothing;
** 1 - Top edge of the screen or the horizon;
** 2 - Right edge of the screen;
** 3 - Bottom edge of the screen;
** 4 - Left edge of the screen.
* 3 - Current score.
* 4 - Number of object, other than Ego, that touched the border.
* 5 - The code of border touched by the object in Var (4).
* 6 - Direction of Ego's motion.
<pre>
                            1
                        8  |  2
                        \  |  /
                          \ | /
                    7 ------------- 3      0 - the object
                          / | \                is motionless
                        /  |  \
                        6  |  4
                            5
</pre>
* 7 - Maximum score.
* 8 - Number of free 256-byte pages of the interpreter's memory.
* 9 - If == 0, it is the number of the word in the user message that was not found in the dictionary. (I would assume they mean "if != 0", but that's what they say. --VB)
* 10 - Time delay between interpreter cycles in 1/20 second intervals.
* 11 - Seconds (interpreter's internal clock)
* 12 - Minutes (interpreter's internal clock)
* 13 - Hours (interpreter's internal clock)
* 14 - Days (interpreter's internal clock)
* 15 - Joystick sensitivity (if Flag (8) = 1).
* 16 - ID number of the view-resource associated with Ego.
* 17 - Interpreter error code (if == 0) (Again I would expect this to say "if != 0". --VB)
* 18 - Additional information that goes with the error code.
* 19 - Key pressed on the keyboard.
* 20 - Computer type. IBM-PC = 0, Atari ST = 4, Amiga = 5, Apple IIGS = 7.
** Exceptions: Amiga's Space Quest I (Version 1.2, AGI 2.082) uses value 20.
* 21 - If Flag (15) == 0 (command reset 15 was issued) and Var (21) is not equal to 0, the window is automatically closed after 1/2 * Var (21) seconds.
* 22 - Sound generator type:
** 1 - PC;
** 3 - Tandy (This value is also used by the Amiga AGI and Apple IIGS AGI).
** Exceptions: Apple IIGS's Gold Rush! (Version 1.0M 1989-02-28 (CE), AGI 3.003) uses value 8.
* 23 - 0:F - sound volume (for Tandy).
* 24 - This variable stores the maximum number that can be entered in the input line. By default, this variable is set to 41 (29h). (information by Dark Minister)
* 25 - ID number of the item selected using status command or 0xFF if ESC was pressed.
* 26 - monitor type
** 0 - CGA (This value is also used by the Apple IIGS AGI);
** 2 - Hercules;
** 3 - EGA (This value is also used by the Amiga AGI).
** Exceptions: Amiga's King's Quest I (Version 1.0U, AGI 2.082) and Space Quest I (Version 1.2, AGI 2.082) use value 0.
<span id="Flags"></span>
=Flags used by the interpreter=
On the interpreter startup all flags are set to 0.
* 0 - Ego base line is completely on pixels with priority = 3 (water surface).
* 1 - Ego is invisible of the screen (completely obscured by another object).
* 2 - the player has issued a command line.
* 3 - Ego base line has touched a pixel with priority 2 (signal).
* 4 - said command has accepted the user input.
* 5 - The new room is executed for the first time.
* 6 - restart_game command has been executed.
* 7 - if this flag is 1, writing to the script buffer is blocked.
* 8 - if 1, Var(15) determines the joystick sensitivity.
* 9 - sound on/off.
* 10 - 1 turns on the built-in debugger.
* 11 - Logic 0 is executed for the first time.
* 12 - "restore_game" command has been executed.
* 13 - 1 allows the "status" command to select items.
* 14 - 1 allows the menu to work.
* 15 - Determines the output mode of `print' and `print_at' commands:
** 1 - message window is left on the screen
** 0 - message window is closed when ENTER or ESC key are pressed. If Var(21) is not 0, the window is closed automatically after 1/2 * Var(21) seconds


<span id="Memory"></span>
<span id="Memory"></span>
Line 508: Line 508:
Written by Lance Ewing with additions/modifications by Peter Kelly and Anders M. Olsson (Last updated: 3 March 1998).
Written by Lance Ewing with additions/modifications by Peter Kelly and Anders M. Olsson (Last updated: 3 March 1998).


Since the data formats for the different AGI interpreter versions are mostly identical or easily convertible to each other, we should expect to be able to run one games data with anothers interpreter. This sounds like a reasonable assumption but when you try it, the interpreter rejects the new data. The reason behind this is game IDs.
Since the data formats for the different AGI interpreter versions are mostly identical or easily convertible to each other, we should expect to be able to run one games data with anothers interpreter. This sounds like a reasonable assumption but when you try it, the interpreter rejects the new data. The reason behind this is ''game IDs''.
 
Every interpreter has got a game ID coded into it and it expects to be given data for that game. Somewhere in the initialization code for each game is a '''set.game.id()'''. When this command is encountered, the interpreter checks the given game ID and compares it with its own. If they are not the same, it quits immediately. Presumably the reason for this was to stop people running games with the wrong interpter version, which can cause problems (unless you know what you're doing).


Every interpreter has got a game ID coded into it and it expects to be given data for that game. Somewhere in the initialization code for each game is a set.game.id(). When this command is encountered, the interpreter checks the given game ID and compares it with its own. If they are not the same, it quits immediately. Presumably the reason for this was to stop people running games with the wrong interpter version, which can cause problems (unless you know what you're doing).
==How do we get around it?==
==How do we get around it?==


Line 525: Line 526:
* Leisure Suit Larry: 'L' 'L' 'L' 'L' 'L' 0x00 'X'
* Leisure Suit Larry: 'L' 'L' 'L' 'L' 'L' 0x00 'X'


The game ID itself is the null terminated string that ends at the 00h. The text that follows it is of no significance, it is simply to fill in the gap although it is useful when searching for the game ID because, as you can see, this text is always "eIDX"> (presubably from "gameIDX" before being overwritten by the actual ID) or a suffix of it (i.e. "IDX", "DX", or "X"). For most games, the game ID is two or three characters which means that you will be able to rely on the "IDX" string being there for these games.
The game ID itself is the null terminated string that ends at the 00h. The text that follows it is of no significance, it is simply to fill in the gap although it is useful when searching for the game ID because, as you can see, this text is always "<tt>eIDX</tt>" (presubably from "gameIDX" before being overwritten by the actual ID) or a suffix of it (i.e. "<tt>IDX</tt>", "<tt>DX</tt>", or "<tt>X</tt>"). For most games, the game ID is two or three characters which means that you will be able to rely on the "IDX" string being there for these games.


===Method 2: The easy way===
===Method 2: The easy way===


Using the above method will allow you to run a different game with an interpreter, but you will still only be able to run the game that has the specified game ID. There is another way around this, which involves patching the logic source. This can be accomplished using a program to edit the logics such as AGI Studio (for the Windows platform). What you can usually do is look at the top part of logic 0 and find out what the initialization logic is (usually around 90--100 -- you might have to look at a few logics before you find it). Then simply go to that logic, find the set.game.id command, remove it, and recompile the logic. Since the command is not used, the interpreter will not try and compare it with it's own ID, and it won't quit.
Using the above method will allow you to run a different game with an interpreter, but you will still only be able to run the game that has the specified game ID. There is another way around this, which involves patching the logic source. This can be accomplished using a program to edit the logics such as AGI Studio (for the Windows platform). What you can usually do is look at the top part of logic 0 and find out what the initialization logic is (usually around 90--100 -- you might have to look at a few logics before you find it). Then simply go to that logic, find the '''set.game.id''' command, remove it, and recompile the logic. Since the command is not used, the interpreter will not try and compare it with it's own ID, and it won't quit.


The only drawback to using this method is that the saved games no longer have the game ID in their name (so, for example, a savegame would be called sg.1 instead of kq2sg.1), but this is not a major hassle.
The only drawback to using this method is that the saved games no longer have the game ID in their name (so, for example, a savegame would be called '''sg.1''' instead of '''kq2sg.1'''), but this is not a major hassle.


==Why can't I find the game ID?==
==Why can't I find the game ID?==


This is because a lot of the AGI files themselves are encrypted. See section Encrypted AGI data for further information.
This is because a lot of the AGI files themselves are encrypted. See section [[AGI/Specifications/Internals#Encryption | Encrypted AGI Data]] for further information.


==Possibilities==
==Possibilities==
Line 548: Line 549:
Written by Lance Ewing, with additions/modifications by Peter Kelly and Anders M. Olsson (Last updated: 3 March 1998).
Written by Lance Ewing, with additions/modifications by Peter Kelly and Anders M. Olsson (Last updated: 3 March 1998).


Many AGI files are encrypted. This was probably to give some protection to their product which was quite unique at the time. You can tell the difference between an encrypted AGI file and a non-encrypted AGI file by the first two characters. If they are "MZ" (the MS-DOS executable file header), then it not encrypted.
Many AGI files are encrypted. This was probably to give some protection to their product which was quite unique at the time. <!-- Footnote --> ''(You can tell the difference between an encrypted AGI file and a non-encrypted AGI file by the first two characters. If they are "MZ" (the MS-DOS executable file header), then it not encrypted.)'' The AGI file is decrypted by the loader program. This is usually called '''sierra.com''' in MS-DOS but can also be named after the game (eg. '''kq1.com'''). In AGI version 1, the loader was called '''load'''. If an AGI game doesn't have a loader, then it shouldn't be encrypted. If an AGI game does have a loader, it does not necessarily mean that the AGI file is encrypted.
 
The AGI file is decrypted by the loader program. This is usually called sierra.com in MS-DOS but can also be named after the game (eg. kq1.com). In AGI version 1, the loader was called load. If an AGI game doesn't have a loader, then it shouldn't be encrypted. If an AGI game does have a loader, it does not necessarily mean that the AGI file is encrypted.
 
The decryption key was not originally embedded in the loader file. If you find a game where the key is embedded in the loader, it is because that game has had copy protection removed. There are several utilities to do that. Anders M Olsson's SUP is one of them. The CD re-releases have been unprotected by Sierra in exactly the same fashion.


The loader would read the decryption key from track 6 of the disk, load the executable file, decrypt and run it. Track 6 had a special format that was supposedly impossible to exactly reproduce by a standard PC floppy disk controller.
The decryption key was not originally embedded in the loader file. If you find a game where the key is embedded in the loader, it is because that game has had copy protection removed. There are several utilities to do that. Anders M Olsson's '''SUP''' is one of them. The CD re-releases have been unprotected by Sierra in exactly the same fashion.


An interesting note is that when a copy-protected Sierra game asked for the original disk one, you could insert disk one from any protected Sierra game. The contents of track 6 were always the same.
The loader would read the decryption key from track 6 of the disk, load the executable file, decrypt and run it. Track 6 had a special format that was supposedly impossible to exactly reproduce by a standard PC floppy disk controller. An interesting note is that when a copy-protected Sierra game asked for the original disk one, you could insert disk one from ''any'' protected Sierra game. The contents of track 6 were always the same.


But even though track 6 was the same, all games didn't use exactly the same encryption key. The two bytes in the loader, immediately following the string "keyOfs", gave an offset on track 6 from where the key would be loaded.
But even though track 6 was the same, all games didn't use exactly the same encryption key. The two bytes in the loader, immediately following the string "<tt>keyOfs</tt>", gave an offset on track 6 from where the key would be loaded.


So, if the decryption string consists of 128 `k' characters, it can actually mean one of two things: Either the AGI file is not encrypted, or the game is still copy-protected.
So, if the decryption string consists of 128 `k' characters, it can actually mean one of two things: Either the AGI file is not encrypted, or the game is still copy-protected.
Line 577: Line 574:
The start of a loader will look something like this:
The start of a loader will look something like this:


<pre>LOADER v3.0 (c) Copyright Sierra On-Line, Inc. 1987 keyOfs</pre>
  LOADER v3.0 (c) Copyright Sierra On-Line, Inc. 1987 keyOfs


There are two bytes in between the "keyOfs" string and the start of the description string. If the decryption key consists of 128 `k' characters, then the AGI file is not encrypted (or the game is still copy-protected). If it consists of a whole lot of random looking characters, then it is encrypted.
There are two bytes in between the "<tt>keyOfs</tt>" string and the start of the description string. If the decryption key consists of 128 `k' characters, then the AGI file is not encrypted (or the game is still copy-protected). If it consists of a whole lot of random looking characters, then it is encrypted.


As an aside, the decryption string is followed immediately by the stack and is usually marked with a whole string of `s' characters. Thus we have `k' for key and `s' for stack. The stack is usually 256 bytes long.
As an aside, the decryption string is followed immediately by the stack and is usually marked with a whole string of `s' characters. Thus we have `k' for key and `s' for stack. The stack is usually 256 bytes long.
==Decrypting the AGI file==
==Decrypting the AGI file==


Line 591: Line 589:
From the AGDS documentation, translated by Vassili Bykov (Last update: 31 August 1998).
From the AGDS documentation, translated by Vassili Bykov (Last update: 31 August 1998).


Note: This section is an excerpt from the description of the said command from section Reference of LOGIC commands.
Note: This section is an excerpt from the description of the '''said''' command from section [[AGI/Specifications/Logic#CommandRef | Reference of LOGIC commands]].


Here is how the input is matched. After the player types a message and presses ENTER, the input line is processed by the interpreter in the following way:
Here is how the input is matched. After the player types a message and presses '''ENTER''', the input line is processed by the interpreter in the following way:


# The interpreter removes all punctuation marks.
# The interpreter removes all punctuation marks.
Line 603: Line 601:


* The Interpreter removes from the sequence of codes all zeros (that means all vocabulary words with zero codes are ignored).
* The Interpreter removes from the sequence of codes all zeros (that means all vocabulary words with zero codes are ignored).
* f2 (the user has entered an input line) is set to 1
* '''f2''' (the user has entered an input line) is set to 1
* f4 (said command accepted the user input) is set to 0.
* '''f4''' ('''said''' command accepted the user input) is set to 0.


If the sequence of code produced by the interpreter is
If the sequence of code produced by the interpreter is V(1), V(2),...V(m), the test is performed as follows:
 
<pre>
    V(1), V(2),...V(m)
</pre>
 
The test is performed as follows:


<pre>
<pre>
Line 625: Line 617:
Otherwise W(i) should be equal to V(i).
Otherwise W(i) should be equal to V(i).


If all elements match, f4 (said accepted the user input) is set to 1 and the command returns TRUE. Otherwise, FALSE is returned.
If all elements match, '''f4''' ('''said''' accepted the user input) is set to 1 and the command returns TRUE. Otherwise, FALSE is returned.


<span id="InterpreterVersions"></span>
<span id="InterpreterVersions"></span>
Line 633: Line 625:
==Sorted by Game==
==Sorted by Game==


<pre>
Known Sierra AGI versions are listed in [[AGI/Specifications/Internals#tab-agi-games | AGI games and interpreter versions table]]. There are a number of different versions of the AGI interpeter but
    Game   Ver.    Int    Int. Ver.      Date
generally the data formats are the same or can be converted
    ------- ------- ------- --------------- ---------
between each other. [[AGI/Specifications/Internals#tab-agi-games | AGI interpreter versions and features table]] compares the
    AGID    ?.?    AGI    2.915          ??/??/??
number of commands and other features in these interpreter versions.
    BC      2.00   AGI    2.439           06/14/87
 
    BC      2.10    AGI    3.002.098      11/10/88
<span id="tab-agi-games"></span>
    GR      2.01   AGI    3.002.149       12/22/88
{| border="1"  cellspacing="0" cellpadding="5" align="center"
    KQ1    1.0U   AGI    2.272           Unknown
|+  AGI games and interpreter versions
    KQ1    2.0F   AGI    2.425           ??/??/87
|-
    KQ1    2.0F   AGI    2.917           Unknown
! Game
    KQ2    2.1     AGI    2.411           Unknown
! Version
    KQ2    2.2     AGI    2.426           Unknown
! Int. version
    KQ2    2.2     AGI    2.917           ??/??/87
! Date</thead><tbody>
    KQ3    1.01   AGI    2.272           11/08/86
|-  
    KQ3    2.00   AGI    2.435           05/25/87
|  The Black Cauldron 
    KQ3    2.14   AGI    2.936           03/15/88
| 2.00
    KQ4    2.0     AGI    3.002.086       07/27/88
| 2.439
    KQ4D    ?.??    AGI    3.002.102       ??/??/??
| 14 Jun 1987
    LSL1    1.00   AGI    2.440           06/01/87
|-
    LSL1    1.0    AGI    2.917          06/01/87
|  Gold Rush&#33; 
    MG      ?.??    AGI    2.915           Unknown
| 2.01
    MH1    1.22   AGI    3.002.102       08/30/88
| 3.002.149
    MH1    1.22   AGI    3.002.107       08/31/88
| 22 Dec 1988
    MH2    3.02B   AGI    3.002.149       07/26/89
|-
    MH2    3.03   AGI    3.002.149       08/17/89
|  King's Quest I
    PQ1    2.0G   AGI    2.917           12/03/87
| 1.0U
    SQ1    1.0X   AGI    2.089           Unknown
| 2.272
    SQ1    2.2     AGI    2.426           ??/??/??
| Unknown
    SQ1    2.2     AGI    2.917           ??/??/??
|-
    SQ1    2.2    AGI    2.917          ??/??/87
|  King's Quest I
    SQ2    2.0C   AGI    2.915           ??/??/87
| 2.0F
    SQ2    2.0C   AGI    2.917           Unknown
| 2.425
    SQ2    2.0D   AGI    2.936           Unknown
| 1987
    SQ2    2.0F   AGI    2.936           Unknown
|-
    XM86    ?.??    AGI    2.272           Unknown
|  King's Quest I
</pre>
| 2.0F
| 2.917
| Unknown
|-
|  King's Quest II
| 2.1
| 2.411
| Unknown
|-
|  King's Quest II
| 2.2
| 2.426
| Unknown
|-
|  King's Quest II
| 2.2
| 2.917
| 1987
|-
|  King's Quest III
| 1.01
| 2.272
|  8 Nov 1986
|-
|  King's Quest III
| 2.00
| 2.435
| 25 May 1987
|-
|  King's Quest III
| 2.14
| 2.936
| 15 Mar 1988
|-
|  King's Quest IV
| 2.0
| 3.002.086
| 27 Jul 1988
|-
|  King's Quest IV demo
| ?
| 3.002.102
| Unknown
|-
|  Leisure Suit Larry
| 1.00
| 2.440
1 Jun 1987
|-
|  Mixed-Up Mother Goose
| ?
| 2.915
| Unknown
|-
|  Man Hunter: New York
| 1.22
| 3.002.102
| 30 Aug 1988
|-
|  Man Hunter: New York
| 1.22
| 3.002.107
| 31 Aug 1988
|-
|  Man Hunter: San Francisco
| 3.02B
| 3.002.149
| 26 Jul 1989
|-
|  Man Hunter: San Francisco
| 3.03
| 3.002.149
| 17 Aug 1989
|-
|  Police Quest I
| 2.0G
| 2.917
|  3 Dec 1987
|-
|  Space Quest I
| 1.0X
| 2.089
| Unknown
|-
|  Space Quest I
| 2.2
| 2.426
| Unknown
|-
|  Space Quest I
| 2.2
| 2.917
| 1987
|-
|  Space Quest II
| 2.0C
| 2.915
| 1987
|-
|  Space Quest II
| 2.0C
| 2.917
| Unknown
|-
|  Space Quest II
| 2.0D
| 2.936
| Unknown
|-
|  Space Quest II
| 2.0F
| 2.936
| Unknown
|-
|  Christmas Card
| ?
| 2.272
| Unknown
|}


==Sorted by Int. Ver.==
==Sorted by Int. Ver.==
<pre>
 
    Game    Ver.    Int    Int. Ver.      Date
<span id="tab-agi-versions"></span>
    ------- ------- ------- --------------- ---------
 
    SQ1    1.0X    AGI    2.089           Unknown
{| border="1"  cellspacing="0" cellpadding="5" align="center"
    KQ1    1.0U    AGI    2.272           Unknown
|+ AGI interpreter versions and features
    KQ3    1.01    AGI    2.272          11/08/86
|-
    XM86    ?.??    AGI    2.272          Unknown
! AGI version
    KQ2    2.1    AGI    2.411           Unknown
! Int. size
    KQ1    2.0F    AGI    2.425          ??/??/87
! Agidata size
    KQ2    2.2    AGI    2.426          Unknown
! Commands
    SQ1    2.2    AGI    2.426          ??/??/??
! Encrypted objects
    KQ3    2.00    AGI    2.435           05/25/87
! LZW
    BC      2.00    AGI    2.439           06/14/87
|-  
    LSL1    1.00    AGI    2.440           06/01/87
| 2.089
    AGID    ?.?    AGI    2.915           ??/??/??
| 34305
    MG      ?.??    AGI    2.915          Unknown
| 6656
    SQ2    2.0C    AGI    2.915          ??/??/87
| 155
    KQ1    2.0F    AGI    2.917           Unknown
| No
    KQ2    2.2    AGI    2.917          ??/??/87
| No
    LSL1    1.0    AGI    2.917          06/01/87
|-
    PQ1    2.0G    AGI    2.917          12/03/87
| 2.272
    SQ1    2.2    AGI    2.917          ??/??/??
| 34816
    SQ1    2.2    AGI    2.917          ??/??/87
| 6656
    SQ2    2.0C    AGI    2.917          Unknown
| 161
    KQ3    2.14    AGI    2.936           03/15/88
| No
    SQ2    2.0D    AGI    2.936          Unknown
| No
    SQ2    2.0F    AGI    2.936          Unknown
|-
    KQ4    2.0    AGI    3.002.086       07/27/88
| 2.411
    BC      2.10    AGI    3.002.098       11/10/88
| 38400
    KQ4D    ?.??    AGI    3.002.102       ??/??/??
| 7680
    MH1    1.22    AGI    3.002.102      08/30/88
| 169
    MH1    1.22    AGI    3.002.107       08/31/88
| Yes
    GR      2.01    AGI    3.002.149       12/22/88
| No
    MH2    3.02B  AGI    3.002.149      07/26/89
|-
    MH2    3.03    AGI    3.002.149      08/17/89
| 2.435
</pre>
| 38400
| 7680
| 169
| Yes
| No
|-
| 2.439
| 38400
| 7680
| 169
| Yes
| No
|-
| 2.440
| 38400
| 7680
| 169
| Yes
| No
|-
| 2.915
| 39424
| 8192
| 173
| Yes
| No
|-
| 2.917
| 39424
| 8192
| 173
| Yes
| No
|-
| 2.936
| 39424
| 8192
| 175
| Yes
| No
|-
| 3.002.086
| 40866
| 8064
| 177
| Yes
| Yes
|-
| 3.002.098
| 40898
| 8080
| 181
| Yes
| Yes
|-
| 3.002.102
| 40898
| 8080
| 181
| Yes
| Yes
|-
| 3.002.107
| 40962
| 8080
| 181
| Yes
| Yes
|-
| 3.002.149
| 40520
| 7488
| 181
| Yes
| Yes
|}


<span id="VersionDifferences"></span>
<span id="VersionDifferences"></span>
Line 828: Line 1,013:
* Firstly, as the interpreter version increased, the number of AGI commands supported increased with it. The last eleven we do not know the names of.
* Firstly, as the interpreter version increased, the number of AGI commands supported increased with it. The last eleven we do not know the names of.
* There are two main AGI versions: AGI v2 and AGI v3.
* There are two main AGI versions: AGI v2 and AGI v3.
* The early AGI v2 games did not encrypt the object file with the "Avis Durgan" string.
* The early AGI v2 games did not encrypt the object file with the "<tt>Avis Durgan</tt>" string.
* AGI v3 games use adaptive LZW to compress their LOGIC, VIEW, and SOUND files.
* AGI v3 games use adaptive LZW to compress their LOGIC, VIEW, and SOUND files.


Line 835: Line 1,020:
There are four commands that have changed the number of arguments that are passed to them. All this information is based on observations made of the above interpreter versions.
There are four commands that have changed the number of arguments that are passed to them. All this information is based on observations made of the above interpreter versions.


* The quit command had no arguments for version 2.089 whereas all the others above have one argument.
* The '''quit''' command had no arguments for version 2.089 whereas all the others above have one argument.
* The print.at and print.at.v commands had only three arguments for versions 2.089--2.400 and four for the other versions.
* The '''print.at''' and '''print.at.v''' commands had only three arguments for versions 2.089--2.400 and four for the other versions.
* Unknown command number 176 had one argument for version 3.002.086 but later versions had no arguments for this command.
* Unknown command number 176 had one argument for version 3.002.086 but later versions had no arguments for this command.