Decoded: OpenTTD (2003) v1.8 (2018) Source file: bitmath_func.hpp Line-by-line code walkthrough by MaiZure bitmath_func.cpp defines bitwise math operations Original code: https://github.com/MaiZure/OpenTTD-1.8/blob/master/src/core/bitmath_func.hpp 1 COMMENT (*) 2 BLANK (-) 3 * 4 * 5 * 6 * 7 * 8 * 9 - 10 * 11 - 12 Header guard 13 Header guard 14 - 15 * 16 * 17 * 18 * 19 * 20 * 21 * 22 * 23 * 24 * 25 * 26 * 27 * 28 * 29 * 30 * 31 * 32 * 33 Sets up a function template with a type parameter 34 Defines type-safe GB with three arguments: input, start, and length 35 BLOCK START - GB, gets some bits within a larger input 36 Shifts to the start and masks the requested substring 37 BLOCK END - GB 38 - 39 * 40 * 41 * 42 * 43 * 44 * 45 * 46 * 47 * 48 * 49 * 50 * 51 * 52 * 53 * 54 * 55 * 56 * 57 * 58 * 59 Sets up a function template with two type parameters 60 Defines SB with 4 arguments: input, start, length, and desired bits 61 BLOCK START - SB, sets some subset of bits in a target value 62 Masks away the desired bit field in the destination 63 Asserts the desired bits in to the destination 64 Returns the new value 65 BLOCK END - SB 66 - 67 * 68 * 69 * 70 * 71 * 72 * 73 * 74 * 75 * 76 * 77 * 78 * 79 * 80 * 81 * 82 * 83 * 84 Sets up a function template with two type parameters 85 Defines AB with 4 arguments: input, start, length, and addend 86 BLOCK START - AB, adds a value to a subset of bits in a larger value 87 Creates the bit mask for the target window 88 Masks away the target window and asserts the masked add result 89 Returns the result 90 BLOCK END - AB 91 - 92 * 93 * 94 * 95 * 96 * 97 * 98 * 99 * 100 * 101 * 102 * 103 * 104 Sets up a function template with one type parameter 105 Defines HasBit with two arguments: a value and a position 106 BLOCK START - HasBit, checks the bit in a specific position 107 Masks the desired position and returns a check against 0. If not zero, then it has a bit 108 BLOCK END - HasBit 109 - 110 * 111 * 112 * 113 * 114 * 115 * 116 * 117 * 118 * 119 * 120 * 121 * 122 Sets up a function template with one type parameter 123 Defines SetBit with two arguments: a value and a position 124 BLOCK START - SetBit, asserts a bit at a position in a value 125 Bitwise OR at the appropriate position 126 BLOCK END - SetBit 127 - 128 * 129 * 130 * 131 * 132 * 133 * 134 * 135 * 136 * 137 * 138 Defines SETBITS macro to OR two values 139 - 140 * 141 * 142 * 143 * 144 * 145 * 146 * 147 * 148 * 149 * 150 * 151 * 152 Sets up a function template with one type parameter 153 Defines ClrBit with two arguments: a value and a position 154 BLOCK START - ClrBit, Sets a bit at a position to 0 155 Masks all but the desired target position in an input value 156 BLOCK END - ClrBit 157 - 158 * 159 * 160 * 161 * 162 * 163 * 164 * 165 * 166 * 167 * 168 Defines CLRBITS macro to remove bits matched by a value (mask complement) 169 - 170 * 171 * 172 * 173 * 174 * 175 * 176 * 177 * 178 * 179 * 180 * 181 * 182 Sets up a function template with one type parameter 183 Defines ToggleBit with two arguments: a value and position 184 BLOCK START - ToggleBit, flips a bit at the desired position 185 Performs an XOR using the position mask 186 BLOCK END - ToggleBit 187 - 188 - 189 * 190 Imports the first bit lookup table from bitmath_func.cpp 191 - 192 * 193 * 194 * 195 * 196 * 197 * 198 * 199 * 200 * 201 * 202 Defines FIND_FIRST_BIT macro using the lookup table 203 - 204 * 205 * 206 * 207 * 208 * 209 * 210 * 211 * 212 * 213 * 214 * 215 * 216 * 217 * 218 Defines FindFirstBit2x64 with one argument: the value to search 219 BLOCK START - FirstFirstBit2x64, returns the least-significant asserted bit position 220 If the first byte has no asserted bit... 221 Lookup bits in position 8-13 222 Otherwise there are bits in the first byte... 223 Check bits 0-5 224 End check against an empty first byte 225 BLOCK END - 226 - 227 Forward declare FirstFirstBit 228 Forward declare FirstLastBit 229 - 230 * 231 * 232 * 233 * 234 * 235 * 236 * 237 * 238 * 239 * 240 Sets up a function template with one type parameter 241 Defines KillFirstBit with one argument: the initial value 242 BLOCK START - KillFirstBit, sets the first bit to zero 243 Masks with value - 1 -- always results in a 0 (1&0 or 0&1) 244 BLOCK END - KillFirstBit 245 - 246 * 247 * 248 * 249 * 250 * 251 * 252 Sets up a function template with one type parameter 253 Defines CountBits with one argument: the value to check 254 BLOCK START - CountBits, returns the number of asserted bits 255 Declares a counter 256 - 257 * 258 * 259 * 260 * 261 - 262 Initializes the counter to 0 and loops while the number has value 263 Masks away the least significant bits one at a time. This takes advantage of the property that subracting one always results in a mask of the least significant bit. 1000 becomes 0111 264 Repeat while the value has bits 265 - 266 Returns the result -- the number of times we had to mask 267 BLOCK END - 268 - 269 * 270 * 271 * 272 * 273 * 274 * 275 Sets up a function template with one type parameter 276 Defines HasExactlyOneBit with one argument: the value to test 277 BLOCK START - HasExactlyOneBit, checks a value for only one bit 278 If the value isn't zero, but masking the value - 1 makes it zero, then it only has 1 bit. Same property as mentioned in CountBits 279 BLOCK END - HasExactlyOneBit 280 - 281 * 282 * 283 * 284 * 285 * 286 * 287 Sets up a function template with one type parameter 288 Defines HasAtMostOneBit with one argument, the value to test 289 BLOCK START - HasAtMostOneBit, true if input has 0 or 1 bits 290 Same as before except the input could be 0 or a 1 bit value 291 BLOCK END - HasAtMostOneBit 292 - 293 * 294 * 295 * 296 * 297 * 298 * 299 * 300 * 301 * 302 Sets up a function template with one type parameter 303 Defines ROL with two arguments, a input and a shift amount 304 BLOCK START - ROL, the usual rotate left operation, platform independent. 305 Returns the left shift of the low order bits masked with the right shift of the high order bits 306 BLOCK END - ROL 307 - 308 * 309 * 310 * 311 * 312 * 313 * 314 * 315 * 316 * 317 Sets up a function template with one type parameter 318 Defines ROR with two arugments: a value and a shfit amount 319 BLOCK START - ROR, the usual rotate right operation, platform independent. 320 Returns the right shift of the high order bits masked over the left shift of the lower order bits 321 BLOCK END - ROR 322 - 323 * 324 * 325 * 326 * 327 * 328 * 329 * 330 * 331 * 332 * 333 * 334 * 335 * 336 * 337 * 338 * 339 * 340 Defines FOR_EACH_SET_BIT_EX macro with four arguments: a type, a counter, a type, and a value. This is used as a support function for higher-level game operations, such as iterator over track configurations stored as bitfields 341 Starts a for loop 342 Initializes a bits value to a value equal to the initial value through multiple comma evaluation. 343 Continue the loop while the initial value is not zero 344 Check each bit position through shift and increment 345 End of for loop 346 If the bit position has value...execute some unseen function that should proceed this macro 347 - 348 * 349 * 350 * 351 * 352 * 353 * 354 * 355 * 356 * 357 * 358 * 359 * 360 * 361 Defines FOR_EACH_SET_BIT in terms of FOR_EACH_SET_BIT_EX 362 - 363 If this is an Apple platform... 364 * 365 * 366 * 367 * 368 Define 32-bit byte swap using Apple built-ins 369 Define 16-but byte swap using Apple built-ins 370 Otherwise if we're using Windows 371 * 372 Define 32-bit byte swap using Visual C built-ins 373 Define 16-bit byte swap using Visual C built-ins 374 Otherwise we're on a generic platform... 375 * 376 * 377 * 378 * 379 * 380 Defines BSWAP32 with one argument: the value to swap 381 BLOCK START - BSWAP32 382 If we're using GCC >= 4.3 lets take advantage of some built-ins 383 * 384 Return the value of the swap 385 Otherwise we need to roll our own 386 Return each byte shifted and masked in reverse order 387 End check for GCC version 388 BLOCK END - BSWAP32 389 - 390 * 391 * 392 * 393 * 394 * 395 Defines BSWAP16 with one argument: the value to check 396 BLOCK START - BSWAP16 397 Return the low order and high order shifts 398 BLOCK END - BSWAP16 399 End check for Apple 400 - 401 Header guard end