texteff.cpp
Go to the documentation of this file.00001
00002
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "strings_type.h"
00008 #include "texteff.hpp"
00009 #include "core/bitmath_func.hpp"
00010 #include "transparency.h"
00011 #include "strings_func.h"
00012 #include "core/alloc_func.hpp"
00013 #include "functions.h"
00014 #include "viewport_func.h"
00015 #include "settings_type.h"
00016
00017 enum {
00018 INIT_NUM_TEXT_EFFECTS = 20,
00019 };
00020
00021 struct TextEffect {
00022 StringID string_id;
00023 int32 x;
00024 int32 y;
00025 int32 right;
00026 int32 bottom;
00027 uint16 duration;
00028 uint64 params_1;
00029 uint64 params_2;
00030 TextEffectMode mode;
00031 };
00032
00033
00034 static TextEffect *_text_effect_list = NULL;
00035 static uint16 _num_text_effects = INIT_NUM_TEXT_EFFECTS;
00036
00037
00046 static void MarkTextEffectAreaDirty(TextEffect *te)
00047 {
00048
00049 MarkAllViewportsDirty(
00050 te->x,
00051 te->y - 1,
00052 (te->right - te->x)*2 + te->x + 1,
00053 (te->bottom - (te->y - 1)) * 2 + (te->y - 1) + 1
00054 );
00055 }
00056
00057 TextEffectID AddTextEffect(StringID msg, int x, int y, uint16 duration, TextEffectMode mode)
00058 {
00059 TextEffect *te;
00060 int w;
00061 char buffer[100];
00062 TextEffectID i;
00063
00064 if (_game_mode == GM_MENU) return INVALID_TE_ID;
00065
00066
00067 for (i = 0; i < _num_text_effects; i++) {
00068 if (_text_effect_list[i].string_id == INVALID_STRING_ID) break;
00069 }
00070
00071
00072 if (i == _num_text_effects) {
00073 _num_text_effects += 25;
00074 _text_effect_list = ReallocT<TextEffect>(_text_effect_list, _num_text_effects);
00075 for (; i < _num_text_effects; i++) _text_effect_list[i].string_id = INVALID_STRING_ID;
00076 i = _num_text_effects - 1;
00077 }
00078
00079 te = &_text_effect_list[i];
00080
00081
00082 te->string_id = msg;
00083 te->duration = duration;
00084 te->y = y - 5;
00085 te->bottom = y + 5;
00086 te->params_1 = GetDParam(0);
00087 te->params_2 = GetDParam(4);
00088 te->mode = mode;
00089
00090 GetString(buffer, msg, lastof(buffer));
00091 w = GetStringBoundingBox(buffer).width;
00092
00093 te->x = x - (w >> 1);
00094 te->right = x + (w >> 1) - 1;
00095 MarkTextEffectAreaDirty(te);
00096
00097 return i;
00098 }
00099
00100 void UpdateTextEffect(TextEffectID te_id, StringID msg)
00101 {
00102 assert(te_id < _num_text_effects);
00103 TextEffect *te;
00104
00105
00106 te = &_text_effect_list[te_id];
00107 te->string_id = msg;
00108 te->params_1 = GetDParam(0);
00109 te->params_2 = GetDParam(4);
00110
00111
00112 char buffer[100];
00113 GetString(buffer, msg, lastof(buffer));
00114 int w = GetStringBoundingBox(buffer).width;
00115
00116
00117 int right_new = te->x + w;
00118 if (te->right < right_new) te->right = right_new;
00119
00120 MarkTextEffectAreaDirty(te);
00121 }
00122
00123 void RemoveTextEffect(TextEffectID te_id)
00124 {
00125 assert(te_id < _num_text_effects);
00126 TextEffect *te;
00127
00128 te = &_text_effect_list[te_id];
00129 MarkTextEffectAreaDirty(te);
00130 te->string_id = INVALID_STRING_ID;
00131 }
00132
00133 static void MoveTextEffect(TextEffect *te)
00134 {
00135
00136 if (te->duration == 0xFFFF) return;
00137 if (te->duration < 8) {
00138 te->string_id = INVALID_STRING_ID;
00139 } else {
00140 te->duration -= 8;
00141 te->y--;
00142 te->bottom--;
00143 }
00144 MarkTextEffectAreaDirty(te);
00145 }
00146
00147 void MoveAllTextEffects()
00148 {
00149 for (TextEffectID i = 0; i < _num_text_effects; i++) {
00150 TextEffect *te = &_text_effect_list[i];
00151 if (te->string_id != INVALID_STRING_ID && te->mode == TE_RISING) MoveTextEffect(te);
00152 }
00153 }
00154
00155 void InitTextEffects()
00156 {
00157 if (_text_effect_list == NULL) _text_effect_list = MallocT<TextEffect>(_num_text_effects);
00158
00159 for (TextEffectID i = 0; i < _num_text_effects; i++) _text_effect_list[i].string_id = INVALID_STRING_ID;
00160 }
00161
00162 void DrawTextEffects(DrawPixelInfo *dpi)
00163 {
00164 switch (dpi->zoom) {
00165 case ZOOM_LVL_NORMAL:
00166 for (TextEffectID i = 0; i < _num_text_effects; i++) {
00167 TextEffect *te = &_text_effect_list[i];
00168 if (te->string_id != INVALID_STRING_ID &&
00169 dpi->left <= te->right &&
00170 dpi->top <= te->bottom &&
00171 dpi->left + dpi->width > te->x &&
00172 dpi->top + dpi->height > te->y) {
00173 if (te->mode == TE_RISING || (_settings_client.gui.loading_indicators && !IsTransparencySet(TO_LOADING))) {
00174 AddStringToDraw(te->x, te->y, te->string_id, te->params_1, te->params_2);
00175 }
00176 }
00177 }
00178 break;
00179
00180 case ZOOM_LVL_OUT_2X:
00181 for (TextEffectID i = 0; i < _num_text_effects; i++) {
00182 TextEffect *te = &_text_effect_list[i];
00183 if (te->string_id != INVALID_STRING_ID &&
00184 dpi->left <= te->right * 2 - te->x &&
00185 dpi->top <= te->bottom * 2 - te->y &&
00186 dpi->left + dpi->width > te->x &&
00187 dpi->top + dpi->height > te->y) {
00188 if (te->mode == TE_RISING || (_settings_client.gui.loading_indicators && !IsTransparencySet(TO_LOADING))) {
00189 AddStringToDraw(te->x, te->y, (StringID)(te->string_id - 1), te->params_1, te->params_2);
00190 }
00191 }
00192 }
00193 break;
00194
00195 case ZOOM_LVL_OUT_4X:
00196 case ZOOM_LVL_OUT_8X:
00197 break;
00198
00199 default: NOT_REACHED();
00200 }
00201 }