Difference between revisions of "ActionD"

From GRFSpecs
Jump to navigationJump to search
(→‎operation: add version info)
(Move global variables out of this page and link separate page)
Line 121: Line 121:
 
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.
 
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 [[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.
== 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||<tt><Id></tt> (i.e., not property numbers)
 
 
|-
 
|3||<tt><Ids...></tt> (i.e., not cargo types or cargo IDs, also not for livery overrides)
 
 
|-
 
|4||<tt><Offset></tt> (not for generic texts, though)
 
 
|-
 
|A||<tt><First-sprite></tt>
 
|}
 
 
=== 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||TTDPatch 2.6 r821
 
 
|-
 
|5||20||Enable catenaries over the third track type (only with electrifiedrailway on)||TTDPatch 2.6 r826, TTDPatch 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 ==
 
== Example ==

Revision as of 11:48, 24 July 2011

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 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 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 Equal 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 [[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.

Example

Something to go here