Difference between revisions of "FF7/Battle/Battle Scenes/Battle Script"

From Final Fantasy Inside
Jump to navigation Jump to search
my_wiki>Akari
m (20 revisions imported)
 
(18 intermediate revisions by 3 users not shown)
Line 3: Line 3:
 
There are four actions to be explained when dealing with any opcode in AI script: Arguments, Values to take from the stack, what to do with Arguments and Values, and what to put back on the stack. So to fully understand what is happening a brief explanation of the stack is necessary.
 
There are four actions to be explained when dealing with any opcode in AI script: Arguments, Values to take from the stack, what to do with Arguments and Values, and what to put back on the stack. So to fully understand what is happening a brief explanation of the stack is necessary.
  
The stack is more-or-less a list of values with different lengths. Only the top of the stack can be accessed at any given time, but when that value is accessed it leaves the stack and the previously added value now becomes the top of the stack. Adding to the stack is called "Pushing" a value and taking a value off is called "Popping". When pushing a value to the stack, the value of the number is pushed followed by the value type. The value type can be one of three different things:
+
The stack is more-or-less a list of values with different lengths. Only the top of the stack (the most recently added value) can be accessed at any given time, but when that value is accessed it is removed from the top of the stack and the previously added value now becomes the top of the stack. Adding to the stack is called "Pushing" a value and taking a value off is called "Popping". When pushing a value to the stack, the value of the number is pushed followed by the value type. The value type can be one of three different things:
 
<br/>
 
<br/>
 
<br/>
 
<br/>
Line 14: Line 14:
 
|-
 
|-
 
| align="center" | 1Xh
 
| align="center" | 1Xh
| Address
+
| [[FF7/Battle/Battle_Scenes/Battle_AI_Addresses|Address]]
 
|-
 
|-
 
| align="center" | 2Xh
 
| align="center" | 2Xh
Line 21: Line 21:
 
|}
 
|}
 
<br/>
 
<br/>
They are stored as DWords, but the X will determine how many bytes to use: 0 = bit, 1 = Byte, 2 = Word, 3 = DWord
+
They are stored as DWords, but the X will determine how many bytes to use: 0 = bit, 1 = Byte, 2 = Word, 3 = Three bytes
  
 
Now that we've seen the stack, here are the opcodes:
 
Now that we've seen the stack, here are the opcodes:
Line 34: Line 34:
 
|-
 
|-
 
| 0Xh
 
| 0Xh
| 2 byte Address
+
| 2 byte Memory Address
 
|  
 
|  
 
| Type 0X stored at translated Address
 
| Type 0X stored at translated Address
Line 41: Line 41:
 
|-
 
|-
 
| 1Xh
 
| 1Xh
| 2 byte Address
+
| 2 byte Memory Address
 
|
 
|
| Argument Type 1X
+
| Address value with a scope of X
 
|-
 
|-
 
! style="background:rgb(224,224,224)" align="center" colspan = "4" | Mathematical and Bit-wise Operators
 
! style="background:rgb(224,224,224)" align="center" colspan = "4" | Mathematical and Bit-wise Operators
Line 139: Line 139:
 
|-
 
|-
 
| 60h
 
| 60h
| One Byte
+
| 1 byte Value
 
|  
 
|  
 
| Argument of type 01
 
| Argument of type 01
 
|-
 
|-
 
| 61h
 
| 61h
| Two Bytes
+
| 2 byte Value
 
|  
 
|  
 
| Argument of type 02
 
| Argument of type 02
 
|-
 
|-
 
| 62h
 
| 62h
| Four Bytes
+
| 3 byte Value
 
|  
 
|  
 
| Argument of type 03
 
| Argument of type 03
 
|-
 
|-
! style="background:rgb(224,224,224)" align="center" colspan = "4" | Script Jumps
+
! style="background:rgb(224,224,224)" align="center" colspan = "4" | Script Jumps (No Pushes)
 
|-
 
|-
 
| 70h
 
| 70h
| Two Bytes
+
| 2 byte Script Address
 
| One of any type
 
| One of any type
 
| Jumps to script address in argument if pop is 0
 
| Jumps to script address in argument if pop is 0
 
|-
 
|-
 
| 71h
 
| 71h
| Two Bytes
+
| 2 byte Script Address
 
| One of any type
 
| One of any type
 
| Jumps to script address in argument if pop and top of stack are not equal
 
| Jumps to script address in argument if pop and top of stack are not equal
 
|-
 
|-
 
| 72h
 
| 72h
| Two Bytes
+
| 2 byte Script Address
 
|  
 
|  
 
| Jumps to script address in argument
 
| Jumps to script address in argument
Line 174: Line 174:
 
|-
 
|-
 
| 74h
 
| 74h
|  
+
|
 
| One of any type
 
| One of any type
|  
+
| Pops one value from stack. (Not used)
 
|-
 
|-
 
| 75h
 
| 75h
 
|  
 
|  
 
| One of any type
 
| One of any type
| Link all scripts of this fighter to given fighter.
+
| Link all scripts of script owner to popped Character ID.
 
|-
 
|-
 
! style="background:rgb(224,224,224)" align="center" colspan = "4" | Bit Operations
 
! style="background:rgb(224,224,224)" align="center" colspan = "4" | Bit Operations
Line 187: Line 187:
 
| 80h
 
| 80h
 
|  
 
|  
| One of type 0X or 2X, One of any type
+
| Two of any type
| First pop ANDed with second pop.
+
| First pop masked by second pop
 
|-
 
|-
 
| 81h
 
| 81h
Line 203: Line 203:
 
|  
 
|  
 
| One of any type
 
| One of any type
| Type 01 with count of number of bits set in pop
+
| If pop is Type 01, Type 01 with count of number of bits set in pop<br/>
 +
If pop is Type 02, Type 02 filled with value of first non-null value in pop
 
|-
 
|-
 
| 84h
 
| 84h
Line 225: Line 226:
 
| Type 02 with only bit in pop turned on (1 << [pop])
 
| Type 02 with only bit in pop turned on (1 << [pop])
 
|-
 
|-
! style="background:rgb(224,224,224)" align="center" colspan = "3" | Commands
+
|}
 +
<p>
 +
&nbsp;
 +
</p>
 +
{| border="1" cellspacing="1" cellpadding="3" align="center" style="border: 1px solid black; border-collapse: collapse;"
 +
! style="background:rgb(204,204,204)" align="center" colspan = "4" | Command
 +
 
 +
|-
 +
! style="background:rgb(224,224,224)" align="center" | Code
 +
! style="background:rgb(224,224,224)" align="center" | Arguments
 +
! style="background:rgb(224,224,224)" align="center" | Value(s) to pop
 
! style="background:rgb(224,224,224)" align="center" | Effect
 
! style="background:rgb(224,224,224)" align="center" | Effect
 
|-
 
|-
Line 241: Line 252:
 
|
 
|
 
| One of any type
 
| One of any type
| Pops variable from stack.
+
| Pops one value from stack.
 
|-
 
|-
 
| 92h
 
| 92h
 
|
 
|
 
| Two of any type
 
| Two of any type
| First pop is attack ID to perform. Second pop action type (0x20 - enemy attack or 0x24 - display string)
+
| First pop is attack ID to perform. Second pop action type<br>
 
|-
 
|-
 
| 93h
 
| 93h
 
| NULL terminated string
 
| NULL terminated string
| colspan="2" align = "center"| Displays string
+
|
 +
| Displays string
 
|-
 
|-
 
| 94h
 
| 94h
 
|  
 
|  
 
| Two of any type
 
| Two of any type
|  
+
| Copy current status, hp and mp as well as some other specific data (like boosts, multipliers) from units in first given mask to units in second mask.
 
|-
 
|-
 
| 95h
 
| 95h
 
|  
 
|  
 
| One of type 1X, one of type 00
 
| One of type 1X, one of type 00
| If second pop is 1, takes value at local address 2010 and writes value at memory bank1/2, get data to 2010  from memory bank1/2 otherwise.
+
| If second pop is 1, takes value at local address 2010 and writes value at [[FF7/Savemap#Save_Memory_Bank_1.2F2|memory bank 1/2]] at offset specified by first pop<br/> If second pop is 0, data at memory bank1/2 at offset specified by first pop is stored at local address 2010.<br/>
 +
Otherwise, command is ignored.
 
|-
 
|-
 
| 96h
 
| 96h
Line 273: Line 286:
 
|-
 
|-
 
| A1h
 
| A1h
| ?
+
|  
| ?
+
| Two values of any type
| ?
+
| Pops two values from stack (Not Used, but valid command)
 
|-
 
|-
 
|}
 
|}
 
<br/>
 
<br/>
 
GENERAL NOTES:
 
GENERAL NOTES:
*Commands 90h and 95h are overloaded.
+
*Command 90h is overloaded.
 
*If a type 2X is popped and any type is accepted, only the first value will be considered.
 
*If a type 2X is popped and any type is accepted, only the first value will be considered.
 
*If specific type is expected and that type is not available, the game with either crash or ignore that entire line.
 
*If specific type is expected and that type is not available, the game with either crash or ignore that entire line.
 
*TRUE and FALSE are stored as type 00 as '1' and '0' respectively.
 
*TRUE and FALSE are stored as type 00 as '1' and '0' respectively.
 +
*Commands 74h and A1h are never used, but have been documented as valid commands.
 +
*Commands 75h and 96h only appear in the Character AI found in the KERNEL.BIN.
 +
*Commands of group 2X, BX, CX, DX, EX, and FX are treated as NOPs. The script will ignore them and continue processing. Also, any 5X, 6X, 7X, 8X, and 9X value that isn't listed above appear to be treated the same way, but it's safest to use a value from the 2X group. An incorrect 0X, 1X, 3X, or 4X will have unintended side-effects.
 +
 +
0X & 1X CODES NOTES:
 +
*Valid values for X are 0, 1, 2, and 3.
 +
**These will store a bit, byte, word, and dword respectively.
  
 
3X CODES NOTES:
 
3X CODES NOTES:
Line 303: Line 323:
  
 
The pushed value is, thus, the MP cost of the defined ability as a type 02.  Note that 0x00 to 0xFF are standard magic and always loaded, while 0x100+ are the unique abilities loaded through scene.bin.
 
The pushed value is, thus, the MP cost of the defined ability as a type 02.  Note that 0x00 to 0xFF are standard magic and always loaded, while 0x100+ are the unique abilities loaded through scene.bin.
 +
 +
92 CODE NOTES:
 +
*Second pop must be one of the following:
 +
:[[FF7/Command_data|Command index]] in case of character AI
 +
:20h - For enemy attack
 +
:22h - Force execution of script (referenced by first pop)
 +
:24h - Pauses battle engine while string is displayed (in conjunction with code 93)

Latest revision as of 05:10, 23 May 2019

(Information on opcodes provided by Terence Fergusson. Almost all information comes from this post on the forums.)

There are four actions to be explained when dealing with any opcode in AI script: Arguments, Values to take from the stack, what to do with Arguments and Values, and what to put back on the stack. So to fully understand what is happening a brief explanation of the stack is necessary.

The stack is more-or-less a list of values with different lengths. Only the top of the stack (the most recently added value) can be accessed at any given time, but when that value is accessed it is removed from the top of the stack and the previously added value now becomes the top of the stack. Adding to the stack is called "Pushing" a value and taking a value off is called "Popping". When pushing a value to the stack, the value of the number is pushed followed by the value type. The value type can be one of three different things:

Code Type
0Xh Value
1Xh Address
2Xh Multiple (between 1-10) Values


They are stored as DWords, but the X will determine how many bytes to use: 0 = bit, 1 = Byte, 2 = Word, 3 = Three bytes

Now that we've seen the stack, here are the opcodes:

Code Arguments Value(s) to pop Value to push
Push Values
0Xh 2 byte Memory Address Type 0X stored at translated Address
Push Addresses
1Xh 2 byte Memory Address Address value with a scope of X
Mathematical and Bit-wise Operators
30h Two of any type Sum of pops
31h Two of any type Difference of pops
32h Two of any type Product of pops
33h Two of any type Quotient of pops
34h Two of any type Remainder from quotient of pops
35h Two of any type Bit-wise AND of pops
36h Two of any type Bit-wise OR of pops
37h One of any type Bit-wise NOT of pop
Logical Operators
40h Two of any type True if pops are EQUAL
41h Two of any type True if pops are NOT EQUAL
42h Two of any type True if first pop is GREATER THAN OR EQUAL TO second pop
43h Two of any type True if first pop is LESS THAN OR EQUAL TO second pop
44h Two of any type True if first pop is GREATER THAN second pop
45h Two of any type True if first pop is LESS THAN second pop
Logical Comparisons
50h Two of any type True if both pops are NON-ZERO (Logical AND)
51h Two of any type True if either pop is NON-ZERO (Logical OR)
52h One of any type True if pop is ZERO (Logical NOT)
Push Constants
60h 1 byte Value Argument of type 01
61h 2 byte Value Argument of type 02
62h 3 byte Value Argument of type 03
Script Jumps (No Pushes)
70h 2 byte Script Address One of any type Jumps to script address in argument if pop is 0
71h 2 byte Script Address One of any type Jumps to script address in argument if pop and top of stack are not equal
72h 2 byte Script Address Jumps to script address in argument
73h This ends the script
74h One of any type Pops one value from stack. (Not used)
75h One of any type Link all scripts of script owner to popped Character ID.
Bit Operations
80h Two of any type First pop masked by second pop
81h Random Word (0-65535)
82h One of any type Random bit of pop stored as type 02
83h One of any type If pop is Type 01, Type 01 with count of number of bits set in pop

If pop is Type 02, Type 02 filled with value of first non-null value in pop

84h One of type 2X Type 02 indicating which values in popped set were greatest
85h One of type 2X Type 02 indicating which values in popped set were least
86h One of type 1X Type 02 indicating MP Cost of attack index referenced in pop
87h One of any type Type 02 with only bit in pop turned on (1 << [pop])

 

Command
Code Arguments Value(s) to pop Effect
90h One of type 1X, One of type 0X or 2X If first pop < 4000h; Stores second pop at first pop
90h One of type 1X, One of type 0X or 2X, One of type 1X If first pop >= 4000h; Stores second pop at first pop constrained by mask at third pop
91h One of any type Pops one value from stack.
92h Two of any type First pop is attack ID to perform. Second pop action type
93h NULL terminated string Displays string
94h Two of any type Copy current status, hp and mp as well as some other specific data (like boosts, multipliers) from units in first given mask to units in second mask.
95h One of type 1X, one of type 00 If second pop is 1, takes value at local address 2010 and writes value at memory bank 1/2 at offset specified by first pop
If second pop is 0, data at memory bank1/2 at offset specified by first pop is stored at local address 2010.

Otherwise, command is ignored.

96h Two of any type Get fighter elemental defense.
A0h One byte, NULL terminated ASCII First argument of any type Displays string to debug console, replacing "%d"s with pops
A1h Two values of any type Pops two values from stack (Not Used, but valid command)


GENERAL NOTES:

  • Command 90h is overloaded.
  • If a type 2X is popped and any type is accepted, only the first value will be considered.
  • If specific type is expected and that type is not available, the game with either crash or ignore that entire line.
  • TRUE and FALSE are stored as type 00 as '1' and '0' respectively.
  • Commands 74h and A1h are never used, but have been documented as valid commands.
  • Commands 75h and 96h only appear in the Character AI found in the KERNEL.BIN.
  • Commands of group 2X, BX, CX, DX, EX, and FX are treated as NOPs. The script will ignore them and continue processing. Also, any 5X, 6X, 7X, 8X, and 9X value that isn't listed above appear to be treated the same way, but it's safest to use a value from the 2X group. An incorrect 0X, 1X, 3X, or 4X will have unintended side-effects.

0X & 1X CODES NOTES:

  • Valid values for X are 0, 1, 2, and 3.
    • These will store a bit, byte, word, and dword respectively.

3X CODES NOTES:

  • The pushed value is type 2x if either of the pops are a 1X or 2X. In that case, the Masks of both pops are ANDed together. In *all* cases, the highest pop's size is used to determine the new pop's size.

4X CODES NOTES:

  • The Pushed value will be type 00 if either component is a 1X or 2X type. It will only push TRUE or FALSE
  • If both were 0X types, the result will be a type 02 which contains the Mask of all the objects in the pops that passed the comparison

86 CODE NOTES:

  • This get the MP Cost of the ability referenced in the pop. The value of pop is referenced to the following areas:
 If Value >= 0xFFFF, return 0
 If Value <= 0x00FF, Addr = 00DAAC78 + Value*0x1C
 If Value >= 0x0100, match Value with wr[0099AAF4+(ID=[0..31])*2]
    First ID it matches, Addr = 0099A774 + ID*0x1C
 If no Addr is found, return 0
 Otherwise, return wr[Addr + 4]

The pushed value is, thus, the MP cost of the defined ability as a type 02. Note that 0x00 to 0xFF are standard magic and always loaded, while 0x100+ are the unique abilities loaded through scene.bin.

92 CODE NOTES:

  • Second pop must be one of the following:
Command index in case of character AI
20h - For enemy attack
22h - Force execution of script (referenced by first pop)
24h - Pauses battle engine while string is displayed (in conjunction with code 93)