# sprite.cpp

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * 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.
    00006  * 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.
    00007  * 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/>.
    00008  */
    00009
    00012 #include "stdafx.h"
    00013 #include "sprite.h"
    00014 #include "viewport_func.h"
    00015 #include "landscape.h"
    00016 #include "spritecache.h"
    00017 #include "core/alloc_func.hpp"
    00018 #include "core/mem_func.hpp"
    00019
    00020
    00031 void DrawCommonTileSeq(const TileInfo *ti, const DrawTileSprites *dts, TransparencyOption to, int32 orig_offset, uint32 newgrf_offset, PaletteID default_palette, bool child_offset_is_unsigned)
    00032 {
    00033   bool parent_sprite_encountered = false;
    00034   const DrawTileSeqStruct *dtss;
    00035   foreach_draw_tile_seq(dtss, dts->seq) {
    00036     SpriteID image = dtss->image.sprite;
    00037
    00038     /* TTD sprite 0 means no sprite */
    00039     if (GB(image, 0, SPRITE_WIDTH) == 0 && !HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE)) continue;
    00040
    00041     /* Stop drawing sprite sequence once we meet a sprite that doesn't have to be opaque */
    00042     if (IsInvisibilitySet(to) && !HasBit(image, SPRITE_MODIFIER_OPAQUE)) return;
    00043
    00044     image += (HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE) ? newgrf_offset : orig_offset);
    00045
    00046     PaletteID pal = SpriteLayoutPaletteTransform(image, dtss->image.pal, default_palette);
    00047
    00048     if ((byte)dtss->delta_z != 0x80) {
    00049       parent_sprite_encountered = true;
    00050       AddSortableSpriteToDraw(
    00051         image, pal,
    00052         ti->x + dtss->delta_x, ti->y + dtss->delta_y,
    00053         dtss->size_x, dtss->size_y,
    00054         dtss->size_z, ti->z + dtss->delta_z,
    00055         !HasBit(image, SPRITE_MODIFIER_OPAQUE) && IsTransparencySet(to)
    00056       );
    00057     } else {
    00058       int offs_x = child_offset_is_unsigned ? (uint8)dtss->delta_x : dtss->delta_x;
    00059       int offs_y = child_offset_is_unsigned ? (uint8)dtss->delta_y : dtss->delta_y;
    00060       bool transparent = !HasBit(image, SPRITE_MODIFIER_OPAQUE) && IsTransparencySet(to);
    00061       if (parent_sprite_encountered) {
    00062         AddChildSpriteScreen(image, pal, offs_x, offs_y, transparent);
    00063       } else {
    00064         if (transparent) {
    00065           SetBit(image, PALETTE_MODIFIER_TRANSPARENT);
    00066           pal = PALETTE_TO_TRANSPARENT;
    00067         }
    00068         DrawGroundSprite(image, pal, NULL, offs_x, offs_y);
    00069       }
    00070     }
    00071   }
    00072 }
    00073
    00084 void DrawCommonTileSeqInGUI(int x, int y, const DrawTileSprites *dts, int32 orig_offset, uint32 newgrf_offset, PaletteID default_palette, bool child_offset_is_unsigned)
    00085 {
    00086   const DrawTileSeqStruct *dtss;
    00087   Point child_offset = {0, 0};
    00088
    00089   foreach_draw_tile_seq(dtss, dts->seq) {
    00090     SpriteID image = dtss->image.sprite;
    00091
    00092     /* TTD sprite 0 means no sprite */
    00093     if (GB(image, 0, SPRITE_WIDTH) == 0 && !HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE)) continue;
    00094
    00095     image += (HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE) ? newgrf_offset : orig_offset);
    00096
    00097     PaletteID pal = SpriteLayoutPaletteTransform(image, dtss->image.pal, default_palette);
    00098
    00099     if ((byte)dtss->delta_z != 0x80) {
    00100       Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
    00101       DrawSprite(image, pal, x + pt.x, y + pt.y);
    00102
    00103       const Sprite *spr = GetSprite(image & SPRITE_MASK, ST_NORMAL);
    00104       child_offset.x = pt.x + spr->x_offs;
    00105       child_offset.y = pt.y + spr->y_offs;
    00106     } else {
    00107       int offs_x = child_offset_is_unsigned ? (uint8)dtss->delta_x : dtss->delta_x;
    00108       int offs_y = child_offset_is_unsigned ? (uint8)dtss->delta_y : dtss->delta_y;
    00109       DrawSprite(image, pal, x + child_offset.x + offs_x, y + child_offset.y + offs_y);
    00110     }
    00111   }
    00112 }
    00113
    00115 const DrawTileSeqStruct *CopyDrawTileSeqStruct(const DrawTileSeqStruct *dtss)
    00116 {
    00117   const DrawTileSeqStruct *element;
    00118
    00119   size_t count = 1; // 1 for the terminator
    00120   foreach_draw_tile_seq(element, dtss) count++;
    00121
    00122   DrawTileSeqStruct *copy = MallocT<DrawTileSeqStruct>(count);
    00123   MemCpyT(copy, dtss, count);
    00124
    00125   return copy;
    00126 }