ActionD

From GRFSpecs
Revision as of 19:22, 12 June 2011 by Orudge (talk | contribs) (13 revisions)
Jump to navigationJump to search

Assign parameters and calculate results

Action D

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.

-=Format=-

The data looks as follows:

 -+<Sprite-number> * <Length> 0D <target> <operation> <source1> <source2> <nowiki>[<data>]</nowiki>+-

||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

<data>|D|Value to use as source if not parameter||

-=Filling in the terms=-

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 the special variables from action 7, see the description of param-num there.

Note that the only special variables which may be given as target are listed below, all others should be considered read-only.

If either source1 or source2 is FF, the value from <data> 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 <data> is an argument to the data access, not a source value.

{toc}

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|Name|Result

00|\D=|Equal|target = source1

01|\D+|Addition|target = source1 + source2

02|\D-|Subtraction|target = source1 - source2

03|\Du*|Unsigned multiplication|target = source1 * source2, with both sources being considered to be unsigned

04|\D*|Signed multiplication|target = source1 * source2, with both sources considered signed

05|\Du<<|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<<|Signed bit shift|same as 05, but source1 is considered signed)

07|\D&|Bitwise AND*|target = source1 AND source2

08|\D<nowiki>|</nowiki>|Bitwise OR*|target = source1 OR source2

09|\Du/|Unsigned division**|target = source1 / source2

0A|\D/|Signed division**|target = source1 / source2

0B|\Du%|Unsigned modulo**|target = source1 % source2

0C|\D%|Signed modulo**|target = source1 % source2||

<nowiki>*</nowiki> Only available in 2.0.1 alpha 48  or higher

<nowiki>**</nowiki> Only available in 2.0.1 alpha 59  or higher

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.

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.  This variable moves all vehicles in the depot view down by this many pixels.

Since OpenTTD r16867 this variable works per grf file, that is: It only affects trains defined in the same grf.

Rail track type cost factors (8F)

This variable is a collection of three bytes that are used as multipliers for track costs when the "trackcostdiff" switch is on.  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|-+<Id>+- (i.e., not property numbers)

3|-+<Ids...>+- (i.e., not cargo types or cargo IDs, also not for livery overrides)

4|-+<Offset>+- (not for generic texts, though)

A|-+<First-sprite>+-||

Misc. GRF Features (9E)

This variable is a global bit mask of various patch features a grf file can enable.  Please only set the bits using operation 08 (bitwise OR), or, if absolutely necessary, remove certain bits with operation 07 (bitwise AND).  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)|(a)

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||

(a) Since OpenTTD r16867 this flag works per grf file, that is: It only affects trains defined in the same grf.

Example code for setting bit 3:

-+  24 * 9     0D 9E 08 9E FF 08 00 00 00+-

(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.

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=-

Something to go here