summaryrefslogtreecommitdiff
path: root/src/texteff.cpp
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2009-12-22 12:50:41 +0000
committerrubidium <rubidium@openttd.org>2009-12-22 12:50:41 +0000
commitb0603f4c2e3df439091e6dafb5063619b4a231c4 (patch)
tree92e39aa29a1f2af1afb3f48a34e6d6fb795e95ec /src/texteff.cpp
parent96a8a0f34da838df85a683d87870822288ad36f6 (diff)
downloadopenttd-b0603f4c2e3df439091e6dafb5063619b4a231c4.tar.xz
(svn r18602) -Codechange: unify the viewport sign and text effect drawing
-Fix [FS#3394]: signs could occasionally glitch
Diffstat (limited to 'src/texteff.cpp')
-rw-r--r--src/texteff.cpp134
1 files changed, 36 insertions, 98 deletions
diff --git a/src/texteff.cpp b/src/texteff.cpp
index c18c93ba7..65bea25c0 100644
--- a/src/texteff.cpp
+++ b/src/texteff.cpp
@@ -24,15 +24,20 @@ enum {
INIT_NUM_TEXT_EFFECTS = 20,
};
-struct TextEffect {
- StringID string_id;
- int32 x;
- int32 y;
- int32 right;
- int32 bottom;
- uint16 duration;
- uint64 params_1;
- TextEffectMode mode;
+/** Container for all information about a text effect */
+struct TextEffect : public ViewportSign{
+ StringID string_id; ///< String to draw for the text effect, if INVALID_STRING_ID then it's not valid
+ uint16 duration; ///< How long the text effect should stay
+ uint64 params_1; ///< DParam parameter
+ TextEffectMode mode; ///< Type of text effect
+
+ /** Reset the text effect */
+ void Reset()
+ {
+ this->MarkDirty();
+ this->width_normal = 0;
+ this->string_id = INVALID_STRING_ID;
+ }
};
/* used for text effects */
@@ -40,30 +45,8 @@ static TextEffect *_text_effect_list = NULL;
static uint16 _num_text_effects = INIT_NUM_TEXT_EFFECTS;
/* Text Effects */
-/**
- * Mark the area of the text effect as dirty.
- *
- * This function marks the area of a text effect as dirty for repaint.
- *
- * @param te The TextEffect to mark the area dirty
- * @ingroup dirty
- */
-static void MarkTextEffectAreaDirty(TextEffect *te)
-{
- /* Width and height of the text effect are doubled, so they are correct in both zoom out levels 1x and 2x. */
- MarkAllViewportsDirty(
- te->x,
- te->y - 1,
- (te->right - te->x)*2 + te->x + 1,
- (te->bottom - (te->y - 1)) * 2 + (te->y - 1) + 1
- );
-}
-
-TextEffectID AddTextEffect(StringID msg, int x, int y, uint16 duration, TextEffectMode mode)
+TextEffectID AddTextEffect(StringID msg, int center, int y, uint16 duration, TextEffectMode mode)
{
- TextEffect *te;
- int w;
- char buffer[100];
TextEffectID i;
if (_game_mode == GM_MENU) return INVALID_TE_ID;
@@ -81,22 +64,17 @@ TextEffectID AddTextEffect(StringID msg, int x, int y, uint16 duration, TextEffe
i = _num_text_effects - 1;
}
- te = &_text_effect_list[i];
+ TextEffect *te = &_text_effect_list[i];
/* Start defining this object */
te->string_id = msg;
te->duration = duration;
- te->y = y - FONT_HEIGHT_NORMAL / 2;
- te->bottom = y + FONT_HEIGHT_NORMAL / 2;
te->params_1 = GetDParam(0);
te->mode = mode;
- GetString(buffer, msg, lastof(buffer));
- w = GetStringBoundingBox(buffer).width;
-
- te->x = x - (w >> 1);
- te->right = x + (w >> 1) - 1;
- MarkTextEffectAreaDirty(te);
+ /* Make sure we only dirty the new area */
+ te->width_normal = 0;
+ te->UpdatePosition(center, y, msg);
return i;
}
@@ -104,33 +82,19 @@ TextEffectID AddTextEffect(StringID msg, int x, int y, uint16 duration, TextEffe
void UpdateTextEffect(TextEffectID te_id, StringID msg)
{
assert(te_id < _num_text_effects);
- TextEffect *te;
/* Update details */
- te = &_text_effect_list[te_id];
+ TextEffect *te = &_text_effect_list[te_id];
te->string_id = msg;
te->params_1 = GetDParam(0);
- /* Update width of text effect */
- char buffer[100];
- GetString(buffer, msg, lastof(buffer));
- int w = GetStringBoundingBox(buffer).width;
-
- /* Only allow to make it broader, so it completely covers the old text. That avoids remnants of the old text. */
- int right_new = te->x + w;
- if (te->right < right_new) te->right = right_new;
-
- MarkTextEffectAreaDirty(te);
+ te->UpdatePosition(te->center, te->top, msg);
}
void RemoveTextEffect(TextEffectID te_id)
{
assert(te_id < _num_text_effects);
- TextEffect *te;
-
- te = &_text_effect_list[te_id];
- MarkTextEffectAreaDirty(te);
- te->string_id = INVALID_STRING_ID;
+ _text_effect_list[te_id].Reset();
}
static void MoveTextEffect(TextEffect *te)
@@ -138,13 +102,13 @@ static void MoveTextEffect(TextEffect *te)
/* Never expire for duration of 0xFFFF */
if (te->duration == 0xFFFF) return;
if (te->duration < 8) {
- te->string_id = INVALID_STRING_ID;
+ te->Reset();
} else {
te->duration -= 8;
- te->y--;
- te->bottom--;
+ te->MarkDirty();
+ te->top--;
+ te->MarkDirty();
}
- MarkTextEffectAreaDirty(te);
}
void MoveAllTextEffects()
@@ -164,41 +128,15 @@ void InitTextEffects()
void DrawTextEffects(DrawPixelInfo *dpi)
{
- switch (dpi->zoom) {
- case ZOOM_LVL_NORMAL:
- for (TextEffectID i = 0; i < _num_text_effects; i++) {
- TextEffect *te = &_text_effect_list[i];
- if (te->string_id != INVALID_STRING_ID &&
- dpi->left <= te->right &&
- dpi->top <= te->bottom &&
- dpi->left + dpi->width > te->x &&
- dpi->top + dpi->height > te->y) {
- if (te->mode == TE_RISING || (_settings_client.gui.loading_indicators && !IsTransparencySet(TO_LOADING))) {
- AddStringToDraw(te->x, te->y, te->string_id, te->params_1, INVALID_STRING_ID);
- }
- }
- }
- break;
-
- case ZOOM_LVL_OUT_2X:
- for (TextEffectID i = 0; i < _num_text_effects; i++) {
- TextEffect *te = &_text_effect_list[i];
- if (te->string_id != INVALID_STRING_ID &&
- 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) {
- if (te->mode == TE_RISING || (_settings_client.gui.loading_indicators && !IsTransparencySet(TO_LOADING))) {
- AddStringToDraw(te->x, te->y, (StringID)(te->string_id - 1), te->params_1, INVALID_STRING_ID);
- }
- }
- }
- break;
-
- case ZOOM_LVL_OUT_4X:
- case ZOOM_LVL_OUT_8X:
- break;
-
- default: NOT_REACHED();
+ /* Don't draw the text effects when zoomed out a lot */
+ if (dpi->zoom > ZOOM_LVL_OUT_2X) return;
+
+ for (TextEffectID i = 0; i < _num_text_effects; i++) {
+ const TextEffect *te = &_text_effect_list[i];
+ if (te->string_id == INVALID_STRING_ID) continue;
+
+ if (te->mode == TE_RISING || (_settings_client.gui.loading_indicators && !IsTransparencySet(TO_LOADING))) {
+ ViewportAddString(dpi, ZOOM_LVL_OUT_2X, te, te->string_id, te->string_id - 1, 0, te->params_1);
+ }
}
}