OpenTTD Source 20250205-master-gfd85ab1e2c
texteff.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "texteff.hpp"
12#include "transparency.h"
13#include "strings_func.h"
14#include "viewport_func.h"
15#include "settings_type.h"
16#include "command_type.h"
17#include "timer/timer.h"
18#include "timer/timer_window.h"
19
20#include "safeguards.h"
21
23struct TextEffect : public ViewportSign {
24 std::vector<StringParameterData> params;
26 uint8_t duration;
28
30 void Reset()
31 {
32 this->MarkDirty();
33 this->width_normal = 0;
34 this->string_id = INVALID_STRING_ID;
35 }
36};
37
38static std::vector<struct TextEffect> _text_effects;
39
40/* Text Effects */
41TextEffectID AddTextEffect(StringID msg, int center, int y, uint8_t duration, TextEffectMode mode)
42{
43 if (_game_mode == GM_MENU) return INVALID_TE_ID;
44
45 auto it = std::ranges::find(_text_effects, INVALID_STRING_ID, &TextEffect::string_id);
46 if (it == std::end(_text_effects)) {
47 /* _text_effects.size() is the maximum ID + 1 that has been allocated. We should not allocate INVALID_TE_ID or beyond. */
48 if (_text_effects.size() >= INVALID_TE_ID) return INVALID_TE_ID;
49 it = _text_effects.emplace(std::end(_text_effects));
50 }
51
52 TextEffect &te = *it;
53
54 /* Start defining this object */
55 te.string_id = msg;
56 te.duration = duration;
57 CopyOutDParam(te.params, 2);
58 te.mode = mode;
59
60 /* Make sure we only dirty the new area */
61 te.width_normal = 0;
62 te.UpdatePosition(center, y, msg);
63
64 return static_cast<TextEffectID>(it - std::begin(_text_effects));
65}
66
67void UpdateTextEffect(TextEffectID te_id, StringID msg)
68{
69 /* Update details */
70 TextEffect &te = _text_effects[te_id];
71 if (msg == te.string_id && !HaveDParamChanged(te.params)) return;
72 te.string_id = msg;
73 CopyOutDParam(te.params, 2);
74
75 te.UpdatePosition(te.center, te.top, te.string_id);
76}
77
78void UpdateAllTextEffectVirtCoords()
79{
80 for (auto &te : _text_effects) {
81 if (te.string_id == INVALID_STRING_ID) continue;
83 te.UpdatePosition(te.center, te.top, te.string_id);
84 }
85}
86
87void RemoveTextEffect(TextEffectID te_id)
88{
89 _text_effects[te_id].Reset();
90}
91
93IntervalTimer<TimerWindow> move_all_text_effects_interval = {std::chrono::milliseconds(30), [](uint count) {
94 if (_pause_mode && _game_mode != GM_EDITOR && _settings_game.construction.command_pause_level <= CMDPL_NO_CONSTRUCTION) return;
95
96 for (TextEffect &te : _text_effects) {
97 if (te.string_id == INVALID_STRING_ID) continue;
98 if (te.mode != TE_RISING) continue;
99
100 if (te.duration < count) {
101 te.Reset();
102 continue;
103 }
104
106 te.duration -= count;
107 te.top -= count * ZOOM_BASE;
109 }
110}};
111
112void InitTextEffects()
113{
114 _text_effects.clear();
115 _text_effects.shrink_to_fit();
116}
117
118void DrawTextEffects(DrawPixelInfo *dpi)
119{
120 /* Don't draw the text effects when zoomed out a lot */
121 if (dpi->zoom > ZOOM_LVL_TEXT_EFFECT) return;
122 if (IsTransparencySet(TO_TEXT)) return;
123
124 ViewportStringFlags flags{};
125 if (dpi->zoom >= ZOOM_LVL_TEXT_EFFECT) flags.Set(ViewportStringFlag::Small);
126
127 for (const TextEffect &te : _text_effects) {
128 if (te.string_id == INVALID_STRING_ID) continue;
129
131 std::string *str = ViewportAddString(dpi, &te, flags, INVALID_COLOUR);
132 if (str == nullptr) continue;
133
135 *str = GetString(te.string_id);
136 }
137 }
138}
constexpr EnumBitSet & Set(Tenum value)
Set the enum value.
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
Types related to commands.
@ CMDPL_NO_CONSTRUCTION
No construction actions may be executed.
PauseMode _pause_mode
The current pause mode.
Definition gfx.cpp:50
void MarkDirty(ZoomLevel maxzoom=ZOOM_LVL_MAX) const
Mark the sign dirty in all viewports.
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:57
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:56
Types related to global configuration settings.
Definition of base types and functions in a cross-platform compatible way.
std::string GetString(StringID string)
Resolve the given StringID into a std::string with all the associated DParam lookups and formatting.
Definition strings.cpp:332
void CopyOutDParam(std::vector< StringParameterData > &backup, size_t num)
Copy num string parameters from the global string parameter array to the backup.
Definition strings.cpp:171
void CopyInDParam(const std::span< const StringParameterData > backup)
Copy the parameters from the backup into the global string parameter array.
Definition strings.cpp:159
bool HaveDParamChanged(const std::span< const StringParameterData > backup)
Checks whether the global string parameters have changed compared to the given backup.
Definition strings.cpp:184
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
GUISettings gui
settings related to the GUI
uint8_t command_pause_level
level/amount of commands that can't be executed while paused
Data about how and where to blit pixels.
Definition gfx_type.h:156
uint8_t loading_indicators
show loading indicators
ConstructionSettings construction
construction of things in-game
Container for all information about a text effect.
Definition texteff.cpp:23
TextEffectMode mode
Type of text effect.
Definition texteff.cpp:27
uint8_t duration
How long the text effect should stay, in ticks (applies only when mode == TE_RISING)
Definition texteff.cpp:26
StringID string_id
String to draw for the text effect, if INVALID_STRING_ID then it's not valid.
Definition texteff.cpp:25
std::vector< StringParameterData > params
Backup of string parameters.
Definition texteff.cpp:24
void Reset()
Reset the text effect.
Definition texteff.cpp:30
Location information about a sign as seen on the viewport.
int32_t center
The center position of the sign.
uint16_t width_normal
The width when not zoomed out (normal font)
void UpdatePosition(int center, int top, StringID str, StringID str_small=STR_NULL)
Update the position of the viewport sign.
int32_t top
The top of the sign.
static std::vector< struct TextEffect > _text_effects
Text effects are stored there.
Definition texteff.cpp:38
IntervalTimer< TimerWindow > move_all_text_effects_interval
Slowly move text effects upwards.
Definition texteff.cpp:93
Functions related to text effects.
TextEffectMode
Text effect modes.
Definition texteff.hpp:20
@ TE_RISING
Make the text effect slowly go upwards.
Definition texteff.hpp:21
Definition of Interval and OneShot timers.
Definition of the Window system.
Functions related to transparency.
bool IsTransparencySet(TransparencyOption to)
Check if the transparency option bit is set and if we aren't in the game menu (there's never transpar...
@ TO_TEXT
loading and cost/income text
std::string * ViewportAddString(const DrawPixelInfo *dpi, const ViewportSign *sign, ViewportStringFlags flags, Colours colour)
Add a string to draw in the current viewport.
Functions related to (drawing on) viewports.
@ Small
Draw using the small font.
@ ZOOM_LVL_TEXT_EFFECT
All zoom levels above this will not show text effects.
Definition zoom_type.h:39