00001 /* $Id: animated_tile.cpp 15299 2009-01-31 20:16:06Z smatz $ */ 00002 00005 #include "stdafx.h" 00006 #include "core/alloc_func.hpp" 00007 #include "functions.h" 00008 00010 TileIndex *_animated_tile_list = NULL; 00012 uint _animated_tile_count = 0; 00014 uint _animated_tile_allocated = 0; 00015 00020 void DeleteAnimatedTile(TileIndex tile) 00021 { 00022 for (TileIndex *ti = _animated_tile_list; ti < _animated_tile_list + _animated_tile_count; ti++) { 00023 if (tile == *ti) { 00024 /* Remove the hole 00025 * The order of the remaining elements must stay the same, otherwise the animation loop 00026 * may miss a tile; that's why we must use memmove instead of just moving the last element. 00027 */ 00028 memmove(ti, ti + 1, (_animated_tile_list + _animated_tile_count - (ti + 1)) * sizeof(*ti)); 00029 _animated_tile_count--; 00030 MarkTileDirtyByTile(tile); 00031 return; 00032 } 00033 } 00034 } 00035 00041 void AddAnimatedTile(TileIndex tile) 00042 { 00043 MarkTileDirtyByTile(tile); 00044 00045 for (const TileIndex *ti = _animated_tile_list; ti < _animated_tile_list + _animated_tile_count; ti++) { 00046 if (tile == *ti) return; 00047 } 00048 00049 /* Table not large enough, so make it larger */ 00050 if (_animated_tile_count == _animated_tile_allocated) { 00051 _animated_tile_allocated *= 2; 00052 _animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, _animated_tile_allocated); 00053 } 00054 00055 _animated_tile_list[_animated_tile_count] = tile; 00056 _animated_tile_count++; 00057 } 00058 00062 void AnimateAnimatedTiles() 00063 { 00064 const TileIndex *ti = _animated_tile_list; 00065 while (ti < _animated_tile_list + _animated_tile_count) { 00066 const TileIndex curr = *ti; 00067 AnimateTile(curr); 00068 /* During the AnimateTile call, DeleteAnimatedTile could have been called, 00069 * deleting an element we've already processed and pushing the rest one 00070 * slot to the left. We can detect this by checking whether the index 00071 * in the current slot has changed - if it has, an element has been deleted, 00072 * and we should process the current slot again instead of going forward. 00073 * NOTE: this will still break if more than one animated tile is being 00074 * deleted during the same AnimateTile call, but no code seems to 00075 * be doing this anyway. 00076 */ 00077 if (*ti == curr) ++ti; 00078 } 00079 } 00080 00084 void InitializeAnimatedTiles() 00085 { 00086 _animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, 256); 00087 _animated_tile_count = 0; 00088 _animated_tile_allocated = 256; 00089 }