2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 /** @file sprite.cpp Handling of sprites */
12 #include "viewport_func.h"
13 #include "landscape.h"
14 #include "spritecache.h"
15 #include "zoom_func.h"
17 #include "safeguards.h"
21 * Draws a tile sprite sequence.
22 * @param ti The tile to draw on
23 * @param dts Sprite and subsprites to draw
24 * @param to The transparency bit that toggles drawing of these sprites
25 * @param orig_offset Sprite-Offset for original sprites
26 * @param newgrf_offset Sprite-Offset for NewGRF defined sprites
27 * @param default_palette The default recolour sprite to use (typically company colour)
28 * @param child_offset_is_unsigned Whether child sprite offsets are interpreted signed or unsigned
30 void DrawCommonTileSeq(const TileInfo
*ti
, const DrawTileSprites
*dts
, TransparencyOption to
, int32 orig_offset
, uint32 newgrf_offset
, PaletteID default_palette
, bool child_offset_is_unsigned
)
32 bool parent_sprite_encountered
= false;
33 const DrawTileSeqStruct
*dtss
;
34 bool skip_childs
= false;
35 foreach_draw_tile_seq(dtss
, dts
->seq
) {
36 SpriteID image
= dtss
->image
.sprite
;
37 PaletteID pal
= dtss
->image
.pal
;
40 if (!dtss
->IsParentSprite()) continue;
44 /* TTD sprite 0 means no sprite */
45 if ((GB(image
, 0, SPRITE_WIDTH
) == 0 && !HasBit(image
, SPRITE_MODIFIER_CUSTOM_SPRITE
)) ||
46 (IsInvisibilitySet(to
) && !HasBit(image
, SPRITE_MODIFIER_OPAQUE
))) {
47 skip_childs
= dtss
->IsParentSprite();
51 image
+= (HasBit(image
, SPRITE_MODIFIER_CUSTOM_SPRITE
) ? newgrf_offset
: orig_offset
);
52 if (HasBit(pal
, SPRITE_MODIFIER_CUSTOM_SPRITE
)) pal
+= newgrf_offset
;
54 pal
= SpriteLayoutPaletteTransform(image
, pal
, default_palette
);
56 if (dtss
->IsParentSprite()) {
57 parent_sprite_encountered
= true;
58 AddSortableSpriteToDraw(
60 ti
->x
+ dtss
->delta_x
, ti
->y
+ dtss
->delta_y
,
61 dtss
->size_x
, dtss
->size_y
,
62 dtss
->size_z
, ti
->z
+ dtss
->delta_z
,
63 !HasBit(image
, SPRITE_MODIFIER_OPAQUE
) && IsTransparencySet(to
)
66 int offs_x
= child_offset_is_unsigned
? (uint8
)dtss
->delta_x
: dtss
->delta_x
;
67 int offs_y
= child_offset_is_unsigned
? (uint8
)dtss
->delta_y
: dtss
->delta_y
;
68 bool transparent
= !HasBit(image
, SPRITE_MODIFIER_OPAQUE
) && IsTransparencySet(to
);
69 if (parent_sprite_encountered
) {
70 AddChildSpriteScreen(image
, pal
, offs_x
, offs_y
, transparent
);
73 SetBit(image
, PALETTE_MODIFIER_TRANSPARENT
);
74 pal
= PALETTE_TO_TRANSPARENT
;
76 DrawGroundSprite(image
, pal
, nullptr, offs_x
, offs_y
);
83 * Draws a tile sprite sequence in the GUI
84 * @param x X position to draw to
85 * @param y Y position to draw to
86 * @param dts Sprite and subsprites to draw
87 * @param orig_offset Sprite-Offset for original sprites
88 * @param newgrf_offset Sprite-Offset for NewGRF defined sprites
89 * @param default_palette The default recolour sprite to use (typically company colour)
90 * @param child_offset_is_unsigned Whether child sprite offsets are interpreted signed or unsigned
92 void DrawCommonTileSeqInGUI(int x
, int y
, const DrawTileSprites
*dts
, int32 orig_offset
, uint32 newgrf_offset
, PaletteID default_palette
, bool child_offset_is_unsigned
)
94 const DrawTileSeqStruct
*dtss
;
95 Point child_offset
= {0, 0};
97 bool skip_childs
= false;
98 foreach_draw_tile_seq(dtss
, dts
->seq
) {
99 SpriteID image
= dtss
->image
.sprite
;
100 PaletteID pal
= dtss
->image
.pal
;
103 if (!dtss
->IsParentSprite()) continue;
107 /* TTD sprite 0 means no sprite */
108 if (GB(image
, 0, SPRITE_WIDTH
) == 0 && !HasBit(image
, SPRITE_MODIFIER_CUSTOM_SPRITE
)) {
109 skip_childs
= dtss
->IsParentSprite();
113 image
+= (HasBit(image
, SPRITE_MODIFIER_CUSTOM_SPRITE
) ? newgrf_offset
: orig_offset
);
114 if (HasBit(pal
, SPRITE_MODIFIER_CUSTOM_SPRITE
)) pal
+= newgrf_offset
;
116 pal
= SpriteLayoutPaletteTransform(image
, pal
, default_palette
);
118 if (dtss
->IsParentSprite()) {
119 Point pt
= RemapCoords(dtss
->delta_x
, dtss
->delta_y
, dtss
->delta_z
);
120 DrawSprite(image
, pal
, x
+ UnScaleGUI(pt
.x
), y
+ UnScaleGUI(pt
.y
));
122 const Sprite
*spr
= GetSprite(image
& SPRITE_MASK
, ST_NORMAL
);
123 child_offset
.x
= UnScaleGUI(pt
.x
+ spr
->x_offs
);
124 child_offset
.y
= UnScaleGUI(pt
.y
+ spr
->y_offs
);
126 int offs_x
= child_offset_is_unsigned
? (uint8
)dtss
->delta_x
: dtss
->delta_x
;
127 int offs_y
= child_offset_is_unsigned
? (uint8
)dtss
->delta_y
: dtss
->delta_y
;
128 DrawSprite(image
, pal
, x
+ child_offset
.x
+ ScaleGUITrad(offs_x
), y
+ child_offset
.y
+ ScaleGUITrad(offs_y
));