changeset 4957:407284f992ba draft

(svn r6956) -Feature: Increase the chatbuffer of chat messages. Messages longer than the allocated graphical box will be wrapped to a new line.
author Darkvater <Darkvater@openttd.org>
date Fri, 27 Oct 2006 11:08:17 +0000
parents 73a3560243e0
children 1298c13d9fcb
files network_gui.c texteff.c
diffstat 2 files changed, 49 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/network_gui.c
+++ b/network_gui.c
@@ -49,7 +49,7 @@
 /* Global to remember sorting after window has been closed */
 static Listing _ng_sorting;
 
-static char _edit_str_buf[64];
+static char _edit_str_buf[150];
 static bool _chat_tab_completion_active;
 
 static void ShowNetworkStartServerWindow(void);
@@ -1708,7 +1708,7 @@
 	WP(w,querystr_d).wnd_class = WC_MAIN_TOOLBAR;
 	WP(w,querystr_d).wnd_num = 0;
 	WP(w,querystr_d).afilter = CS_ALPHANUMERAL;
-	InitializeTextBuffer(&WP(w, querystr_d).text, _edit_str_buf, lengthof(_edit_str_buf), w->widget[2].right - w->widget[2].left);
+	InitializeTextBuffer(&WP(w, querystr_d).text, _edit_str_buf, lengthof(_edit_str_buf), 0);
 }
 
 #endif /* ENABLE_NETWORK */
--- a/texteff.c
+++ b/texteff.c
@@ -3,6 +3,7 @@
 #include "stdafx.h"
 #include "openttd.h"
 #include "functions.h"
+#include "macros.h"
 #include "strings.h"
 #include "gfx.h"
 #include "viewport.h"
@@ -26,7 +27,7 @@
 	uint32 params_2;
 } TextEffect;
 
-#define MAX_TEXTMESSAGE_LENGTH 250
+#define MAX_TEXTMESSAGE_LENGTH 150
 
 typedef struct TextMessage {
 	char message[MAX_TEXTMESSAGE_LENGTH];
@@ -44,48 +45,61 @@
 
 /* The chatbox grows from the bottom so the coordinates are pixels from
  * the left and pixels from the bottom. The height is the maximum height */
-static const Oblong _textmsg_box = {10, 30, 400, 150};
-static Pixel _textmessage_backup[150 * 400]; // (height * width)
+static const Oblong _textmsg_box = {10, 30, 500, 150};
+static Pixel _textmessage_backup[150 * 500]; // (height * width)
 
 extern void memcpy_pitch(void *d, void *s, int w, int h, int spitch, int dpitch);
 
-// Duration is in game-days
+static inline uint GetTextMessageCount(void)
+{
+	uint i = 0;
+
+	for (i; i < MAX_CHAT_MESSAGES; i++) {
+		if (_textmsg_list[i].message[0] == '\0') break;
+	}
+
+	return i;
+}
+
+/* Add a text message to the 'chat window' to be shown
+ * @param color The colour this message is to be shown in
+ * @param duration The duration of the chat message in game-days
+ * @param message message itself in printf() style */
 void CDECL AddTextMessage(uint16 color, uint8 duration, const char *message, ...)
 {
 	char buf[MAX_TEXTMESSAGE_LENGTH];
+	const char *bufp;
 	va_list va;
-	size_t length;
-	uint i;
+	uint msg_count;
+	uint16 lines;
 
 	va_start(va, message);
 	vsnprintf(buf, lengthof(buf), message, va);
 	va_end(va);
 
-	/* Special color magic */
-	if ((color & 0xFF) == 0xC9) color = 0x1CA;
-
-	/* Cut the message till it fits inside the chatbox */
-	length = strlen(buf);
-	while (GetStringBoundingBox(buf).width > _textmsg_box.width - 9) buf[--length] = '\0';
+	/* Force linebreaks for strings that are too long */
+	lines = GB(FormatStringLinebreaks(buf, _textmsg_box.width - 8), 0, 16) + 1;
+	if (lines >= MAX_CHAT_MESSAGES) return;
 
-	/* Find an empty spot and put the message there */
-	for (i = 0; i < MAX_CHAT_MESSAGES; i++) {
-		if (_textmsg_list[i].message[0] == '\0') {
-			// Empty spot
-			ttd_strlcpy(_textmsg_list[i].message, buf, sizeof(_textmsg_list[i].message));
-			_textmsg_list[i].color = color;
-			_textmsg_list[i].end_date = _date + duration;
-
-			_textmessage_dirty = true;
-			return;
-		}
+	msg_count = GetTextMessageCount();
+	/* We want to add more chat messages than there is free space for, remove 'old' */
+	if (lines > MAX_CHAT_MESSAGES - msg_count) {
+		int i = lines - (MAX_CHAT_MESSAGES - msg_count);
+		memmove(&_textmsg_list[0], &_textmsg_list[i], sizeof(_textmsg_list[0]) * (msg_count - i));
+		msg_count = MAX_CHAT_MESSAGES - lines;
 	}
 
-	// We did not found a free spot, trash the first one, and add to the end
-	memmove(&_textmsg_list[0], &_textmsg_list[1], sizeof(_textmsg_list[0]) * (MAX_CHAT_MESSAGES - 1));
-	ttd_strlcpy(_textmsg_list[MAX_CHAT_MESSAGES - 1].message, buf, sizeof(_textmsg_list[MAX_CHAT_MESSAGES - 1].message));
-	_textmsg_list[MAX_CHAT_MESSAGES - 1].color = color;
-	_textmsg_list[MAX_CHAT_MESSAGES - 1].end_date = _date + duration;
+	for (bufp = buf; lines != 0; lines--) {
+		TextMessage *tmsg = &_textmsg_list[msg_count++];
+		ttd_strlcpy(tmsg->message, bufp, sizeof(tmsg->message));
+
+		/* The default colour for a message is player colour. Replace this with
+		 * white for any additional lines */
+		tmsg->color = (bufp == buf && color & IS_PALETTE_COLOR) ? color : (0x1D - 15) | IS_PALETTE_COLOR;
+		tmsg->end_date = _date + duration;
+
+		bufp += strlen(bufp) + 1; // jump to 'next line' in the formatted string
+	}
 
 	_textmessage_dirty = true;
 }
@@ -142,12 +156,13 @@
 	uint i;
 
 	for (i = 0; i < MAX_CHAT_MESSAGES; i++) {
-		if (_textmsg_list[i].message[0] == '\0') continue;
+		TextMessage *tmsg = &_textmsg_list[i];
+		if (tmsg->message[0] == '\0') continue;
 
-		if (_date > _textmsg_list[i].end_date) {
+		/* Message has expired, remove from the list */
+		if (tmsg->end_date < _date) {
 			/* Move the remaining messages over the current message */
-			if (i != MAX_CHAT_MESSAGES - 1)
-				memmove(&_textmsg_list[i], &_textmsg_list[i + 1], sizeof(_textmsg_list[i]) * (MAX_CHAT_MESSAGES - i - 1));
+			if (i != MAX_CHAT_MESSAGES - 1) memmove(tmsg, tmsg + 1, sizeof(*tmsg) * (MAX_CHAT_MESSAGES - i - 1));
 
 			/* Mark the last item as empty */
 			_textmsg_list[MAX_CHAT_MESSAGES - 1].message[0] = '\0';
@@ -199,7 +214,6 @@
 		j++;
 		GfxFillRect(_textmsg_box.x, _screen.height-_textmsg_box.y-j*13-2, _textmsg_box.x+_textmsg_box.width - 1, _screen.height-_textmsg_box.y-j*13+10, /* black, but with some alpha */ 0x322 | USE_COLORTABLE);
 
-		DoDrawString(_textmsg_list[i].message, _textmsg_box.x + 2, _screen.height - _textmsg_box.y - j * 13 - 1, 0x10);
 		DoDrawString(_textmsg_list[i].message, _textmsg_box.x + 3, _screen.height - _textmsg_box.y - j * 13, _textmsg_list[i].color);
 	}