1 /*!
2  * \file
3  * \ingroup text_font
4  * \brief   Text handling
5  */
6 #ifndef __TEXT_H__
7 #define __TEXT_H__
8 
9 typedef struct text_message text_message;
10 
11 #include <stdlib.h>
12 #include <SDL_types.h>
13 #include "platform.h"
14 #include "font.h"
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 #define DISPLAY_TEXT_BUFFER_SIZE 5000 /*!< maximum number of lines in the text buffer */
21 #define DISPLAY_TEXT_BUFFER_DEL 100 /*!< number of lines to discard when buffer is full */
22 
23 #define CHAT_ALL	((Uint8) -1)
24 #define CHAT_NONE	((Uint8) -2)
25 #define CHAT_LIST	((Uint8) -3)
26 #define CHAT_HIST	((Uint8) -4)
27 
28 #define FILTER_LOCAL	CHAT_LOCAL
29 #define FILTER_PERSONAL	CHAT_PERSONAL
30 #define FILTER_GM	CHAT_GM
31 #define FILTER_SERVER	CHAT_SERVER
32 #define FILTER_MOD	CHAT_MOD
33 #define FILTER_CHANNEL1	CHAT_CHANNEL1
34 #define FILTER_CHANNEL2	CHAT_CHANNEL2
35 #define FILTER_CHANNEL3	CHAT_CHANNEL3
36 #define FILTER_ALL	CHAT_ALL
37 #define FILTER_NONE	CHAT_NONE
38 
39 #define LOG_NONE				0
40 #define LOG_CHAT				1
41 #define LOG_SERVER				2
42 #define LOG_SERVER_SEPERATE		3
43 
44 struct text_message
45 {
46 	Uint8 chan_idx;
47 	Uint32 channel;
48 	Uint16 len, size;
49 	char *data;
50 	Uint16 wrap_width;
51 	float wrap_zoom;
52 	Uint8 wrap_lines;
53 	Uint8 deleted;
54 	float max_line_width;
55 	float r, g, b;
56 };
57 
58 extern text_message display_text_buffer[DISPLAY_TEXT_BUFFER_SIZE];
59 extern int last_message;
60 extern Uint8 current_filter;
61 
62 extern text_message input_text_line; /*!< user input text */
63 
64 extern char last_pm_from[32]; /*!< actor name from whom the last pm arrived */
65 
66 extern int show_timestamp;
67 
68 extern int dark_channeltext;
69 
70 extern int log_chat; /*!< flag stating whether to log server messages or not */
71 
72 extern int emote_filter; //used to ignore text lines of emotes only
73 
74 extern int summoning_filter; //used to ignore text lines of summoning messages
75 
76 /*!
77  * \brief get the current value for seen PM and MODPM message
78  *
79  *	This count just increases until the clear function is called, the AFK
80  * 	state does not impact the count.
81  *
82  * \retval int the current count
83  * \callgraph
84  */
85 extern int get_seen_pm_count(void);
86 
87 /*!
88  * \brief set the current value for seen PM and MODPM message to zero
89  *
90  * \callgraph
91  */
92 extern void clear_seen_pm_count(void);
93 
94 /*!
95  * \brief Allocate the character buffer for a text_message
96  *
97  *	Allocates memory for the character buffer of text_message \a msg,
98  *	and initializes its size and used length.
99  *
100  * \param msg  The text_message for which to allocate a buffer
101  * \param size The desired size of the buffer
102  */
103 void alloc_text_message_data (text_message *msg, int size);
104 
105 /*!
106  * \brief Resize the character buffer of a text_message
107  *
108  *	If necessary, resize the character buffer of text_message \a msg,
109  *	so that it can hold at least a (zero-terminated) string of \a len
110  *	characters. If \a len is less than the current allocated size,
111  *	nothing is done, otherwise the array is doubled in size until
112  *	it is large enough. The existing data in the text_message's
113  *	buffer is preserved.
114  *
115  * \param msg The text_message that should be resized
116  * \param len The new minimum size of the character string
117  */
118 void resize_text_message_data (text_message *msg, int len);
119 
120 /*!
121  * \brief Clear the text string of a text_message
122  *
123  *	Set the text of text_message \a msg to an empty string.
124  *
125  * \param msg The text message to be cleared
126  */
clear_text_message_data(text_message * msg)127 static __inline__ void clear_text_message_data (text_message *msg)
128 {
129 	msg->len = 0;
130 	if (msg->size > 0)
131 		msg->data[0] = '\0';
132 }
133 
134 /*!
135  * \brief Copy a string into a text_message
136  *
137  *	Copy string \a data into the character buffer of text_message
138  *	\a msg. Note that if the current character buffer is too small
139  *	to hold all of \a data, only the first part is copied.
140  *
141  * \param msg  The text_message to be updated
142  * \param data The string to be copied
143  * \sa resize_text_message_data()
144  */
145 void set_text_message_data (text_message *msg, const char* data);
146 
147 /*!
148  * \brief Free a text_message's character buffer
149  *
150  *	Free the memory allocated for the character buffer in
151  *	text_message \a msg.
152  *
153  * \param msg The text_message whose character buffer will be freed
154  */
free_text_message_data(text_message * msg)155 static __inline__ void free_text_message_data (text_message *msg)
156 {
157 	if (msg->size > 0)
158 	{
159 		free (msg->data);
160 		msg->data = NULL;
161 		msg->len = msg->size = 0;
162 	}
163 }
164 
165 /*!
166  * \brief Set the color of a text_message
167  *
168  *	Set the color in which the text of text_message \a msg should
169  *	be drawn. Note that this color is inly used until the first
170  *	color character in the text is encountered.
171  *
172  * \param msg The text message for which to set the color
173  * \param r   The red component of the new text color
174  * \param g   The green component of the new text color
175  * \param b   The blue component of the new text color
176  */
set_text_message_color(text_message * msg,float r,float g,float b)177 static __inline__ void set_text_message_color (text_message *msg, float r, float g, float b)
178 {
179 	msg->r = r;
180 	msg->g = g;
181 	msg->b = b;
182 }
183 
184 /*!
185  * \brief Initialize a text_message
186  *
187  *	Initialize text_message \a msg by allocating a character buffer
188  *	of \a size bytes, and setting the other fields to default
189  *	values.
190  *
191  * \param msg  The text_message to be initialized
192  * \param size The initial size of the \a msg's characetr buffer
193  */
init_text_message(text_message * msg,Uint16 size)194 static __inline__ void init_text_message (text_message *msg, Uint16 size)
195 {
196 	msg->chan_idx = CHAT_NONE;
197 	msg->channel = 0;
198 	alloc_text_message_data (msg, size);
199 	msg->wrap_width = 0;
200 	msg->wrap_zoom = 1.0f;
201 	msg->wrap_lines = 0;
202 	msg->deleted = 0;
203 	msg->max_line_width = 0.0f;
204 	set_text_message_color (msg, -1.0f, -1.0f, -1.0f);
205 }
206 
207 /*!
208  * \brief Whether text message \a msg is empty
209  */
text_message_is_empty(const text_message * msg)210 static __inline__ int text_message_is_empty (const text_message *msg)
211 {
212 	return msg->len == 0;
213 }
214 
215 /*!
216  * \ingroup text_font
217  * \brief   Initializes the text buffers
218  *
219  *      Initializes the text buffers.
220  */
221 void init_text_buffers ();
222 
223 /*!
224  * \ingroup text_font
225  * \brief   Writes a timestamp to the logfile.
226  *
227  *      Writes a timestamp to the logfile.
228  *
229  */
230 void timestamp_chat_log();
231 
232 /*!
233  * \ingroup text_font
234  * \brief   Writes the given data up to a length of \a len to a logfile.
235  *
236  *      Writes the given data up to a length of \a len to a logfile.
237  *
238  * \param channel The channel index of the message
239  * \param data    The data to write to the logfile
240  * \param len     The length of data.
241  */
242 void write_to_log (Uint8 channel, const Uint8* const data, int len);
243 
244 /*!
245  * \ingroup text_font
246  * \brief   Sends the current input text to the server
247  *
248  *      Sends the current text in input_text_line to the server.
249  *
250  * \param line The text to send
251  * \param len The length of the text
252  */
253 void send_input_text_line (char *line, int len);
254 
255 /*!
256  * \ingroup text_font
257  * \brief Parse and process a text message
258  *
259  * Parse the string in \a text_to_add to check if it should be ignored, or if
260  * an action is associated with it. If it is not to be ignored, pass it to
261  * \ref filter_text to replace any substrings the user does not wish to see.
262  *
263  * \param text_to_add   the string to add
264  * \param len           the length of text_to_add
265  * \param size          the maximum number of bytes in \a text_to_add
266  * \param channel       the text channel associated with the text
267  * \retval int
268  * \callgraph
269  */
270 int filter_or_ignore_text(char *text_to_add, int len, int size, Uint8 channel);
271 
272 /*!
273  * \ingroup text_font
274  * \brief   Puts a character in a buffer
275  *
276  *      Puts the given character \a ch into text message \a buf at position \a pos
277  *
278  * \param buf	(pointer to) the message
279  * \param ch    the character to add
280  * \param pos	the position at which the character is to be placed
281  * \retval int	1 if a character is inserted, 0 otherwise
282  * \callgraph
283  */
284 int put_char_in_buffer (text_message *buf, Uint8 ch, int pos);
285 
286 /*!
287  * \ingroup text_font
288  * \brief    Inserts a string in a buffer
289  *
290  *      Inserts the given string \a str into the text buffer at position \a pos
291  *
292  * \param buf	(pointer to) the message
293  * \param str	the string to add
294  * \param pos	the position at which the string is to be placed
295  * \retval int	the number of characters inserted
296  * \callgraph
297  */
298 int put_string_in_buffer (text_message *buf, const Uint8 *str, int pos);
299 
300 /*!
301  * \ingroup text_font
302  * \brief Adds the string in text_to_add up to the specified length in the text buffer.
303  *
304  *      Adds the string in text_to_add up to the specified length to the text buffer. If x_chars_limit is !=0 then words in the filter list will get filtered and replaced.
305  *
306  * \param channel	the channel index of the message
307  * \param text_to_add   the string to add to the buffer
308  * \param len           the length of text_to_add
309  *
310  * \callgraph
311  */
312 void put_text_in_buffer (Uint8 channel, const Uint8 *text_to_add, int len);
313 
314 /*!
315  * \ingroup text_font
316  * \brief Works like \ref put_text_in_buffer, but the text will be in the specified color.
317  *
318  *      Works like \ref put_text_in_buffer, but the text will be in the specified color.
319  *
320  * \param color         the color of the text
321  * \param channel	the channel index of the message
322  * \param text_to_add   the string to add to the buffer
323  * \param len           the length of text_to_add
324  *
325  * \callgraph
326  */
327 void put_colored_text_in_buffer (Uint8 color, Uint8 channel, const Uint8 *text_to_add, int len);
328 
329 /*!
330  * \ingroup text_font
331  * \brief Find the offset of the text to show in game.
332  *
333  * In the game window, the last few lines of console text are shown, and they are
334  * scrolled out of view as time progresses. This function finds the first message,
335  * and the offset within the message, of the first line to be displayed in the
336  * game window, based on the current time and the last time a text message was
337  * added.
338  *
339  * \param msg    Place to store the message number of the first message to display
340  * \param offset Byte offset within the message of the first line to display
341  * \param filter A filter for the messages, can be used to skip unwanted messages
342  * \param width  The text width used for wrapping lines
343  *
344  * \return 0 if no line is to be shown, 1 otherwise
345  */
346 int find_last_lines_time (int *msg, int *offset, Uint8 filter, int width);
347 
348 /*!
349  * \ingroup text_font
350  * \brief Finds the position of the beginning of a line
351  *
352  * Finds the position of the beginning of a line in the text message buffer
353  *
354  * \param nr_lines The total number of lines
355  * \param line     The number of the line to be found
356  * \param filter   A filter for the messages, can be used to skip unwanted messages
357  * \param msg      The message in which the lines is located
358  * \param offset   The offset in the message at which the line starts
359  * \param font     the font category in which the line is rendered
360  * \param zoom     the text zoom that is to be used for wrapping
361  * \param width    the text width that is to be used for wrapping
362  */
363 void find_line_nr(int nr_lines, int line, Uint8 filter, int *msg, int *offset,
364 	font_cat font, float zoom, int width);
365 
366 /*!
367  * \ingroup interface_console
368  * \brief Moves the screen up one line in console mode.
369  *
370  *      Moves the screen in console mode one line up.
371  *
372  * \sa console_move_down, \sa console_move_page_down, \sa console_move_page_up
373  */
374 void console_move_up();
375 
376 /*!
377  * \ingroup interface_console
378  * \brief Moves the screen in console mode one line down
379  *
380  *      Moves the screen down one line in console mode.
381  *
382  * \sa console_move_up, \sa console_move_page_down, \sa console_move_page_up
383  */
384 void console_move_down();
385 
386 /*!
387  * \ingroup interface_console
388  * \brief moves the screen down one page in console mode
389  *
390  *      Moves the screen in console mode down one page.
391  *
392  * \sa console_move_page_up, \sa console_move_down, \sa console_move_up
393  * \callgraph
394  */
395 void console_move_page_down();
396 
397 /*!
398  * \ingroup interface_console
399  * \brief Moves the screen up one page in console mode
400  *
401  *      Moves the screen in console mode up one page.
402  *
403  * \sa console_move_page_down, \sa console_move_up, \sa console_move_down
404  * \callgraph
405  */
406 void console_move_page_up();
407 
408 /*!
409  * \ingroup text_font
410  * \brief Clears the text buffer
411  *
412  *      clears the text buffer
413  *
414  * \callgraph
415  */
416 void clear_display_text_buffer ();
417 
418 /*!
419  * \ingroup text_font
420  * \brief   Rewraps the a text buffer.
421  *
422  *      Rewraps a text buffer.
423  *
424  * \param msg    pointer to the message to rewrap
425  * \param cat    the category for the font in which the text is to be rendered
426  * \param zoom   the text zoom to use for wrapping
427  * \param width  the max width of a line
428  * \param cursor cursor passed to \ref reset_soft_breaks
429  * \return the number of lines after wrapping
430  */
431 int rewrap_message(text_message* msg, font_cat cat, float zoom, int width, int *cursor);
432 
433 void cleanup_text_buffers(void);
434 
435 
436 /*!
437  * \ingroup text_font
438  * \brief return special day status
439  *
440  * \retval       true is today is special
441  *
442  * \callgraph
443  */
444 int today_is_special_day(void);
445 
446 /*!
447  * \ingroup text_font
448  * \brief set is special day
449  *
450  * \callgraph
451  */
452 void set_today_is_special_day(void);
453 
454 /*!
455  * \ingroup text_font
456  * \brief clear is special day
457  *
458  * \callgraph
459  */
460 void clear_today_is_special_day(void);
461 
462 /* hud indicator glow perk functions */
463 int glow_perk_is_active(void);
464 int glow_perk_is_unavailable(void);
465 void check_glow_perk(void);
466 
467 #define LOG_TO_CONSOLE(color,buffer)	put_colored_text_in_buffer(color,CHAT_SERVER,(const Uint8*)buffer,-1) /*!< logs the text in buffer with the specified color to the console. */
468 
469 #ifdef __cplusplus
470 } // extern "C"
471 #endif
472 
473 #endif
474