Action 0x0D: Set parameter */
| 180 | |
| 181 | /** Action 0x0D: Set parameter */ |
| 182 | static void ParamSet(ByteReader &buf) |
| 183 | { |
| 184 | /* <0D> <target> <operation> <source1> <source2> [<data>] |
| 185 | * |
| 186 | * B target parameter number where result is stored |
| 187 | * B operation operation to perform, see below |
| 188 | * B source1 first source operand |
| 189 | * B source2 second source operand |
| 190 | * D data data to use in the calculation, not necessary |
| 191 | * if both source1 and source2 refer to actual parameters |
| 192 | * |
| 193 | * Operations |
| 194 | * 00 Set parameter equal to source1 |
| 195 | * 01 Addition, source1 + source2 |
| 196 | * 02 Subtraction, source1 - source2 |
| 197 | * 03 Unsigned multiplication, source1 * source2 (both unsigned) |
| 198 | * 04 Signed multiplication, source1 * source2 (both signed) |
| 199 | * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a |
| 200 | * signed quantity; left shift if positive and right shift if |
| 201 | * negative, source1 is unsigned) |
| 202 | * 06 Signed bit shift, source1 by source2 |
| 203 | * (source2 like in 05, and source1 as well) |
| 204 | */ |
| 205 | |
| 206 | uint8_t target = buf.ReadByte(); |
| 207 | uint8_t oper = buf.ReadByte(); |
| 208 | uint32_t src1 = buf.ReadByte(); |
| 209 | uint32_t src2 = buf.ReadByte(); |
| 210 | |
| 211 | uint32_t data = 0; |
| 212 | if (buf.Remaining() >= 4) data = buf.ReadDWord(); |
| 213 | |
| 214 | /* You can add 80 to the operation to make it apply only if the target |
| 215 | * is not defined yet. In this respect, a parameter is taken to be |
| 216 | * defined if any of the following applies: |
| 217 | * - it has been set to any value in the newgrf(w).cfg parameter list |
| 218 | * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by |
| 219 | * an earlier action D */ |
| 220 | if (HasBit(oper, 7)) { |
| 221 | if (target < 0x80 && target < std::size(_cur_gps.grffile->param)) { |
| 222 | GrfMsg(7, "ParamSet: Param {} already defined, skipping", target); |
| 223 | return; |
| 224 | } |
| 225 | |
| 226 | oper = GB(oper, 0, 7); |
| 227 | } |
| 228 | |
| 229 | if (src2 == 0xFE) { |
| 230 | if (GB(data, 0, 8) == 0xFF) { |
| 231 | if (data == 0x0000FFFF) { |
| 232 | /* Patch variables */ |
| 233 | src1 = GetPatchVariable(src1); |
| 234 | } else { |
| 235 | /* GRF Resource Management */ |
| 236 | uint8_t op = src1; |
| 237 | GrfSpecFeature feature{static_cast<uint8_t>(GB(data, 8, 8))}; |
| 238 | uint16_t count = GB(data, 16, 16); |
| 239 |
no test coverage detected