1 /* $Id: sprite.cpp 24900 2013-01-08 22:46:42Z planetmaker $ */
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 #include "safeguards.h"
23 * Draws a tile sprite sequence.
24 * @param ti The tile to draw on
25 * @param dts Sprite and subsprites to draw
26 * @param to The transparency bit that toggles drawing of these sprites
27 * @param orig_offset Sprite-Offset for original sprites
28 * @param newgrf_offset Sprite-Offset for NewGRF defined sprites
29 * @param default_palette The default recolour sprite to use (typically company colour)
30 * @param child_offset_is_unsigned Whether child sprite offsets are interpreted signed or unsigned
32 void DrawCommonTileSeq(const TileInfo
*ti
, const DrawTileSprites
*dts
, TransparencyOption to
, int32 orig_offset
, uint32 newgrf_offset
, PaletteID default_palette
, bool child_offset_is_unsigned
)
34 bool parent_sprite_encountered
= false;
35 const DrawTileSeqStruct
*dtss
;
36 bool skip_childs
= false;
37 foreach_draw_tile_seq(dtss
, dts
->seq
) {
38 SpriteID image
= dtss
->image
.sprite
;
39 PaletteID pal
= dtss
->image
.pal
;
42 if (!dtss
->IsParentSprite()) continue;
46 /* TTD sprite 0 means no sprite */
47 if ((GB(image
, 0, SPRITE_WIDTH
) == 0 && !HasBit(image
, SPRITE_MODIFIER_CUSTOM_SPRITE
)) ||
48 (IsInvisibilitySet(to
) && !HasBit(image
, SPRITE_MODIFIER_OPAQUE
))) {
49 skip_childs
= dtss
->IsParentSprite();
53 image
+= (HasBit(image
, SPRITE_MODIFIER_CUSTOM_SPRITE
) ? newgrf_offset
: orig_offset
);
54 if (HasBit(pal
, SPRITE_MODIFIER_CUSTOM_SPRITE
)) pal
+= newgrf_offset
;
56 pal
= SpriteLayoutPaletteTransform(image
, pal
, default_palette
);
58 if (dtss
->IsParentSprite()) {
59 parent_sprite_encountered
= true;
60 AddSortableSpriteToDraw(
62 ti
->x
+ dtss
->delta_x
, ti
->y
+ dtss
->delta_y
,
63 dtss
->size_x
, dtss
->size_y
,
64 dtss
->size_z
, ti
->z
+ dtss
->delta_z
,
65 !HasBit(image
, SPRITE_MODIFIER_OPAQUE
) && IsTransparencySet(to
)
68 int offs_x
= child_offset_is_unsigned
? (uint8
)dtss
->delta_x
: dtss
->delta_x
;
69 int offs_y
= child_offset_is_unsigned
? (uint8
)dtss
->delta_y
: dtss
->delta_y
;
70 bool transparent
= !HasBit(image
, SPRITE_MODIFIER_OPAQUE
) && IsTransparencySet(to
);
71 if (parent_sprite_encountered
) {
72 AddChildSpriteScreen(image
, pal
, offs_x
, offs_y
, transparent
);
75 SetBit(image
, PALETTE_MODIFIER_TRANSPARENT
);
76 pal
= PALETTE_TO_TRANSPARENT
;
78 DrawGroundSprite(image
, pal
, NULL
, offs_x
, offs_y
);
85 * Draws a tile sprite sequence in the GUI
86 * @param x X position to draw to
87 * @param y Y position to draw to
88 * @param dts Sprite and subsprites to draw
89 * @param orig_offset Sprite-Offset for original sprites
90 * @param newgrf_offset Sprite-Offset for NewGRF defined sprites
91 * @param default_palette The default recolour sprite to use (typically company colour)
92 * @param child_offset_is_unsigned Whether child sprite offsets are interpreted signed or unsigned
94 void DrawCommonTileSeqInGUI(int x
, int y
, const DrawTileSprites
*dts
, int32 orig_offset
, uint32 newgrf_offset
, PaletteID default_palette
, bool child_offset_is_unsigned
)
96 const DrawTileSeqStruct
*dtss
;
97 Point child_offset
= {0, 0};
99 bool skip_childs
= false;
100 foreach_draw_tile_seq(dtss
, dts
->seq
) {
101 SpriteID image
= dtss
->image
.sprite
;
102 PaletteID pal
= dtss
->image
.pal
;
105 if (!dtss
->IsParentSprite()) continue;
109 /* TTD sprite 0 means no sprite */
110 if (GB(image
, 0, SPRITE_WIDTH
) == 0 && !HasBit(image
, SPRITE_MODIFIER_CUSTOM_SPRITE
)) {
111 skip_childs
= dtss
->IsParentSprite();
115 image
+= (HasBit(image
, SPRITE_MODIFIER_CUSTOM_SPRITE
) ? newgrf_offset
: orig_offset
);
116 if (HasBit(pal
, SPRITE_MODIFIER_CUSTOM_SPRITE
)) pal
+= newgrf_offset
;
118 pal
= SpriteLayoutPaletteTransform(image
, pal
, default_palette
);
120 if (dtss
->IsParentSprite()) {
121 Point pt
= RemapCoords(dtss
->delta_x
, dtss
->delta_y
, dtss
->delta_z
);
122 DrawSprite(image
, pal
, x
+ UnScaleGUI(pt
.x
), y
+ UnScaleGUI(pt
.y
));
124 const Sprite
*spr
= GetSprite(image
& SPRITE_MASK
, ST_NORMAL
);
125 child_offset
.x
= UnScaleGUI(pt
.x
+ spr
->x_offs
);
126 child_offset
.y
= UnScaleGUI(pt
.y
+ spr
->y_offs
);
128 int offs_x
= child_offset_is_unsigned
? (uint8
)dtss
->delta_x
: dtss
->delta_x
;
129 int offs_y
= child_offset_is_unsigned
? (uint8
)dtss
->delta_y
: dtss
->delta_y
;
130 DrawSprite(image
, pal
, x
+ child_offset
.x
+ ScaleGUITrad(offs_x
), y
+ child_offset
.y
+ ScaleGUITrad(offs_y
));