Advertisement
ZoriaRPG

How to Add New ZScript Commands v2

Dec 14th, 2016
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.07 KB | None | 0 0
  1. //Add a new zscript instruction
  2.  
  3. //! Note: A ZASM instruction may ave a label of no more than 15 chars.
  4. // LINKPLAYWARPSOUND will return an error wen compiling
  5. // PLAYWARPSOUND is fine.
  6.  
  7. When adding to ( script_command command_list[NUMCOMMANDS+1] ) list, in ffasm.cpp, the ORDER of listing
  8. any new parameter MUST MATCH the order in ( ASM_DEFINE ) in file ffscript.h!
  9. This differs from script variables.
  10.  
  11.  
  12. //Drawing
  13.  
  14. Script_Drawing.cpp
  15. add function
  16. add opcode redirect with ZASM label
  17.  
  18. GlobalSymbols.cpp
  19.  
  20. Add table entry, with proper args values. The entry name should match the ZScript instruction.
  21. Add function to bind the name in the table to the O-Register
  22.  
  23. Bytecode.cpp
  24.  
  25. Add ORegister redirect that returns the ZASM instruction
  26.  
  27. Bytecode.h
  28.  
  29. Add class ORegister entry tat returns the opcode entry in Bytecode.cpp
  30.  
  31. ffasm.cpp
  32.  
  33. Add entry to script command list, using the ZASM label
  34.  
  35. ffscript.cpp
  36.  
  37. add case statement to switch(script_command) and ensure the args value matches that in GlobalSymbols.c[[
  38.  
  39. add case entry to switch(scommand), and ensure it is in the script commands case list
  40. Both of these use the ZASM label
  41.  
  42. ffscript.h
  43. Add the ZASM label to the ASM_DEFINE table.
  44.  
  45. //Link
  46.  
  47. Link.h
  48.  
  49. Add a new public variable if needed, suc as:
  50.     int linkdointhing
  51. (or)
  52. Find a public variable to use
  53. Add an empty function set (getter, setter) with the identifier that you desire, such as
  54.     int getLinkDoingThing()
  55.     void setLinkDoingThing(int value)
  56.    
  57. Add a clear instruction in the Init function:
  58.     linkdointhing = 0;
  59.  
  60. Link.cpp
  61. Create a pair of setter/getter functions tied to the link class, such as:
  62.  
  63.     //Return the variable using a getter.
  64.     int LinkClass::getLinkDoingThing()
  65.     {
  66.         return linkdointhing;
  67.     }
  68.  
  69.     //Set the variable using a setter
  70.     void LinkClass::setLinkDoingThing(int value)
  71.     {
  72.         linkdointhing=value;
  73.        
  74.     }
  75.  
  76. ! You can constrain the min and max values written with: vbound(int value, int min, int max)
  77.  
  78.     //Set the variable using a setter
  79.     void LinkClass::setLinkDoingThing(int value)
  80.     {
  81.         linkdointhing=vbound(value,0,3);
  82.        
  83.     }
  84.    
  85. ffasm.cpp
  86. Add an entry to the ( variable_list[] ) table, and introduce your ZASM keyword:
  87.     { "LINKDOTHING", LINKDOTHING, 0, 0 },
  88.     The first value is a string, that is matched wit the assembly, to the second value, called by GlobalSymbols.cpp.
  89.  
  90. ffscript.h
  91. Define the ZASM label and give it a unique numeric value. This is used by the wordtable to look it up.
  92.     #define LINKDOTHING           0x0300
  93. If you added something new, be sure to increase the value of NUMVARIABLES.
  94.  
  95.  
  96. ffscript.cpp
  97.  
  98.  
  99. in the ( long get_register(const long arg) switch(arg) ) STATEMENT, under 'Link's Variables' add a GETTER instruction case:
  100.     case LINKDOTHING:
  101.     ret=Link.getLinkDoingThing*10000; //THis points to the LinkClass::getWarpSound() function
  102.                     //Be sure to work with the ZScript 10,000 multplier!
  103.     break;
  104.  
  105. in the ( long set_register(const long arg) switch(arg) ) STATEMENT, under 'Link's Variables' add a SETTER instruction case:
  106.     case LINKDOTHING:
  107.     Link.getLinkDoingThing(value/10000); //THis points to the LinkClass::getWarpSound() function
  108.                     //Be sure to work with the ZScript 10,000 multplier!
  109.     break;
  110.  
  111. /parser/ByteCode.h
  112. Add a new definition with a unique value using your ZASM label.
  113. This DOES NOT need to match the word table ID tat you set earlier.
  114.     #define LINKDOTHING 401
  115.    
  116. /parser/ByteCode.cpp
  117.  
  118. in ( string VarArgument::toString() switch(ID) ) add a string redirect case for the ZASM label:
  119.  
  120.     case LINKDOTHING: //We the word table looks up the ZASM instruction and finds this...
  121.         return "LINKDOTHING"; //it returns this string.
  122.        
  123. /parser/GlobalSynbols.cpp
  124. in ( static AccessorTable LinkSTable[] ) add setter/getter entries.
  125.  
  126.  { "getDoThing",            ScriptParser::TYPE_FLOAT,         GETTER,       PLAYWARPSOUND,         1,      {  ScriptParser::TYPE_LINK,         -1,                               -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1                           } },
  127.     { "setDoThing",            ScriptParser::TYPE_VOID,          SETTER,       PLAYWARPSOUND,         1,      {  ScriptParser::TYPE_LINK,          ScriptParser::TYPE_FLOAT,        -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1,                           -1                           } },
  128.    
  129. The first etry on each line is te ZScript command token. The chars 'set' or 'get' in lowercase are removed, so
  130. getDoThing / setDoThing i the Link table becomes Link->DoThing in ZScript.
  131.  
  132. The second entry on eac line is the TYPE. Getters are typed by their return. Setters are void typed, but you
  133. must define the input type later.
  134. The third entry is the instruction type: SETTER, GETTER, or FUNCTION.
  135. The fourth, is the ZASM label.
  136. The fifth, is '1' unless you are creating a FUNCTION type.
  137. Following these, is a ScriptParser::Type. For Link->, this is always ScriptParser::TYPE_LINK
  138. Followin this, is the input parameters.
  139. For a return, these are always all -1.
  140. For a setter, the first is its value type (TYPE_FLOAT, or TYPE_BOOL).
  141. For a function, define each input parameter by its type.
  142.  
  143. You're done.
  144.  
  145. // Adding a Function
  146.  
  147. //From DarkDragon regarding the stack:
  148.     the ZScript calling convention is more or less equivalent to C's.
  149.     The caller first pushes the return address onto the stack, then all of the function's explicit
  150.     argument, and finally, if the function is a member function, the "this" pointer is implicitly
  151.     pushed as the last argument.
  152.  
  153.     The return value of the function is by convention stored in EXP1.
  154.  
  155.     The callee, then, before it can return, must pop all of the arguments (including the "this" pointer)
  156.     off of the stack. That's what the lines are doing that you've commented about. The ZASM instruction
  157.     uses the top 4 entries of the stack, but leaves them untouched, so ZScript pops them off, then pops
  158.     off the return address and jumps to it. You could use NUL instead of EXP2 for these pops if you wanted.
  159.  
  160.     The reason EXP2 is used as scratch space instead of EXP1 is simply to avoid accidentally tampering
  161.     with the return value of the function.
  162.  
  163. Addin a function requires some additional work, as follows:
  164.  
  165. ffasm.cpp
  166. Add a new entry at the END of the table ( script_command command_list[NUMCOMMANDS+1] ) with the following format
  167. ZASMLABEL, number_of_args_for_the_assembler, has_arg_1, has_arg_2, more (?what's this now)
  168.  
  169. These are used by the function: int set_argument(char *argbuf, ffscript **script, int com, int argument)
  170.  
  171. Note that entries often have an 'R" and a 'V', meaning Register, and Value. These are effectively, ( ) and ( ).
  172.  
  173. Keep a careful eye on the position of the function in this table, as it must match the position of their counterparts
  174.     in ( enum ASM_DEFINE ) inside ffscript.h.
  175.  
  176. ffscript.h
  177.  
  178. Add an entry into the ( enum ASM_DEFINE ) table to match each entry that you added in ffasm.cpp. |
  179. These must be in the same sequence.
  180.  
  181. ffscript.cpp
  182.  
  183. Add a function to which you wish to pair each entry that you created in ffasm.cpp/ffscript.h
  184.  
  185. ByteCode.cpp
  186.  
  187. Add a string redirect, ( string OIdentifier::toString() ) in the list after the ( switch(ID) ) statement
  188.     in ( string VarArgument::toString() )
  189.  
  190. ByteCode.h
  191.  
  192. Add a class definition, setting its identifier, public type (UnaryCode, BinaryCode, OpCode) and
  193.     set its instructions. Return it new if desired.
  194.  
  195. GlobalSymbols.cpp
  196. Insert the function into the table to which you desire to link it, based on the class to which you are assigning it.
  197.     Set its type to ScriptParser::TYPE, its use to FUNCTION, its 'va' to '0' (this is for a script class variable,
  198.     such as 'X' in 'Link->X'), its indices, its number_of_indices to -1 (these are for array script vars, such as
  199.     ComboD[]), its type/class association, then, one entry for each of its inputs by type.
  200.     Use -1 to fill in any unused inputs.
  201.  
  202. In the vector for its class (e.g. ScreenSymbols::addSymbolsCode), create a routine for it, using the existing entries as
  203. examples. This may require writing a new opcode, or you may be able to use stack registers directly, depending on how many
  204. values you need to parse, and your return types.
  205.  
  206. //Global
  207.  
  208.  
  209. //NPCs
  210.  
  211. //Weapons
  212.  
  213. //FFCs
  214.  
  215. //Items
  216.  
  217. //itemdata
  218. ref->info /The current, selected object int he struct is identified by *
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement