Difference between revisions of "ActionD"

From GRFSpecs
Jump to navigationJump to search
 
(wording)
 
(14 intermediate revisions by 4 users not shown)
Line 1: Line 1:
  +
== Introduction ==
   
'''''Assign parameters and calculate results'''''
 
 
=Action D=
 
   
 
Assign parameters and calculate results.
 
Assign parameters and calculate results.
   
{maketoc}
 
   
-=Introduction=-
 
   
 
Action D allows you to set the value of grf parameter (i.e. those usually set as options in the newgrf(w).cfg file), as well as do math on them.
 
Action D allows you to set the value of grf parameter (i.e. those usually set as options in the newgrf(w).cfg file), as well as do math on them.
   
  +
== Syntax ==
-=Format=-
 
   
 
The data looks as follows:
 
The data looks as follows:
   
<pre> -+&lt;Sprite-number&gt; * &lt;Length&gt; 0D &lt;target&gt; &lt;operation&gt; &lt;source1&gt; &lt;source2&gt; <nowiki><nowiki>[&lt;data&gt;]</nowiki></nowiki>+-</pre>
+
<Sprite-number> * <Length> 0D <target> <operation> <source1> <source2> [<data>]
   
  +
{|
||'''Element'''|[[GRFActionsDetailed|'''Size''']]|'''Description'''
 
  +
!Element!![[GRFActionsDetailed|Size]]!!Description
   
  +
|-
&lt;Sprite-number&gt;|dec|A sequential sprite number
 
  +
|<Sprite-number>||dec||A sequential sprite number
   
  +
|-
&lt;length&gt;|dec|The total number of bytes used in this action
 
  +
|<length>||dec||The total number of bytes used in this action
   
  +
|-
0D|B|Defines action 0D
 
  +
|0D||B||Defines action 0D
   
  +
|-
&lt;target&gt;|B|Target parameter
 
  +
|<target>||B||Target parameter
   
  +
|-
&lt;operation&gt;|B|Calculation to carry out
 
  +
|<operation>||B||Calculation to carry out
   
  +
|-
&lt;source1&gt;|B|First argument
 
  +
|<source1>||B||First argument
   
  +
|-
&lt;source2&gt;|B|Second argument
 
  +
|<source2>||B||Second argument
   
  +
|-
&lt;data&gt;|D|Value to use as source if not parameter||
 
  +
|<data>||D||Value to use as source if not parameter
  +
|}
   
  +
== Description ==
-=Filling in the terms=-
 
   
===target, source1, source2===
+
=== target, source1, source2 ===
   
These bytes specify the target parameter and source parameters. &nbsp;They can either be simply the numbers of grf parameters, or they can be the special variables from [[Action7|action 7]], see the description of param-num there.
+
These bytes specify the target parameter and source parameters. They can either be simply the numbers of grf parameters, or they can be a [[GlobalVariables| global variable]].
   
  +
If either source1 or source2 is FF, the value from <data> is used instead of a parameter value.
Note that the only special variables which may be given as target are listed below, all others should be considered read-only.
 
   
  +
If <source2> is FE, then this action D will perform one of the following special variable accesses. In this case, <operation> must be assignment and <data> is an argument to the data access, not a source value.
If either source1 or source2 is FF, the value from &lt;data&gt; is used instead of a parameter value.
 
   
  +
* [[ReadingOtherGRFParameters | Read parameters of another GRF]]
If &lt;source2&gt; is FE, then this action D will perform one of the following special variable accesses. In this case, &lt;operation&gt; must be assignment and &lt;data&gt; is an argument to the data access, not a source value.
 
  +
* [[ReadingPatchVariables | Read game configuration settings]]
  +
* [[GRFResourceManagement | Reserve GRF resources to prevent conflicts with other GRFs]]
   
  +
=== operation ===
{toc}
 
   
  +
The operation to carry out on the source arguments. This byte has an escape sequence for each of its possible values, as listed below. See [[GRFActionsDetailed#Byte order|the discussion of escape sequences]] for further information on escape sequences in general. The result of this calculation will be stored in the target parameter.
===operation===
 
   
  +
{|
The operation to carry out on the source arguments. This byte has an escape sequence for each of its possible values, as listed below. See [[GRFActionsDetailed#Byte_order|the discussion of escape sequences]] for further information on escape sequences in general. The result of this calculation will be stored in the target parameter.
 
  +
!Operation!!Escape!!Version!!Name!!Result
   
  +
|-
||Operation|Escape|Name|Result
 
  +
|00||\D=||{{ottdp| | }}||Assignment||target = source1
   
  +
|-
00|\D=|Equal|target = source1
 
  +
|01||\D+||{{ottdp| | }}||Addition||target = source1 + source2
   
  +
|-
01|\D+|Addition|target = source1 + source2
 
  +
|02||\D-||{{ottdp| | }}||Subtraction||target = source1 - source2
   
  +
|-
02|\D-|Subtraction|target = source1 - source2
 
  +
|03||\Du*||{{ottdp| | }}||Unsigned multiplication||target = source1 * source2, with both sources being considered to be unsigned
   
  +
|-
03|\Du*|Unsigned multiplication|target = source1 * source2, with both sources being considered to be unsigned
 
  +
|04||\D*||{{ottdp| | }}||Signed multiplication||target = source1 * source2, with both sources considered signed
   
  +
|-
04|\D*|Signed multiplication|target = source1 * source2, with both sources considered signed
 
  +
|05||\Du<<||{{ottdp| | }}||Unsigned bit shift||target = source1 << source2 if source2>0, or target = source1 >> abs(source2) if source2 < 0. source1 is considered to be unsigned
   
  +
|-
05|\Du&lt;&lt;|Unsigned bit shift|target = source1 &lt;&lt; source2 if source2&gt;0, or target = source1 &gt;&gt; abs(source2) if source2 &lt; 0. source1 is considered to be unsigned
 
  +
|06||\D<<||{{ottdp| | }}||Signed bit shift||same as 05, but source1 is considered signed)
   
  +
|-
06|\D&lt;&lt;|Signed bit shift|same as 05, but source1 is considered signed)
 
  +
|07||\D&||{{ottdp| |2.5|ttdprev=alpha 48}}||Bitwise AND||target = source1 AND source2
   
  +
|-
07|\D&|Bitwise AND*|target = source1 AND source2
 
  +
|08||\D||{{ottdp| |2.5|ttdprev=alpha 48}}|||Bitwise OR||target = source1 OR source2
   
  +
|-
08|\D<nowiki><nowiki>|</nowiki></nowiki>|Bitwise OR*|target = source1 OR source2
 
  +
|09||\Du/||{{ottdp| |2.5|ttdprev=alpha 59}}||Unsigned division||target = source1 / source2
   
  +
|-
09|\Du/|Unsigned division**|target = source1 / source2
 
  +
|0A||\D/||{{ottdp| |2.5|ttdprev=alpha 59}}||Signed division||target = source1 / source2
   
  +
|-
0A|\D/|Signed division**|target = source1 / source2
 
  +
|0B||\Du%||{{ottdp| |2.5|ttdprev=alpha 59}}||Unsigned modulo||target = source1 % source2
   
  +
|-
0B|\Du%|Unsigned modulo**|target = source1 % source2
 
  +
|0C||\D%||{{ottdp| |2.5|ttdprev=alpha 59}}||Signed modulo||target = source1 % source2
  +
|}
   
  +
You can add 80 to the operation number to make it apply only if the target is not defined yet. In this respect, a parameter is taken to be defined if any of the following applies:
0C|\D%|Signed modulo**|target = source1 % source2||
 
 
<nowiki><nowiki>*</nowiki></nowiki> Only available in 2.0.1 alpha 48 &nbsp;or higher
 
 
<nowiki><nowiki>**</nowiki></nowiki> Only available in 2.0.1 alpha 59 &nbsp;or higher
 
 
You can add 80 to the operation number to make it apply only if the target is not defined yet. &nbsp;In this respect, a parameter is taken to be defined if any of the following applies:
 
 
* it has been set to any value in the newgrf(w).cfg parameter list
 
* it has been set to any value in the newgrf(w).cfg parameter list
 
* it '''or a parameter with higher number''' has been set to any value by an earlier action D
 
* it '''or a parameter with higher number''' has been set to any value by an earlier action D
Line 92: Line 109:
 
If, for example, parameters 0 and 1 are set in the newgrf(w).cfg file, and action D sets parameter 4, then parameters 2 and 3 automatically become defined and get a value of zero.
 
If, for example, parameters 0 and 1 are set in the newgrf(w).cfg file, and action D sets parameter 4, then parameters 2 and 3 automatically become defined and get a value of zero.
   
==Notes==
+
=== Notes ===
   
You can do a bitwise NOT of &lt;param&gt; by calculating &quot;-1 - &lt;param&gt;&quot;, i.e. operation=02, source1=FF, source2=param, data=FF FF FF FF.
+
You can do a bitwise NOT of <param> by calculating "-1 - <param>", i.e. operation=02, source1=FF, source2=param, data=FF FF FF FF.
   
 
The target operand can also refer to the special variables from action 7, see below for the list of variables that it is valid to write to.
 
The target operand can also refer to the special variables from action 7, see below for the list of variables that it is valid to write to.
Line 100: Line 117:
 
Because the patch has to reallocate memory for the whole parameter list whenever a new parameter is added, you should set the parameter with the highest number first (whenever possible, at least) so that all memory can be allocated right away.
 
Because the patch has to reallocate memory for the whole parameter list whenever a new parameter is added, you should set the parameter with the highest number first (whenever possible, at least) so that all memory can be allocated right away.
   
Note that parameters are never reset after the game has started, therefore you must not modify newgrf(w).cfg parameters with any kind of irreversible operation. &nbsp;It is valid to, for example, add a value to a parameter only if the same value is later subtracted, to keep the parameter the same across loading or starting several games.
+
Note that parameters are never reset after the game has started, therefore you must not modify newgrf(w).cfg parameters with any kind of irreversible operation. It is valid to, for example, add a value to a parameter only if the same value is later subtracted, to keep the parameter the same across loading or starting several games.
 
==Writable variables (global)==
 
 
The following global variables can be written to:
 
 
||Variable|Size(*)|Meaning
 
 
8E|B|Y-Offset for train sprites
 
 
8F|3*B|Rail track type cost factors
 
 
93|W|Tile refresh offset to left
 
 
94|W|Tile refresh offset to right
 
 
95|W|Tile refresh offset upwards
 
 
96|W|Tile refresh offset downwards
 
 
97|B|Snow line height
 
 
99|D|Global ID offset
 
 
9E|D|Misc. GRF Features
 
 
9F|D|Locale-dependent settings||
 
 
(*) Action D only supports writing dword values. The size given here is merely used to convey how much of that dword value will be used by the game, i.e. what the maximum value is.
 
 
===Y-Offset for train sprites (8E)===
 
 
Since train sprites must normally have the same offsets on the map and in the depot view, they will appear either too low on the map or too high in the depot view. &nbsp;This variable moves all vehicles in the depot view down by this many pixels.
 
 
===Rail track type cost factors (8F)===
 
 
This variable is a collection of three bytes that are used as multipliers for track costs when the &quot;trackcostdiff&quot; switch is on. &nbsp;The value of 08 is the baseline value that is used by standard TTD.
 
 
The defaults are the following:
 
 
||Values|Track types|Electrified railways setting
 
 
08, 10, 18|Regular, Monorail, Maglev|off
 
 
08, 0D, 10|Regular, Electric, Monorail/Maglev|on||
 
 
===Tile refresh offsets (93, 94, 95, 96)===
 
 
These four offsets define the size and position of the rectangle refreshed when TTD decides to refresh a tile. The basis of the calculations is the pixel coordinate of the north corner of the tile.
 
 
After calculating it, TTD subtracts offset_left from it to get the x coordinate of the left edge, adds offset_right to get the x coordinate of the right edge, subtracts offset_up to get the y coordinate of the top edge and adds offset_down to get the y coordinate of the bottom edge. This results in refreshing (offset_left+offset_right)*(offset_up+offset_down) pixels. The default values of these variables are 31, 36, 122 and 32, respectively.
 
 
Reading these values is not too useful, but you can modify them using action D as well, so your sprites that would exceed the original limits can still be redrawn and animated properly. Please note that TTD uses these values for every tile, so specifying too high values may slow the game down. Please also note that these variables are specified as dwords for technical reasons, but only the bottom word will be used.
 
 
Since these values are global to the entire game, you shouldn't just overwrite them with an action D. Instead, you should first check if they're big enough for you by using action 7, and skip your action D if they are. This way, the variables will be set to the maximal value needed, not just the value needed for the last grf in the list.
 
 
===Snow line height (97)===
 
 
This is only active if the tempsnowline switch is on. It defaults to FF (no snow) and 38 in the temperate and arctic climates, respectively. It must be set to a multiple of 8, which is one level of height difference.
 
 
===Global ID offset (99)===
 
 
Setting this variable will add the given value to all the relevant IDs in subsequent action 0, action 3 (''except'' livery overrides), action 4 (''except'' generic texts) and action A entries. This is a more convenient way of applying the result of a GRF resource request. Setting this variable applies only to the current .grf file only.
 
 
In detail, it affects the following elements:
 
 
||Action|Element modified
 
 
0|-+&lt;Id&gt;+- (i.e., not property numbers)
 
 
3|-+&lt;Ids...&gt;+- (i.e., not cargo types or cargo IDs, also not for livery overrides)
 
 
4|-+&lt;Offset&gt;+- (not for generic texts, though)
 
 
A|-+&lt;First-sprite&gt;+-||
 
 
===Misc. GRF Features (9E)===
 
 
This variable is a global bit mask of various patch features a grf file can enable. &nbsp;Please only set the bits using operation 08 (bitwise OR), or, if absolutely necessary, remove certain bits with operation 07 (bitwise AND). &nbsp;This ensures that you don't mess up the settings of other grf files.
 
 
||Bit|Value|Feature|Min. version
 
 
0|1|Allow trees and fields in the desert
 
 
1|2|Show pavement and lights in desert towns
 
 
2|4|Fields have a height, using a 3D bounding box
 
 
3|8|Display train vehicles with full width of 32 pixels in depot window (instead of 29 pixels)|
 
 
4|10|Enable ambient sound effect callback 144|2.6 r821
 
 
5|20|Enable catenaries over the third track type (only with electrifiedrailway on)|2.6 r826, 2.5 r1439 (beta 10)
 
 
31|80000000|Only to be set by ttdpbase(w).grf for identification||
 
 
Example code for setting bit 3:
 
 
<pre>-+ &nbsp;24 * 9 &nbsp; &nbsp; 0D 9E 08 9E FF 08 00 00 00+-</pre>
 
 
(Here, the first 08 indicates the bitwise OR operation, and 08 00 00 00 is the value to OR var.9E with.)
 
 
===Locale-dependent settings (9F)===
 
 
This variable is a doubleword in the format rrccmmll, where the meaning of the bytes is:
 
 
||Byte|Meaning
 
 
rr|Reserved for future use, just put zero here for now
 
 
cc|Default currency to be used when the game is first started. It can be larger than 5 to select one of the currencies added via morecurrencies. If this value is larger than 5 while morecurrencies is disabled, US dollars will be used instead.
 
 
mm|Default measurement system to be used when the game is first started. 00h means the imperial system (miles), 01h means the metric system (kilometers), other values are forbidden.
 
 
ll|Language ID. By setting this byte, you can override the default language ID and allow other GRFs to supply correctly localized texts. (The other GRF can check for this value in action 4s)||
 
 
Reading this variable isn't reliable, so you must only write to it. Please also note that the cc and mm parts are considered only while loading the title screen for the first time, changing them later is ignored.
 
   
  +
Those global variables which can be written to are indicated in a separate column in the [[GlobalVariables| global variable list]]. Note that Action D only supports writing dword values. The size given there is merely used to convey how much of that dword value will be used by the game, i.e. what the maximum value is.
'''NOTE''': This variable is reset after the initialization stage. Only changes during the activation stage are considered. This way, GRFs disabled in newgrf.cfg won't change the language and/or default settings. If you want to modify the cc or mm part, make sure the corresponding action D isn't skipped by an earlier action 7 or 9. In particular, if your GRF isn't available for the tropic climate, make sure you set variable 9F before the climate check, since the default title screen is tropic, and your climate check will fail on it.
 
   
-=Example=-
+
== Example ==
   
 
<span style='color:#808080'>Something to go here</span>
 
<span style='color:#808080'>Something to go here</span>

Latest revision as of 16:56, 18 March 2015

Introduction

Assign parameters and calculate results.


Action D allows you to set the value of grf parameter (i.e. those usually set as options in the newgrf(w).cfg file), as well as do math on them.

Syntax

The data looks as follows:

<Sprite-number> * <Length> 0D <target> <operation> <source1> <source2> []
Element Size Description
<Sprite-number> dec A sequential sprite number
<length> dec The total number of bytes used in this action
0D B Defines action 0D
<target> B Target parameter
<operation> B Calculation to carry out
<source1> B First argument
<source2> B Second argument
D Value to use as source if not parameter

Description

target, source1, source2

These bytes specify the target parameter and source parameters. They can either be simply the numbers of grf parameters, or they can be a global variable.

If either source1 or source2 is FF, the value from is used instead of a parameter value.

If <source2> is FE, then this action D will perform one of the following special variable accesses. In this case, <operation> must be assignment and is an argument to the data access, not a source value.

operation

The operation to carry out on the source arguments. This byte has an escape sequence for each of its possible values, as listed below. See the discussion of escape sequences for further information on escape sequences in general. The result of this calculation will be stored in the target parameter.

Operation Escape Version Name Result
00 \D= Supported by OpenTTD Supported by TTDPatch Assignment target = source1
01 \D+ Supported by OpenTTD Supported by TTDPatch Addition target = source1 + source2
02 \D- Supported by OpenTTD Supported by TTDPatch Subtraction target = source1 - source2
03 \Du* Supported by OpenTTD Supported by TTDPatch Unsigned multiplication target = source1 * source2, with both sources being considered to be unsigned
04 \D* Supported by OpenTTD Supported by TTDPatch Signed multiplication target = source1 * source2, with both sources considered signed
05 \Du<< Supported by OpenTTD Supported by TTDPatch Unsigned bit shift target = source1 << source2 if source2>0, or target = source1 >> abs(source2) if source2 < 0. source1 is considered to be unsigned
06 \D<< Supported by OpenTTD Supported by TTDPatch Signed bit shift same as 05, but source1 is considered signed)
07 \D& Supported by OpenTTD Supported by TTDPatch 2.5 (alpha 48)2.5 Bitwise AND target = source1 AND source2
08 \D Supported by OpenTTD Supported by TTDPatch 2.5 (alpha 48)2.5 Bitwise OR target = source1 OR source2
09 \Du/ Supported by OpenTTD Supported by TTDPatch 2.5 (alpha 59)2.5 Unsigned division target = source1 / source2
0A \D/ Supported by OpenTTD Supported by TTDPatch 2.5 (alpha 59)2.5 Signed division target = source1 / source2
0B \Du% Supported by OpenTTD Supported by TTDPatch 2.5 (alpha 59)2.5 Unsigned modulo target = source1 % source2
0C \D% Supported by OpenTTD Supported by TTDPatch 2.5 (alpha 59)2.5 Signed modulo target = source1 % source2

You can add 80 to the operation number to make it apply only if the target is not defined yet. In this respect, a parameter is taken to be defined if any of the following applies:

  • it has been set to any value in the newgrf(w).cfg parameter list
  • it or a parameter with higher number has been set to any value by an earlier action D

If, for example, parameters 0 and 1 are set in the newgrf(w).cfg file, and action D sets parameter 4, then parameters 2 and 3 automatically become defined and get a value of zero.

Notes

You can do a bitwise NOT of <param> by calculating "-1 - <param>", i.e. operation=02, source1=FF, source2=param, data=FF FF FF FF.

The target operand can also refer to the special variables from action 7, see below for the list of variables that it is valid to write to.

Because the patch has to reallocate memory for the whole parameter list whenever a new parameter is added, you should set the parameter with the highest number first (whenever possible, at least) so that all memory can be allocated right away.

Note that parameters are never reset after the game has started, therefore you must not modify newgrf(w).cfg parameters with any kind of irreversible operation. It is valid to, for example, add a value to a parameter only if the same value is later subtracted, to keep the parameter the same across loading or starting several games.

Those global variables which can be written to are indicated in a separate column in the global variable list. Note that Action D only supports writing dword values. The size given there is merely used to convey how much of that dword value will be used by the game, i.e. what the maximum value is.

Example

Something to go here