Difference between revisions of "ACS"

From OdaWiki
(Sources: Changed to just the text for the link)
(ACS Specifications: Linked below)
Line 1: Line 1:
 
ACS (Action Coding Script?) is a compiled scripting language that works along side with the Hexen map format.  The compiled scripts are stored in a map's BEHAVIOR lump in a binary format decoded by the zdoom/hexen engines.  '''The license the ACS interpreter was released under is not GPL complaint, so there is no ACS support in Odamex.'''  Here is some info I dug which can aid in rewriting the interpreter.
 
ACS (Action Coding Script?) is a compiled scripting language that works along side with the Hexen map format.  The compiled scripts are stored in a map's BEHAVIOR lump in a binary format decoded by the zdoom/hexen engines.  '''The license the ACS interpreter was released under is not GPL complaint, so there is no ACS support in Odamex.'''  Here is some info I dug which can aid in rewriting the interpreter.
  
== ACS Specifications ==
 
ACS File Format
 
---------------
 
(All numbers are little-endian and 32 bits long)
 
(Pointers are relative to the beginning of the lump)
 
  
{| border="1" width="75%"
 
!Bytes  0 - 3
 
|ACS\0' (0x00534341)
 
|-
 
!Bytes  4 - 7
 
|Pointer to script and text pointers
 
|-
 
!Bytes  8 -...
 
|Varies
 
|}
 
 
-------------
 
Pointer Table
 
-------------
 
The first dword is a count of the number of scripts in the lump. It is
 
immediately followed by an entry for each script in the lump. These
 
entries are of the format:
 
 
DWORD 0 This script's number
 
DWORD 1 A pointer to the start of the script
 
DWORD 2 The number of parameters the script accepts
 
 
These are then followed by a dword indicating how many different strings
 
are in the script. The remaining dwords contain pointers to each of the
 
strings.
 
 
------------
 
Script Codes
 
------------
 
Compiled ACS scripts do not distinguish between their arguments and
 
their local variables. When a script is executed, it's parameters
 
are copied to its first x local variables, where x is the number of
 
parameters the script takes. The ACC compiler will output an error
 
for any script with more than 10 local variables (including
 
parameters), so it's probably safe to allocate enough space for only
 
10 variables in an ACS interpreter.
 
 
There are 64 world variables available (numbered 0-63) that are
 
accessible from scripts executed from any map in a single hub. Each
 
map can also have 32 map variables accessible to all scripts in that
 
map, but not by scripts in other maps.
 
 
ACS's internal functions are actually opcodes. Some use arguments on
 
the stack, and others have their arguments immediately following them
 
in the code. For those that use arguments on the stack, the arguments
 
are first pushed on to the stack in sequence, and then the function's
 
opcode is stored. If the function uses a string as an argument, then
 
the string's index is pushed onto the stack as a number. Functions
 
are responsible for popping the arguments passed to them before they
 
return. The first value pushed is the function's first parameter, the
 
second value pushed is the second parameter, etc.
 
 
    #0: PCD_NOP
 
    #1: PCD_TERMINATE
 
    #2: PCD_SUSPEND
 
    #3: PCD_PUSHNUMBER x
 
    #4: PCD_LSPEC1 x
 
    #5: PCD_LSPEC2 x
 
    #6: PCD_LSPEC3 x
 
    #7: PCD_LSPEC4 x
 
    #8: PCD_LSPEC5 x
 
    #9: PCD_LSPEC1DIRECT x a
 
  #10: PCD_LSPEC2DIRECT x a b
 
  #11: PCD_LSPEC3DIRECT x a b c
 
  #12: PCD_LSPEC4DIRECT x a b c d
 
  #13: PCD_LSPEC5DIRECT x a b c d e
 
  #14: PCD_ADD
 
  #15: PCD_SUBTRACT
 
  #16: PCD_MULTIPLY
 
  #17: PCD_DIVIDE
 
  #18: PCD_MODULUS
 
  #19: PCD_EQ
 
  #20: PCD_NE
 
  #21: PCD_LT
 
  #22: PCD_GT
 
  #23: PCD_LE
 
  #24: PCD_GE
 
  #25: PCD_ASSIGNSCRIPTVAR x
 
  #26: PCD_ASSIGNMAPVAR x
 
  #27: PCD_ASSIGNWORLDVAR x
 
  #28: PCD_PUSHSCRIPTVAR x
 
  #29: PCD_PUSHMAPVAR x
 
  #30: PCD_PUSHWORLDVAR x
 
  #31: PCD_ADDSCRIPTVAR x
 
  #32: PCD_ADDMAPVAR x
 
  #33: PCD_ADDWORLDVAR x
 
  #34: PCD_SUBSCRIPTVAR x
 
  #35: PCD_SUBMAPVAR x
 
  #36: PCD_SUBWORLDVAR x
 
  #37: PCD_MULSCRIPTVAR x
 
  #38: PCD_MULMAPVAR x
 
  #39: PCD_MULWORLDVAR x
 
  #40: PCD_DIVSCRIPTVAR x
 
  #41: PCD_DIVMAPVAR x
 
  #42: PCD_DIVWORLDVAR x
 
  #43: PCD_MODSCRIPTVAR x
 
  #44: PCD_MODMAPVAR x
 
  #45: PCD_MODWORLDVAR x
 
  #46: PCD_INCSCRIPTVAR x
 
  #47: PCD_INCMAPVAR x
 
  #48: PCD_INCWORLDVAR x
 
  #49: PCD_DECSCRIPTVAR x
 
  #50: PCD_DECMAPVAR x
 
  #51: PCD_DECWORLDVAR x
 
  #52: PCD_GOTO x
 
  #53: PCD_IFGOTO x
 
  #54: PCD_DROP
 
  #55: PCD_DELAY
 
  #56: PCD_DELAYDIRECT x
 
  #57: PCD_RANDOM
 
  #58: PCD_RANDOMDIRECT x y
 
  #59: PCD_THINGCOUNT
 
  #60: PCD_THINGCOUNTDIRECT x y
 
  #61: PCD_TAGWAIT
 
  #62: PCD_TAGWAITDIRECT x
 
  #63: PCD_POLYWAIT
 
  #64: PCD_POLYWAITDIRECT x
 
  #65: PCD_CHANGEFLOOR
 
  #66: PCD_CHANGEFLOORDIRECT x y
 
  #67: PCD_CHANGECEILING
 
  #68: PCD_CHANGECEILINGDIRECT x y
 
  #69: PCD_RESTART
 
  #70: PCD_ANDLOGICAL
 
  #71: PCD_ORLOGICAL
 
  #72: PCD_ANDBITWISE
 
  #73: PCD_ORBITWISE
 
  #74: PCD_EORBITWISE
 
  #75: PCD_NEGATELOGICAL
 
  #76: PCD_LSHIFT
 
  #77: PCD_RSHIFT
 
  #78: PCD_UNARYMINUS
 
  #79: PCD_IFNOTGOTO x
 
  #80: PCD_LINESIDE
 
  #81: PCD_SCRIPTWAIT
 
  #82: PCD_SCRIPTWAITDIRECT x
 
  #83: PCD_CLEARLINESPECIAL
 
  #84: PCD_CASEGOTO x y
 
  #85: PCD_BEGINPRINT
 
  #86: PCD_ENDPRINT
 
  #87: PCD_PRINTSTRING
 
  #88: PCD_PRINTNUMBER
 
  #89: PCD_PRINTCHARACTER
 
  #90: PCD_PLAYERCOUNT
 
  #91: PCD_GAMETYPE
 
  #92: PCD_GAMESKILL
 
  #93: PCD_TIMER
 
  #94: PCD_SECTORSOUND
 
  #95: PCD_AMBIENTSOUND
 
  #96: PCD_SOUNDSEQUENCE
 
  #97: PCD_SETLINETEXTURE
 
  #98: PCD_SETLINEBLOCKING
 
  #99: PCD_SETLINESPECIAL
 
  #100: PCD_THINGSOUND
 
  #101: PCD_ENDPRINTBOLD
 
 
*1: PCD_TERMINATE
 
    Terminates script execution.
 
 
*3: PCD_PUSHNUMBER x
 
    Push x onto the stack.
 
 
*4: PCD_LSPEC1 x
 
    Execute line special x. It takes one argument on the stack.
 
 
*5: PCD_LSPEC2 x
 
    Execute line special x. It takes two arguments on the stack.
 
 
*6: PCD_LSPEC3 x
 
    Execute line special x. It takes three argument on the stack.
 
 
*7: PCD_LSPEC4 x
 
    Execute line special x. It takes four argument on the stack.
 
 
*8: PCD_LSPEC5 x
 
    Execute line special x. It takes five argument on the stack.
 
 
*9: PCD_LSPEC1DIRECT x a
 
    Execute line special x (a).
 
 
*10: PCD_LSPEC2DIRECT x a b
 
 
    Execute line special x (a, b).
 
 
*11: PCD_LSPEC3DIRECT x a b c
 
 
    Execute line special x (a, b, c).
 
 
*12: PCD_LSPEC4DIRECT x a b c d
 
 
    Execute line special x (a, b, c, d).
 
 
*13: PCD_LSPEC5DIRECT x a b c d e
 
 
    Execute line special x (a, b, c, d, e).
 
 
*14: PCD_ADD
 
 
    Stack before:
 
        int val1
 
        int val2
 
   
 
    Stack after:
 
        int (val1 + val2)
 
 
*15: PCD_SUBTRACT
 
 
    Stack before:
 
        int val1
 
        int val2
 
   
 
    Stack after:
 
        int (val1 - val2)
 
 
*16: PCD_MULTIPLY
 
 
    Stack before:
 
        int val1
 
        int val2
 
   
 
    Stack after:
 
        int (val1 * val2)
 
 
*17: PCD_DIVIDE
 
 
    Stack before:
 
        int val1
 
        int val2
 
   
 
    Stack after:
 
        int (val1 / val2)
 
 
*18: PCD_MODULUS
 
 
    Stack before:
 
        int val1
 
        int val2
 
   
 
    Stack after:
 
        int (val1 % val2)
 
 
*19: PCD_EQ
 
 
    Stack before:
 
        int val1
 
        int val2
 
   
 
    Stack after:
 
        (val1 == val2)
 
 
*20: PCD_NE
 
 
    Stack before:
 
        int val1
 
        int val2
 
   
 
    Stack after:
 
        (val1 != val2)
 
 
*21: PCD_LT
 
 
    Stack before:
 
        int val1
 
        int val2
 
   
 
    Stack after:
 
        (val1 < val2)
 
 
*22: PCD_GT
 
 
    Stack before:
 
        int val1
 
        int val2
 
   
 
    Stack after:
 
        (val1 > val2)
 
 
*23: PCD_LE
 
 
    Stack before:
 
        int val1
 
        int val2
 
   
 
    Stack after:
 
        (val1 <= val2)
 
 
*24: PCD_GE
 
 
    Stack before:
 
        int val1
 
        int val2
 
   
 
    Stack after:
 
        (val1 >= val2)
 
 
*25: PCD_ASSIGNSCRIPTVAR x
 
 
    Stack before:
 
        int val
 
   
 
    Store val in script var x.
 
 
*26: PCD_ASSIGNMAPVAR x
 
 
    Stack before:
 
        int val
 
   
 
    Store val in map var x.
 
 
*27: PCD_ASSIGNWORLDVAR x
 
 
    Stack before:
 
        int val
 
   
 
    Store val in world var x.
 
 
*28: PCD_PUSHSCRIPTVAR x
 
 
    Push value of script var x onto the stack.
 
 
*29: PCD_PUSHMAPVAR x
 
   
 
    Push value of map var x onto the stack.
 
 
*30: PCD_PUSHWORLDVAR x
 
 
    Push value of world var x onto the stack.
 
 
*31: PCD_ADDSCRIPTVAR x
 
 
    Stack before:
 
        int val
 
   
 
    script var x += val
 
 
*32: PCD_ADDMAPVAR x
 
 
    Stack before:
 
        int val
 
   
 
    map var x += val
 
 
*33: PCD_ADDWORLDVAR x
 
 
    Stack before:
 
        int val
 
   
 
    world var x += val
 
 
*34: PCD_SUBSCRIPTVAR x
 
 
    Stack before:
 
        int val
 
   
 
    script var x -= val
 
 
*35: PCD_SUBMAPVAR x
 
 
    Stack before:
 
        int val
 
   
 
    map var x -= val
 
 
*36: PCD_SUBWORLDVAR x
 
 
    Stack before:
 
        int val
 
   
 
    world var x -= val
 
 
*37: PCD_MULSCRIPTVAR x
 
 
    Stack before:
 
        int val
 
   
 
    script var x *= val
 
 
*38: PCD_MULMAPVAR x
 
 
    Stack before:
 
        int val
 
   
 
    map var x *= val
 
 
*39: PCD_MULWORLDVAR x
 
 
    Stack before:
 
        int val
 
   
 
    world var x *= val
 
 
*40: PCD_DIVSCRIPTVAR x
 
 
    Stack before:
 
        int val
 
   
 
    script var x /= val
 
 
*41: PCD_DIVMAPVAR x
 
 
    Stack before:
 
        int val
 
   
 
    map var x /= val
 
 
*42: PCD_DIVWORLDVAR x
 
 
    Stack before:
 
        int val
 
   
 
    world var x /= val
 
 
*43: PCD_MODSCRIPTVAR x
 
 
    Stack before:
 
        int val
 
   
 
    script var x %= val
 
 
*44: PCD_MODMAPVAR x
 
 
    Stack before:
 
        int val
 
   
 
    map var x %= val
 
 
*45: PCD_MODWORLDVAR x
 
 
    Stack before:
 
        int val
 
   
 
    world var x %= val
 
 
*46: PCD_INCSCRIPTVAR x
 
 
    script var x += 1
 
 
*47: PCD_INCMAPVAR x
 
 
    map var x += 1
 
 
*48: PCD_INCWORLDVAR x
 
 
    world var x += 1
 
 
*49: PCD_DECSCRIPTVAR x
 
 
    script var x -= 1
 
 
*50: PCD_DECMAPVAR x
 
 
    map var x -= 1
 
 
*51: PCD_DECWORLDVAR x
 
 
    world varx -= 1
 
 
*52: PCD_GOTO x
 
 
    Jump to offset x (relative to beginning of object file).
 
 
*53: PCD_IFGOTO x
 
 
    Stack before:
 
        int boolean
 
   
 
    If the boolean is true, jump to offset x.
 
 
*54: PCD_DROP
 
 
    Stack before:
 
        int anything
 
   
 
    Pop one number off the stack and discard it.
 
 
*55: PCD_DELAY
 
 
    Stack before:
 
        int tics
 
   
 
    Pop a number off the stick and delay for that many tics.
 
 
*56: PCD_DELAYDIRECT x
 
 
    Delay for x tics.
 
 
*57: PCD_RANDOM
 
 
    Stack before:
 
        int minval
 
        int maxval
 
   
 
    Stack after:
 
        int random(minval, maxval)
 
 
*58: PCD_RANDOMDIRECT x y
 
 
    Stack after:
 
        int random(x, y)
 
 
*59: PCD_THINGCOUNT
 
 
    Stack before:
 
        int type
 
        int tid
 
   
 
    Stack after:
 
        int thingcount(type,tid)
 
 
*60: PCD_THINGCOUNTDIRECT x y
 
 
    Stack after:
 
        int thingcount(x, y)
 
 
*61: PCD_TAGWAIT
 
 
    Stack before:
 
        int tag
 
   
 
    Pops a tag value off the stack and suspends execution of the current
 
    script until all sectors with a matching tag value are inactive.
 
 
*62: PCD_TAGWAITDIRECT x
 
 
    Waits for all sectors with tag x to become inactive before continuing
 
    execution of the current script.
 
 
*63: PCD_POLYWAIT
 
 
    Stack before:
 
        int po
 
   
 
    Suspends execution of the current script until polyobj po is inactive.
 
 
*64: PCD_POLYWAITDIRECT x
 
 
    Suspends execution of the current script until polyobj x is inactive.
 
 
*65: PCD_CHANGEFLOOR
 
 
    Stack before:
 
        int tag
 
        str flatname
 
   
 
    Sets the floor flat of all sectors tagged with tag to flatname.
 
 
*66: PCD_CHANGEFLOORDIRECT x y
 
 
    Sets the floor flat of all sectors tagged with x to y.
 
 
*67: PCD_CHANGECEILING
 
 
    Stack before:
 
        int tag
 
        str flatname
 
   
 
    Sets the ceiling flat of all sectors tagged with tag to flatname.
 
 
*68: PCD_CHANGECEILINGDIRECT x y
 
 
    Sets the ceiling flat of all sectors tagged with x to y.
 
 
*69: PCD_RESTART
 
 
    Restart execution of the current script from the beginning.
 
 
*70: PCD_ANDLOGICAL
 
 
    Stack before:
 
        int boolean1
 
        int boolean2
 
   
 
    Stack after:
 
        (boolean1 && boolean2)
 
 
*71: PCD_ORLOGICAL
 
 
    Stack before:
 
        int boolean1
 
        int boolean2
 
   
 
    Stack after:
 
        (boolean1 || boolean2)
 
 
*72: PCD_ANDBITWISE
 
 
    Stack before:
 
        int param1
 
        int param2
 
   
 
    Stack after
 
        int (param1 & param2)
 
 
*73: PCD_ORBITWISE
 
 
    Stack before:
 
        int param1
 
        int param2
 
   
 
    Stack after:
 
        int (param1 | param2)
 
 
*74: PCD_EORBITWISE
 
 
    Stack before:
 
        int param1
 
        int param2
 
   
 
    Stack after:
 
        int (param1 ^ param2)
 
 
*75: PCD_NEGATELOGICAL
 
 
    Stack before:
 
        int val
 
   
 
    Stack after:
 
        int (!val)
 
 
*76: PCD_LSHIFT
 
 
    Stack before:
 
        int a
 
        int b
 
   
 
    Stack after:
 
        int (a << b)
 
 
*77: PCD_RSHIFT
 
 
    Stack before:
 
        int a
 
        int b
 
   
 
    Stack after:
 
        int (a >> b)
 
 
*78: PCD_UNARYMINUS
 
 
    Stack before:
 
        int val
 
   
 
    Stack after:
 
        int (-val)
 
 
*79: PCD_IFNOTGOTO x
 
 
    Stack before:
 
        int boolean
 
   
 
    If boolean is false, jump to offset x.
 
 
*80: PCD_LINESIDE
 
 
    Stack after:
 
        int lineside
 
   
 
    lineside is a numerical parameter indicating which side of the line
 
    activated this script.
 
 
*81: PCD_SCRIPTWAIT
 
 
    Stack before:
 
        int scr
 
   
 
    Suspend execution of the current script until script scr has
 
    terminated.
 
 
*82: PCD_SCRIPTWAITDIRECT x
 
 
    Suspend execution of the current script until script x has
 
    terminated.
 
 
*83: PCD_CLEARLINESPECIAL
 
 
    Clears the special of the activating line.
 
 
*84: PCD_CASEGOTO x y
 
 
    Stack before:
 
        int val
 
   
 
    Stack after:
 
        int val (if not taken)
 
 
    If the val == x, pop it and jump to offset y.
 
 
*85: PCD_BEGINPRINT
 
 
    Prepare to build a string to output to the screen by creating a new
 
    empty working string.
 
 
*86: PCD_ENDPRINT
 
 
    Output the current working string to the local machine's screen.
 
 
*87: PCD_PRINTSTRING
 
 
    Stack before:
 
        str string
 
   
 
    Pop a string index off the stack and append it to the current
 
    working string.
 
 
*88: PCD_PRINTNUMBER
 
 
    Stack before:
 
        int num
 
   
 
    Append num to the current working string in its ASCII representation.
 
 
*89: PCD_PRINTCHARACTER
 
 
    Stack before:
 
        int char
 
   
 
    Append the ASCII character char to the current working string.
 
 
*90: PCD_PLAYERCOUNT
 
 
    Stack after:
 
        int playercount
 
   
 
    playercount is the number of players in the game.
 
 
*91: PCD_GAMETYPE
 
 
    Stack after:
 
        int gametype
 
   
 
    gametype represents the current game type.
 
 
*92: PCD_GAMESKILL
 
 
    Stack after:
 
        int gameskill
 
   
 
    gameskill is the current game skill.
 
 
*93: PCD_TIMER
 
 
    Stack after:
 
        int gametime
 
   
 
    gametime is the current level time in tics.
 
 
*94: PCD_SECTORSOUND
 
 
    Stack before:
 
        str name
 
        int volume
 
   
 
    Pops two values off the stack and plays a sound in the sector
 
    pointed at by this script's activating linedef.
 
 
*95: PCD_AMBIENTSOUND
 
 
    Stack before:
 
        str snd
 
        int vol
 
   
 
    Plays the sound snd at volume vol (0-127) on the local machine.
 
 
*96: PCD_SOUNDSEQUENCE
 
 
    Stack before:
 
        str seq
 
   
 
    Plays the sound sequence seq in the facing sector.
 
 
*97: PCD_SETLINETEXTURE
 
 
    Stack before:
 
        int line
 
        int side
 
        int position
 
        str texturename
 
 
*98: PCD_SETLINEBLOCKING
 
 
    Stack before:
 
        int line
 
        int blocking
 
 
*99: PCD_SETLINESPECIAL
 
 
    Stack before:
 
        int line
 
        int special
 
        int arg1
 
        int arg2
 
        int arg3
 
        int arg4
 
        int arg5
 
   
 
    Sets the line special and args for all matching lines.
 
 
*100: PCD_THINGSOUND
 
 
    Stack before:
 
        int tid
 
        str name
 
        int volume
 
 
    Plays a sound at all things marked with tid.
 
 
*101: PCD_ENDPRINTBOLD
 
 
    Print the current working string to the screen of all computers in
 
    the game.
 
  
 
== Sources ==
 
== Sources ==
 
http://odamex.net/doc/thirdparty/acsspec.txt - Unspecified author, found in the zdoom utilities source.
 
http://odamex.net/doc/thirdparty/acsspec.txt - Unspecified author, found in the zdoom utilities source.

Revision as of 22:59, 19 November 2006

ACS (Action Coding Script?) is a compiled scripting language that works along side with the Hexen map format. The compiled scripts are stored in a map's BEHAVIOR lump in a binary format decoded by the zdoom/hexen engines. The license the ACS interpreter was released under is not GPL complaint, so there is no ACS support in Odamex. Here is some info I dug which can aid in rewriting the interpreter.


Sources

http://odamex.net/doc/thirdparty/acsspec.txt - Unspecified author, found in the zdoom utilities source.