Difference between revisions of "Action6"
m (10 revisions) |
(Put the behaviour for versions people care about first.) |
||
(6 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
⚫ | |||
− | + | Action 6 allows modifying the contents of the following sprite. It uses the values of the grf parameters and writes them into the data of the following sprite. |
|
⚫ | |||
− | =Action 6= |
||
⚫ | |||
− | Modify the contents of the following sprite |
||
⚫ | |||
⚫ | |||
− | |||
− | Action 6 allows modifying the contents of the following sprite. It uses the values of the grf parameters and writes them into the data of the following sprite. |
||
− | |||
⚫ | |||
The data looks as follows: |
The data looks as follows: |
||
− | < |
+ | <sprite-number> * <Length> 06 (<param-num> <param-size> <offset>){n} FF |
+ | {| |- |
||
− | + | !'''Element'''!![[GRFActionsDetailed|'''Size''']]!!'''Description''' |
|
+ | |- |
||
⚫ | |||
+ | |- |
||
⚫ | |||
+ | |- |
||
⚫ | |||
+ | |- |
||
⚫ | |||
+ | |- |
||
⚫ | |||
+ | |- |
||
⚫ | |||
+ | |- |
||
⚫ | |||
+ | |} |
||
⚫ | |||
⚫ | |||
+ | == Description == |
||
⚫ | |||
⚫ | |||
⚫ | |||
− | |||
⚫ | |||
− | |||
⚫ | |||
− | |||
⚫ | |||
− | |||
⚫ | |||
− | |||
⚫ | |||
− | |||
− | -=Filling in the terms=- |
||
− | |||
⚫ | |||
This is just the number you are at. |
This is just the number you are at. |
||
− | ===Length=== |
+ | === Length === |
Count the number of bytes in this action. |
Count the number of bytes in this action. |
||
− | ===param-num=== |
+ | === param-num === |
This is the parameter number from the newgrf(w).cfg parameters to apply to the following sprite data. It can of course be the result of an ActionD calculation as well. The first parameter has number 00. |
This is the parameter number from the newgrf(w).cfg parameters to apply to the following sprite data. It can of course be the result of an ActionD calculation as well. The first parameter has number 00. |
||
Line 50: | Line 49: | ||
The modification is not carried out if the parameter has not been defined yet. |
The modification is not carried out if the parameter has not been defined yet. |
||
− | ===param-size=== |
+ | === param-size === |
How many bytes of the parameter to use. If this is larger than 4 (the size of a parameter), the bytes of the following parameter are used. In that case, all required parameters must be defined or no modification will be done. |
How many bytes of the parameter to use. If this is larger than 4 (the size of a parameter), the bytes of the following parameter are used. In that case, all required parameters must be defined or no modification will be done. |
||
− | If this value has bit 7 set, the parameter is ''added'' to the destination value, instead of simply stored. This is useful especially when allocating sprites using the GRF Resource Management, because one typically allocates more than one sprite, but the parameter can only hold a single number, the first sprite allocated. |
+ | If this value has bit 7 set, the parameter is ''added'' to the destination value, instead of simply stored. This is useful especially when allocating sprites using the GRF Resource Management, because one typically allocates more than one sprite, but the parameter can only hold a single number, the first sprite allocated. <br>Thus, to apply several sprite numbers properly (such that it works for several activations, not just the first one), use an algorithm like the following: |
− | * Suppose you have a sprite number |
+ | * Suppose you have a sprite number <nowiki><s></nowiki> to which you want to add <nowiki><i></nowiki> (where <nowiki><i></nowiki> is returned by the GRF Resource Management) |
− | * To make this work several times (whenever the grf is activated), you cannot simply add |
+ | * To make this work several times (whenever the grf is activated), you cannot simply add <nowiki><i></nowiki> to <nowiki><s></nowiki> directly |
− | * Instead, use [[ActionD]] to define a new, otherwise unused parameter |
+ | * Instead, use [[ActionD]] to define a new, otherwise unused parameter <j>, and store in it the value of <nowiki><i></nowiki> before it is set by Action D, i.e. <j> holds the previous value of <nowiki><i></nowiki>. |
− | * Next, after setting |
+ | * Next, after setting <nowiki><i></nowiki> with the GRF Resource Management, calculate <j> = <nowiki><i></nowiki> - <j> (i.e. subtract the previous value of i from the new value of i and store in j). |
− | * Use Action 6 to add the value of |
+ | * Use Action 6 to add the value of <j> to <nowiki><s></nowiki>, instead of adding the value of <nowiki><i></nowiki> directly. |
− | * This way, the new value |
+ | * This way, the new value <nowiki><s></nowiki> is the current value of <nowiki><s></nowiki> plus the new <nowiki><i></nowiki> minus the old <nowiki><i></nowiki>, which is the initial value of <nowiki><s></nowiki> plus the new <nowiki><i></nowiki>, just what we wanted. |
− | * Skip the action D's as well as both action 6 and the action it modifies during the [[GrfLoadingStages| |
+ | * Skip the action D's as well as both action 6 and the action it modifies during the [[GrfLoadingStages|"test" stage]] by skipping these actions if action 7 var 84 has bit 10 set. |
* Make sure that when using action 7/9, that either ''both'' or ''none'' of the above two operations are skipped. if only one but not the other is skipped, the values will go out of synch. |
* Make sure that when using action 7/9, that either ''both'' or ''none'' of the above two operations are skipped. if only one but not the other is skipped, the values will go out of synch. |
||
See below for an example. |
See below for an example. |
||
− | ===offset=== |
+ | === offset === |
Number of byte in the following sprite to modify. The counting starts with 0 at the action byte and can go up to the length of the sprite. It is not possible to add data at the end of the sprite. |
Number of byte in the following sprite to modify. The counting starts with 0 at the action byte and can go up to the length of the sprite. It is not possible to add data at the end of the sprite. |
||
− | Since |
+ | Since {{ottdp| |2.5|ttdprev=alpha 51}}, this is an extended byte (see [[GRFActionsDetailed]]). |
− | |||
− | -=Notes=- |
||
− | |||
⚫ | |||
− | |||
⚫ | |||
− | + | == Example == |
|
This is an example on how to apply the sprite numbers returned by the GRF Resource Management to an action 0: |
This is an example on how to apply the sprite numbers returned by the GRF Resource Management to an action 0: |
||
− | <pre> |
+ | <pre>// First, set param 1 (<j>) to the old value of param 0 (<i>) |
-1 * 5 0D 01 00 00 00 |
-1 * 5 0D 01 00 00 00 |
||
Line 90: | Line 83: | ||
-1 * 9 0D 00 00 00 FE FF 08 03 00 |
-1 * 9 0D 00 00 00 FE FF 08 03 00 |
||
− | // Now calculate |
+ | // Now calculate <j> = <i> - <j> |
-1 * 5 0D 01 02 00 01 |
-1 * 5 0D 01 02 00 01 |
||
− | // So |
+ | // So <j> = new <i> - old <i> |
− | // Use Action 6 to add |
+ | // Use Action 6 to add <j> to the sprite numbers in the sample sprite layout |
-1 * 11 06 01 84 07 01 84 11 01 84 1B FF |
-1 * 11 06 01 84 07 01 84 11 01 84 1B FF |
||
Line 112: | Line 105: | ||
80 |
80 |
||
− | + | </pre> |
Latest revision as of 14:07, 25 July 2024
Introduction
Action 6 allows modifying the contents of the following sprite. It uses the values of the grf parameters and writes them into the data of the following sprite.
Since TTDPatch 2.0.1 alpha 51, Action 6 is applied both at initialization as well as activation, and can be skipped with either Action 7 or 9 as appropriate.
Previously this action was processed only once during the initialization of a .grf file and ignored during the following activations when starting or loading a game. You must use Action 9 and not Action 7 to skip Action 6 if compatibility with such ancient versions is required.
Format
The data looks as follows:
<sprite-number> * <Length> 06 (<param-num> <param-size> <offset>){n} FF
Element | Size | Description |
---|---|---|
<sprite-number> | dec | A sequential sprite number |
<length> | dec | The total number of bytes used in this action |
06 | B | Defines action 06 |
<param-num> | B | Which grf parameter to apply |
<param-size> | B | How many bytes to overwrite |
<offset> | B* | Which byte to overwrite |
<FF> | B | Marks the end of the list |
The triplet of <param-num> <param-size> <offset> can be repeated as often as desired.
Description
Sprite-number
This is just the number you are at.
Length
Count the number of bytes in this action.
param-num
This is the parameter number from the newgrf(w).cfg parameters to apply to the following sprite data. It can of course be the result of an ActionD calculation as well. The first parameter has number 00.
The modification is not carried out if the parameter has not been defined yet.
param-size
How many bytes of the parameter to use. If this is larger than 4 (the size of a parameter), the bytes of the following parameter are used. In that case, all required parameters must be defined or no modification will be done.
If this value has bit 7 set, the parameter is added to the destination value, instead of simply stored. This is useful especially when allocating sprites using the GRF Resource Management, because one typically allocates more than one sprite, but the parameter can only hold a single number, the first sprite allocated.
Thus, to apply several sprite numbers properly (such that it works for several activations, not just the first one), use an algorithm like the following:
- Suppose you have a sprite number <s> to which you want to add <i> (where <i> is returned by the GRF Resource Management)
- To make this work several times (whenever the grf is activated), you cannot simply add <i> to <s> directly
- Instead, use ActionD to define a new, otherwise unused parameter <j>, and store in it the value of <i> before it is set by Action D, i.e. <j> holds the previous value of <i>.
- Next, after setting <i> with the GRF Resource Management, calculate <j> = <i> - <j> (i.e. subtract the previous value of i from the new value of i and store in j).
- Use Action 6 to add the value of <j> to <s>, instead of adding the value of <i> directly.
- This way, the new value <s> is the current value of <s> plus the new <i> minus the old <i>, which is the initial value of <s> plus the new <i>, just what we wanted.
- Skip the action D's as well as both action 6 and the action it modifies during the "test" stage by skipping these actions if action 7 var 84 has bit 10 set.
- Make sure that when using action 7/9, that either both or none of the above two operations are skipped. if only one but not the other is skipped, the values will go out of synch.
See below for an example.
offset
Number of byte in the following sprite to modify. The counting starts with 0 at the action byte and can go up to the length of the sprite. It is not possible to add data at the end of the sprite.
Since 2.5, this is an extended byte (see GRFActionsDetailed).
Example
This is an example on how to apply the sprite numbers returned by the GRF Resource Management to an action 0:
// First, set param 1 (<j>) to the old value of param 0 (<i>) -1 * 5 0D 01 00 00 00 // Then, use the GRF Resource Management to reserve 3 sprites -1 * 9 0D 00 00 00 FE FF 08 03 00 // Now calculate <j> = <i> - <j> -1 * 5 0D 01 02 00 01 // So <j> = new <i> - old <i> // Use Action 6 to add <j> to the sprite numbers in the sample sprite layout -1 * 11 06 01 84 07 01 84 11 01 84 1B FF -1 * 32 00 04 01 01 00 09 01 00 00 00 00 // first allocated sprite 00 00 00 10 05 02 01 00 00 00 // second allocated sprite 00 0B 00 10 05 02 02 00 00 00 // third 80