4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
10 /** @file sprite.cpp Handling of sprites */
14 #include "viewport_func.h"
15 #include "landscape.h"
16 #include "spritecache.h"
17 #include "zoom_func.h"
19 /** Compute the palette to use for a layout sprite. */
20 static inline PaletteID
SpriteLayoutPalette (SpriteID image
, PaletteID pal
,
21 uint32 offset
, PaletteID def
)
23 if (HasBit(image
, PALETTE_MODIFIER_TRANSPARENT
) || HasBit(image
, PALETTE_MODIFIER_COLOUR
)) {
24 if (HasBit(pal
, SPRITE_MODIFIER_CUSTOM_SPRITE
)) pal
+= offset
;
25 return (pal
!= 0 ? pal
: def
);
32 * Draws a tile sprite sequence.
33 * @param ti The tile to draw on
34 * @param seq Sprite and subsprites to draw
35 * @param to The transparency bit that toggles drawing of these sprites
36 * @param orig_offset Sprite-Offset for original sprites
37 * @param newgrf_offset Sprite-Offset for NewGRF defined sprites
38 * @param default_palette The default recolour sprite to use (typically company colour)
39 * @param child_offset_is_unsigned Whether child sprite offsets are interpreted signed or unsigned
41 void DrawCommonTileSeq (const TileInfo
*ti
, const DrawTileSeqStruct
*seq
,
42 TransparencyOption to
, int32 orig_offset
, uint32 newgrf_offset
,
43 PaletteID default_palette
, bool child_offset_is_unsigned
)
45 bool parent_sprite_encountered
= false;
46 const DrawTileSeqStruct
*dtss
;
47 bool skip_childs
= false;
48 foreach_draw_tile_seq(dtss
, seq
) {
49 SpriteID image
= dtss
->image
.sprite
;
52 if (!dtss
->IsParentSprite()) continue;
56 /* TTD sprite 0 means no sprite */
57 if ((GB(image
, 0, SPRITE_WIDTH
) == 0 && !HasBit(image
, SPRITE_MODIFIER_CUSTOM_SPRITE
)) ||
58 (IsInvisibilitySet(to
) && !HasBit(image
, SPRITE_MODIFIER_OPAQUE
))) {
59 skip_childs
= dtss
->IsParentSprite();
63 image
+= (HasBit(image
, SPRITE_MODIFIER_CUSTOM_SPRITE
) ? newgrf_offset
: orig_offset
);
65 PaletteID pal
= SpriteLayoutPalette (image
, dtss
->image
.pal
,
66 newgrf_offset
, default_palette
);
68 bool transparent
= !HasBit(image
, SPRITE_MODIFIER_OPAQUE
) && IsTransparencySet(to
);
69 if (dtss
->IsParentSprite()) {
70 parent_sprite_encountered
= true;
71 AddSortableSpriteToDraw (ti
->vd
,
73 ti
->x
+ dtss
->delta_x
, ti
->y
+ dtss
->delta_y
,
74 dtss
->size_x
, dtss
->size_y
,
75 dtss
->size_z
, ti
->z
+ dtss
->delta_z
,
79 int offs_x
= child_offset_is_unsigned
? (uint8
)dtss
->delta_x
: dtss
->delta_x
;
80 int offs_y
= child_offset_is_unsigned
? (uint8
)dtss
->delta_y
: dtss
->delta_y
;
81 if (parent_sprite_encountered
) {
82 AddChildSpriteScreen (ti
->vd
, image
, pal
, offs_x
, offs_y
, transparent
);
85 SetBit(image
, PALETTE_MODIFIER_TRANSPARENT
);
86 pal
= PALETTE_TO_TRANSPARENT
;
88 DrawGroundSprite (ti
, image
, pal
, NULL
, offs_x
, offs_y
);
95 * Draws a tile sprite sequence in the GUI
96 * @param dpi Area to draw on.
97 * @param x X position to draw to
98 * @param y Y position to draw to
99 * @param seq Sprite and subsprites to draw
100 * @param orig_offset Sprite-Offset for original sprites
101 * @param newgrf_offset Sprite-Offset for NewGRF defined sprites
102 * @param default_palette The default recolour sprite to use (typically company colour)
103 * @param child_offset_is_unsigned Whether child sprite offsets are interpreted signed or unsigned
105 void DrawCommonTileSeqInGUI (BlitArea
*dpi
, int x
, int y
,
106 const DrawTileSeqStruct
*seq
, int32 orig_offset
, uint32 newgrf_offset
,
107 PaletteID default_palette
, bool child_offset_is_unsigned
)
109 const DrawTileSeqStruct
*dtss
;
110 Point child_offset
= {0, 0};
112 bool skip_childs
= false;
113 foreach_draw_tile_seq(dtss
, seq
) {
114 SpriteID image
= dtss
->image
.sprite
;
117 if (!dtss
->IsParentSprite()) continue;
121 /* TTD sprite 0 means no sprite */
122 if (GB(image
, 0, SPRITE_WIDTH
) == 0 && !HasBit(image
, SPRITE_MODIFIER_CUSTOM_SPRITE
)) {
123 skip_childs
= dtss
->IsParentSprite();
127 image
+= (HasBit(image
, SPRITE_MODIFIER_CUSTOM_SPRITE
) ? newgrf_offset
: orig_offset
);
129 PaletteID pal
= SpriteLayoutPalette (image
, dtss
->image
.pal
,
130 newgrf_offset
, default_palette
);
132 if (dtss
->IsParentSprite()) {
133 Point pt
= RemapCoords(dtss
->delta_x
, dtss
->delta_y
, dtss
->delta_z
);
134 DrawSprite (dpi
, image
, pal
, x
+ UnScaleGUI(pt
.x
), y
+ UnScaleGUI(pt
.y
));
136 const Sprite
*spr
= GetSprite(image
& SPRITE_MASK
, ST_NORMAL
);
137 child_offset
.x
= UnScaleGUI(pt
.x
+ spr
->x_offs
);
138 child_offset
.y
= UnScaleGUI(pt
.y
+ spr
->y_offs
);
140 int offs_x
= child_offset_is_unsigned
? (uint8
)dtss
->delta_x
: dtss
->delta_x
;
141 int offs_y
= child_offset_is_unsigned
? (uint8
)dtss
->delta_y
: dtss
->delta_y
;
142 DrawSprite (dpi
, image
, pal
, x
+ child_offset
.x
+ ScaleGUITrad(offs_x
), y
+ child_offset
.y
+ ScaleGUITrad(offs_y
));