179 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			179 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "stdafx.h"
 | |
| #include "ttd.h"
 | |
| #include "gfx.h"
 | |
| #include "viewport.h"
 | |
| #include "saveload.h"
 | |
| 
 | |
| typedef struct TextEffect {
 | |
| 	StringID string_id;
 | |
| 	int16 x,y,right,bottom;
 | |
| 	uint16 duration;
 | |
| 	uint32 params_1;
 | |
| 	uint32 params_2;
 | |
| } TextEffect;
 | |
| 
 | |
| static TextEffect _text_effect_list[30];
 | |
| TileIndex _animated_tile_list[256];
 | |
| 
 | |
| static void MarkTextEffectAreaDirty(TextEffect *te)
 | |
| {
 | |
| 	MarkAllViewportsDirty(
 | |
| 		te->x,
 | |
| 		te->y - 1,
 | |
| 		(te->right - te->x)*2 + te->x + 1,
 | |
| 		(te->bottom - (te->y - 1)) * 2 + (te->y - 1) + 1
 | |
| 	);
 | |
| }
 | |
| 
 | |
| void AddTextEffect(StringID msg, int x, int y, uint16 duration)
 | |
| {
 | |
| 	TextEffect *te;
 | |
| 	int w;
 | |
| 	char buffer[100];
 | |
| 
 | |
| 	if (_game_mode == GM_MENU)
 | |
| 		return;
 | |
| 
 | |
| 	for (te = _text_effect_list; te->string_id != 0xFFFF; ) {
 | |
| 		if (++te == endof(_text_effect_list))
 | |
| 			return;
 | |
| 	}
 | |
| 
 | |
| 	te->string_id = msg;
 | |
| 	te->duration = duration;
 | |
| 	te->y = y - 5;
 | |
| 	te->bottom = y + 5;
 | |
| 	te->params_1 = GET_DPARAM32(0);
 | |
| 	te->params_2 = GET_DPARAM32(4);
 | |
| 
 | |
| 	GetString(buffer, msg);
 | |
| 	w = GetStringWidth(buffer);
 | |
| 
 | |
| 	te->x = x - (w >> 1);
 | |
| 	te->right = x + (w >> 1) - 1;
 | |
| 	MarkTextEffectAreaDirty(te);
 | |
| }
 | |
| 
 | |
| static void MoveTextEffect(TextEffect *te)
 | |
| {
 | |
| 	if (te->duration < 8) {
 | |
| 		te->string_id = 0xFFFF;
 | |
| 	} else {
 | |
| 		te->duration-=8;
 | |
| 		te->y--;
 | |
| 		te->bottom--;
 | |
| 	}
 | |
| 	MarkTextEffectAreaDirty(te);
 | |
| }
 | |
| 
 | |
| void MoveAllTextEffects()
 | |
| {
 | |
| 	TextEffect *te;
 | |
| 
 | |
| 	for (te = _text_effect_list; te != endof(_text_effect_list); te++ ) {
 | |
| 		if (te->string_id != 0xFFFF)
 | |
| 			MoveTextEffect(te);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void InitTextEffects()
 | |
| {
 | |
| 	TextEffect *te;
 | |
| 
 | |
| 	for (te = _text_effect_list; te != endof(_text_effect_list); te++ ) {
 | |
| 		te->string_id = 0xFFFF;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void DrawTextEffects(DrawPixelInfo *dpi)
 | |
| {
 | |
| 	TextEffect *te;
 | |
| 
 | |
| 	if (dpi->zoom < 1) {
 | |
| 		for (te = _text_effect_list; te != endof(_text_effect_list); te++ ) {
 | |
| 			if (te->string_id == 0xFFFF)
 | |
| 				continue;
 | |
| 
 | |
| 			/* intersection? */
 | |
| 			if ((int16)dpi->left > te->right ||
 | |
| 					(int16)dpi->top > te->bottom ||
 | |
| 					(int16)(dpi->left + dpi->width) <= te->x ||
 | |
| 					(int16)(dpi->top + dpi->height) <= te->y)
 | |
| 						continue;
 | |
| 			AddStringToDraw(te->x, te->y, te->string_id, te->params_1, te->params_2);
 | |
| 		}
 | |
| 	} else if (dpi->zoom == 1) {
 | |
| 		for (te = _text_effect_list; te != endof(_text_effect_list); te++ ) {
 | |
| 			if (te->string_id == 0xFFFF)
 | |
| 				continue;
 | |
| 
 | |
| 			/* intersection? */
 | |
| 			if (dpi->left > te->right*2 -  te->x ||
 | |
| 					dpi->top > te->bottom*2 - te->y ||
 | |
| 					(dpi->left + dpi->width) <= te->x ||
 | |
| 					(dpi->top + dpi->height) <= te->y)
 | |
| 						continue;
 | |
| 			AddStringToDraw(te->x, te->y, (StringID)(te->string_id-1), te->params_1, te->params_2);
 | |
| 		}
 | |
| 
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void DeleteAnimatedTile(uint tile)
 | |
| {
 | |
| 	TileIndex *ti;
 | |
| 
 | |
| 	for(ti=_animated_tile_list; ti!=endof(_animated_tile_list); ti++) {
 | |
| 		if ( (TileIndex)tile == *ti) {
 | |
| 			/* remove the hole */
 | |
| 			memcpy_overlapping(ti, ti+1, endof(_animated_tile_list) - 1 - ti);
 | |
| 			/* and clear last item */
 | |
| 			endof(_animated_tile_list)[-1] = 0;
 | |
| 			MarkTileDirtyByTile(tile);
 | |
| 			return;
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| bool AddAnimatedTile(uint tile)
 | |
| {
 | |
| 	TileIndex *ti;
 | |
| 
 | |
| 	for(ti=_animated_tile_list; ti!=endof(_animated_tile_list); ti++) {
 | |
| 		if ( (TileIndex)tile == *ti || *ti == 0) {
 | |
| 			*ti = tile;
 | |
| 			MarkTileDirtyByTile(tile);
 | |
| 			return true;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return false;
 | |
| }
 | |
| 
 | |
| void AnimateAnimatedTiles()
 | |
| {
 | |
| 	TileIndex *ti;
 | |
| 	uint tile;
 | |
| 
 | |
| 	for(ti=_animated_tile_list; ti!=endof(_animated_tile_list) && (tile=*ti) != 0; ti++) {
 | |
| 		AnimateTile(tile);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void InitializeAnimatedTiles()
 | |
| {
 | |
| 	memset(_animated_tile_list, 0, sizeof(_animated_tile_list));
 | |
| }
 | |
| 
 | |
| static void SaveLoad_ANIT()
 | |
| {
 | |
| 	SlArray(_animated_tile_list, lengthof(_animated_tile_list), SLE_UINT16);
 | |
| }
 | |
| 
 | |
| 
 | |
| const ChunkHandler _animated_tile_chunk_handlers[] = {
 | |
| 	{ 'ANIT', SaveLoad_ANIT, SaveLoad_ANIT, CH_RIFF | CH_LAST},
 | |
| };
 | |
| 
 | |
| 
 |