* Load a recolour sprite into memory. * @param file GRF we're reading from. * @param file_pos Position within file. * @param num Size of the sprite in the GRF. * @param allocator Sprite allocator to use. * @return Sprite data. */
| 415 | * @return Sprite data. |
| 416 | */ |
| 417 | static void *ReadRecolourSprite(SpriteFile &file, size_t file_pos, uint num, SpriteAllocator &allocator) |
| 418 | { |
| 419 | /* "Normal" recolour sprites are ALWAYS 257 bytes. Then there is a small |
| 420 | * number of recolour sprites that are 17 bytes that only exist in DOS |
| 421 | * GRFs which are the same as 257 byte recolour sprites, but with the last |
| 422 | * 240 bytes zeroed. */ |
| 423 | static const uint RECOLOUR_SPRITE_SIZE = 257; |
| 424 | uint8_t *dest = allocator.Allocate<uint8_t>(std::max(RECOLOUR_SPRITE_SIZE, num)); |
| 425 | |
| 426 | file.SeekTo(file_pos, SEEK_SET); |
| 427 | if (file.NeedsPaletteRemap()) { |
| 428 | uint8_t *dest_tmp = new uint8_t[std::max(RECOLOUR_SPRITE_SIZE, num)]; |
| 429 | |
| 430 | /* Only a few recolour sprites are less than 257 bytes */ |
| 431 | if (num < RECOLOUR_SPRITE_SIZE) std::fill_n(dest_tmp, RECOLOUR_SPRITE_SIZE, 0); |
| 432 | file.ReadBlock(dest_tmp, num); |
| 433 | |
| 434 | /* The data of index 0 is never used; "literal 00" according to the (New)GRF specs. */ |
| 435 | for (uint i = 1; i < RECOLOUR_SPRITE_SIZE; i++) { |
| 436 | dest[i] = _palmap_w2d[dest_tmp[_palmap_d2w[i - 1] + 1]]; |
| 437 | } |
| 438 | delete[] dest_tmp; |
| 439 | } else { |
| 440 | file.ReadBlock(dest, num); |
| 441 | } |
| 442 | |
| 443 | return dest; |
| 444 | } |
| 445 | |
| 446 | /** |
| 447 | * Read a sprite from disk. |
no test coverage detected