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 "core/alloc_func.hpp" 00014 #include "functions.h" 00015 00017 TileIndex *_animated_tile_list = NULL; 00019 uint _animated_tile_count = 0; 00021 uint _animated_tile_allocated = 0; 00022 00027 void DeleteAnimatedTile(TileIndex tile) 00028 { 00029 for (TileIndex *ti = _animated_tile_list; ti < _animated_tile_list + _animated_tile_count; ti++) { 00030 if (tile == *ti) { 00031 /* Remove the hole 00032 * The order of the remaining elements must stay the same, otherwise the animation loop 00033 * may miss a tile; that's why we must use memmove instead of just moving the last element. 00034 */ 00035 memmove(ti, ti + 1, (_animated_tile_list + _animated_tile_count - (ti + 1)) * sizeof(*ti)); 00036 _animated_tile_count--; 00037 MarkTileDirtyByTile(tile); 00038 return; 00039 } 00040 } 00041 } 00042 00048 void AddAnimatedTile(TileIndex tile) 00049 { 00050 MarkTileDirtyByTile(tile); 00051 00052 for (const TileIndex *ti = _animated_tile_list; ti < _animated_tile_list + _animated_tile_count; ti++) { 00053 if (tile == *ti) return; 00054 } 00055 00056 /* Table not large enough, so make it larger */ 00057 if (_animated_tile_count == _animated_tile_allocated) { 00058 _animated_tile_allocated *= 2; 00059 _animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, _animated_tile_allocated); 00060 } 00061 00062 _animated_tile_list[_animated_tile_count] = tile; 00063 _animated_tile_count++; 00064 } 00065 00069 void AnimateAnimatedTiles() 00070 { 00071 const TileIndex *ti = _animated_tile_list; 00072 while (ti < _animated_tile_list + _animated_tile_count) { 00073 const TileIndex curr = *ti; 00074 AnimateTile(curr); 00075 /* During the AnimateTile call, DeleteAnimatedTile could have been called, 00076 * deleting an element we've already processed and pushing the rest one 00077 * slot to the left. We can detect this by checking whether the index 00078 * in the current slot has changed - if it has, an element has been deleted, 00079 * and we should process the current slot again instead of going forward. 00080 * NOTE: this will still break if more than one animated tile is being 00081 * deleted during the same AnimateTile call, but no code seems to 00082 * be doing this anyway. 00083 */ 00084 if (*ti == curr) ++ti; 00085 } 00086 } 00087 00091 void InitializeAnimatedTiles() 00092 { 00093 _animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, 256); 00094 _animated_tile_count = 0; 00095 _animated_tile_allocated = 256; 00096 }