src/texteff.cpp
branchnoai
changeset 10294 7798ae816af8
parent 9724 b39bc69bb2f2
child 10455 22c441f5adf9
equal deleted inserted replaced
10292:7856e972f8aa 10294:7798ae816af8
     2 
     2 
     3 /** @file texteff.cpp */
     3 /** @file texteff.cpp */
     4 
     4 
     5 #include "stdafx.h"
     5 #include "stdafx.h"
     6 #include "openttd.h"
     6 #include "openttd.h"
     7 #include "tile_cmd.h"
       
     8 #include "landscape.h"
     7 #include "landscape.h"
     9 #include "gfx_func.h"
     8 #include "gfx_func.h"
    10 #include "saveload.h"
       
    11 #include "console.h"
     9 #include "console.h"
    12 #include "variables.h"
    10 #include "variables.h"
    13 #include "blitter/factory.hpp"
    11 #include "blitter/factory.hpp"
    14 #include "texteff.hpp"
    12 #include "texteff.hpp"
    15 #include "video/video_driver.hpp"
    13 #include "video/video_driver.hpp"
   421 			break;
   419 			break;
   422 
   420 
   423 		default: NOT_REACHED();
   421 		default: NOT_REACHED();
   424 	}
   422 	}
   425 }
   423 }
   426 
       
   427 /** The table/list with animated tiles. */
       
   428 TileIndex *_animated_tile_list = NULL;
       
   429 /** The number of animated tiles in the current state. */
       
   430 uint _animated_tile_count = 0;
       
   431 /** The number of slots for animated tiles allocated currently. */
       
   432 static uint _animated_tile_allocated = 0;
       
   433 
       
   434 /**
       
   435  * Removes the given tile from the animated tile table.
       
   436  * @param tile the tile to remove
       
   437  */
       
   438 void DeleteAnimatedTile(TileIndex tile)
       
   439 {
       
   440 	for (TileIndex *ti = _animated_tile_list; ti < _animated_tile_list + _animated_tile_count; ti++) {
       
   441 		if (tile == *ti) {
       
   442 			/* Remove the hole
       
   443 			 * The order of the remaining elements must stay the same, otherwise the animation loop
       
   444 			 * may miss a tile; that's why we must use memmove instead of just moving the last element.
       
   445 			 */
       
   446 			memmove(ti, ti + 1, (_animated_tile_list + _animated_tile_count - (ti + 1)) * sizeof(*ti));
       
   447 			_animated_tile_count--;
       
   448 			MarkTileDirtyByTile(tile);
       
   449 			return;
       
   450 		}
       
   451 	}
       
   452 }
       
   453 
       
   454 /**
       
   455  * Add the given tile to the animated tile table (if it does not exist
       
   456  * on that table yet). Also increases the size of the table if necessary.
       
   457  * @param tile the tile to make animated
       
   458  */
       
   459 void AddAnimatedTile(TileIndex tile)
       
   460 {
       
   461 	MarkTileDirtyByTile(tile);
       
   462 
       
   463 	for (const TileIndex *ti = _animated_tile_list; ti < _animated_tile_list + _animated_tile_count; ti++) {
       
   464 		if (tile == *ti) return;
       
   465 	}
       
   466 
       
   467 	/* Table not large enough, so make it larger */
       
   468 	if (_animated_tile_count == _animated_tile_allocated) {
       
   469 		_animated_tile_allocated *= 2;
       
   470 		_animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, _animated_tile_allocated);
       
   471 	}
       
   472 
       
   473 	_animated_tile_list[_animated_tile_count] = tile;
       
   474 	_animated_tile_count++;
       
   475 }
       
   476 
       
   477 /**
       
   478  * Animate all tiles in the animated tile list, i.e.\ call AnimateTile on them.
       
   479  */
       
   480 void AnimateAnimatedTiles()
       
   481 {
       
   482 	const TileIndex *ti = _animated_tile_list;
       
   483 	while (ti < _animated_tile_list + _animated_tile_count) {
       
   484 		const TileIndex curr = *ti;
       
   485 		AnimateTile(curr);
       
   486 		/* During the AnimateTile call, DeleteAnimatedTile could have been called,
       
   487 		 * deleting an element we've already processed and pushing the rest one
       
   488 		 * slot to the left. We can detect this by checking whether the index
       
   489 		 * in the current slot has changed - if it has, an element has been deleted,
       
   490 		 * and we should process the current slot again instead of going forward.
       
   491 		 * NOTE: this will still break if more than one animated tile is being
       
   492 		 *       deleted during the same AnimateTile call, but no code seems to
       
   493 		 *       be doing this anyway.
       
   494 		 */
       
   495 		if (*ti == curr) ++ti;
       
   496 	}
       
   497 }
       
   498 
       
   499 /**
       
   500  * Initialize all animated tile variables to some known begin point
       
   501  */
       
   502 void InitializeAnimatedTiles()
       
   503 {
       
   504 	_animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, 256);
       
   505 	_animated_tile_count = 0;
       
   506 	_animated_tile_allocated = 256;
       
   507 }
       
   508 
       
   509 /**
       
   510  * Save the ANIT chunk.
       
   511  */
       
   512 static void Save_ANIT()
       
   513 {
       
   514 	SlSetLength(_animated_tile_count * sizeof(*_animated_tile_list));
       
   515 	SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
       
   516 }
       
   517 
       
   518 /**
       
   519  * Load the ANIT chunk; the chunk containing the animated tiles.
       
   520  */
       
   521 static void Load_ANIT()
       
   522 {
       
   523 	/* Before version 80 we did NOT have a variable length animated tile table */
       
   524 	if (CheckSavegameVersion(80)) {
       
   525 		/* In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) */
       
   526 		SlArray(_animated_tile_list, 256, CheckSavegameVersion(6) ? (SLE_FILE_U16 | SLE_VAR_U32) : SLE_UINT32);
       
   527 
       
   528 		for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
       
   529 			if (_animated_tile_list[_animated_tile_count] == 0) break;
       
   530 		}
       
   531 		return;
       
   532 	}
       
   533 
       
   534 	_animated_tile_count = SlGetFieldLength() / sizeof(*_animated_tile_list);
       
   535 
       
   536 	/* Determine a nice rounded size for the amount of allocated tiles */
       
   537 	_animated_tile_allocated = 256;
       
   538 	while (_animated_tile_allocated < _animated_tile_count) _animated_tile_allocated *= 2;
       
   539 
       
   540 	_animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, _animated_tile_allocated);
       
   541 	SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
       
   542 }
       
   543 
       
   544 /**
       
   545  * "Definition" imported by the saveload code to be able to load and save
       
   546  * the animated tile table.
       
   547  */
       
   548 extern const ChunkHandler _animated_tile_chunk_handlers[] = {
       
   549 	{ 'ANIT', Save_ANIT, Load_ANIT, CH_RIFF | CH_LAST},
       
   550 };