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