animated_tile.cpp

Go to the documentation of this file.
00001 /* $Id: animated_tile.cpp 13301 2008-05-27 21:41:00Z rubidium $ */
00002 
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "saveload.h"
00008 #include "landscape.h"
00009 #include "core/alloc_func.hpp"
00010 #include "functions.h"
00011 
00013 TileIndex *_animated_tile_list = NULL;
00015 uint _animated_tile_count = 0;
00017 static uint _animated_tile_allocated = 0;
00018 
00023 void DeleteAnimatedTile(TileIndex tile)
00024 {
00025   for (TileIndex *ti = _animated_tile_list; ti < _animated_tile_list + _animated_tile_count; ti++) {
00026     if (tile == *ti) {
00027       /* Remove the hole
00028        * The order of the remaining elements must stay the same, otherwise the animation loop
00029        * may miss a tile; that's why we must use memmove instead of just moving the last element.
00030        */
00031       memmove(ti, ti + 1, (_animated_tile_list + _animated_tile_count - (ti + 1)) * sizeof(*ti));
00032       _animated_tile_count--;
00033       MarkTileDirtyByTile(tile);
00034       return;
00035     }
00036   }
00037 }
00038 
00044 void AddAnimatedTile(TileIndex tile)
00045 {
00046   MarkTileDirtyByTile(tile);
00047 
00048   for (const TileIndex *ti = _animated_tile_list; ti < _animated_tile_list + _animated_tile_count; ti++) {
00049     if (tile == *ti) return;
00050   }
00051 
00052   /* Table not large enough, so make it larger */
00053   if (_animated_tile_count == _animated_tile_allocated) {
00054     _animated_tile_allocated *= 2;
00055     _animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, _animated_tile_allocated);
00056   }
00057 
00058   _animated_tile_list[_animated_tile_count] = tile;
00059   _animated_tile_count++;
00060 }
00061 
00065 void AnimateAnimatedTiles()
00066 {
00067   const TileIndex *ti = _animated_tile_list;
00068   while (ti < _animated_tile_list + _animated_tile_count) {
00069     const TileIndex curr = *ti;
00070     AnimateTile(curr);
00071     /* During the AnimateTile call, DeleteAnimatedTile could have been called,
00072      * deleting an element we've already processed and pushing the rest one
00073      * slot to the left. We can detect this by checking whether the index
00074      * in the current slot has changed - if it has, an element has been deleted,
00075      * and we should process the current slot again instead of going forward.
00076      * NOTE: this will still break if more than one animated tile is being
00077      *       deleted during the same AnimateTile call, but no code seems to
00078      *       be doing this anyway.
00079      */
00080     if (*ti == curr) ++ti;
00081   }
00082 }
00083 
00087 void InitializeAnimatedTiles()
00088 {
00089   _animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, 256);
00090   _animated_tile_count = 0;
00091   _animated_tile_allocated = 256;
00092 }
00093 
00097 static void Save_ANIT()
00098 {
00099   SlSetLength(_animated_tile_count * sizeof(*_animated_tile_list));
00100   SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
00101 }
00102 
00106 static void Load_ANIT()
00107 {
00108   /* Before version 80 we did NOT have a variable length animated tile table */
00109   if (CheckSavegameVersion(80)) {
00110     /* In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) */
00111     SlArray(_animated_tile_list, 256, CheckSavegameVersion(6) ? (SLE_FILE_U16 | SLE_VAR_U32) : SLE_UINT32);
00112 
00113     for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
00114       if (_animated_tile_list[_animated_tile_count] == 0) break;
00115     }
00116     return;
00117   }
00118 
00119   _animated_tile_count = (uint)SlGetFieldLength() / sizeof(*_animated_tile_list);
00120 
00121   /* Determine a nice rounded size for the amount of allocated tiles */
00122   _animated_tile_allocated = 256;
00123   while (_animated_tile_allocated < _animated_tile_count) _animated_tile_allocated *= 2;
00124 
00125   _animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, _animated_tile_allocated);
00126   SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
00127 }
00128 
00133 extern const ChunkHandler _animated_tile_chunk_handlers[] = {
00134   { 'ANIT', Save_ANIT, Load_ANIT, CH_RIFF | CH_LAST},
00135 };

Generated on Fri Nov 21 19:01:31 2008 for openttd by  doxygen 1.5.6