summaryrefslogtreecommitdiff
path: root/texteff.c
diff options
context:
space:
mode:
authortruelight <truelight@openttd.org>2004-12-04 17:54:56 +0000
committertruelight <truelight@openttd.org>2004-12-04 17:54:56 +0000
commitd6a1f3e412834c52b09e297cffc36d0776cb7a92 (patch)
tree68d3e795694a875138c369707ed74b5b4b022d49 /texteff.c
parentc90bba35a23204c47151cf0ab97b16d8a124dabe (diff)
downloadopenttd-d6a1f3e412834c52b09e297cffc36d0776cb7a92.tar.xz
(svn r942) -Merged branch/network back into the trunk
Diffstat (limited to 'texteff.c')
-rw-r--r--texteff.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/texteff.c b/texteff.c
index 60b221cf2..bccab3c9f 100644
--- a/texteff.c
+++ b/texteff.c
@@ -3,6 +3,9 @@
#include "gfx.h"
#include "viewport.h"
#include "saveload.h"
+#include "hal.h"
+#include "console.h"
+#include <stdarg.h> /* va_list */
typedef struct TextEffect {
StringID string_id;
@@ -12,9 +15,187 @@ typedef struct TextEffect {
uint32 params_2;
} TextEffect;
+#define MAX_TEXTMESSAGE_LENGTH 250
+
+typedef struct TextMessage {
+ char message[MAX_TEXTMESSAGE_LENGTH];
+ uint16 color;
+ uint16 end_date;
+} TextMessage;
+
+#define MAX_CHAT_MESSAGES 10
static TextEffect _text_effect_list[30];
+static TextMessage _text_message_list[MAX_CHAT_MESSAGES];
TileIndex _animated_tile_list[256];
+
+int _textmessage_width = 0;
+bool _textmessage_dirty = true;
+bool _textmessage_visible = false;
+
+const int _textmessage_box_left = 10; // Pixels from left
+const int _textmessage_box_y = 150; // Height of box
+const int _textmessage_box_bottom = 20; // Pixels from bottom
+const int _textmessage_box_max_width = 400; // Max width of box
+
+static byte _textmessage_backup[150*400]; // (y * max_width)
+
+extern void memcpy_pitch(void *d, void *s, int w, int h, int spitch, int dpitch);
+
+// Duration is in game-days
+void AddTextMessage(uint16 color, uint8 duration, const char *message, ...)
+{
+ int i;
+ char buf[1024];
+ char buf2[MAX_TEXTMESSAGE_LENGTH];
+ va_list va;
+ int length;
+
+ va_start(va, message);
+ vsprintf(buf, message, va);
+ va_end(va);
+
+ if ((color & 0xFF) == 0xC9) color = 0x1CA;
+
+ length = MAX_TEXTMESSAGE_LENGTH;
+ snprintf(buf2, length, "%s", buf);
+ while (GetStringWidth(buf2) > _textmessage_width - 9) {
+ snprintf(buf2, --length, "%s", buf);
+ }
+
+ for (i = 0; i < MAX_CHAT_MESSAGES; i++) {
+ if (_text_message_list[i].message[0] == '\0') {
+ // Empty spot
+ snprintf(_text_message_list[i].message, MAX_TEXTMESSAGE_LENGTH, "%s", buf2);
+ _text_message_list[i].color = color;
+ _text_message_list[i].end_date = _date + duration;
+
+ _textmessage_dirty = true;
+ return;
+ }
+ }
+
+ // We did not found a free spot, trash the first one, and add to the end
+ memmove(&_text_message_list[0], &_text_message_list[1], sizeof(TextMessage) * (MAX_CHAT_MESSAGES - 1));
+ snprintf(_text_message_list[MAX_CHAT_MESSAGES - 1].message, MAX_TEXTMESSAGE_LENGTH, "%s", buf2);
+ _text_message_list[MAX_CHAT_MESSAGES - 1].color = color;
+ _text_message_list[i].end_date = _date + duration;
+
+ _textmessage_dirty = true;
+}
+
+void InitTextMessage()
+{
+ int i;
+ for (i = 0; i < MAX_CHAT_MESSAGES; i++) {
+ _text_message_list[i].message[0] = '\0';
+ }
+
+ _textmessage_width = _textmessage_box_max_width;
+}
+
+// Hide the textbox
+void UndrawTextMessage()
+{
+ if (_textmessage_visible) {
+ // Sometimes we also need to hide the cursor
+ // This is because both textmessage and the cursor take a shot of the
+ // screen before drawing.
+ // Now the textmessage takes his shot and paints his data before the cursor
+ // does, so in the shot of the cursor is the screen-data of the textmessage
+ // included when the cursor hangs somewhere over the textmessage. To
+ // avoid wrong repaints, we undraw the cursor in that case, and everything
+ // looks nicely ;)
+ // (and now hope this story above makes sense to you ;))
+
+ if (_cursor.visible) {
+ if (_cursor.draw_pos.x + _cursor.draw_size.x >= _textmessage_box_left &&
+ _cursor.draw_pos.x <= _textmessage_box_left + _textmessage_width &&
+ _cursor.draw_pos.y + _cursor.draw_size.y >= _screen.height - _textmessage_box_bottom - _textmessage_box_y &&
+ _cursor.draw_pos.y <= _screen.height - _textmessage_box_bottom) {
+ UndrawMouseCursor();
+ }
+ }
+
+ _textmessage_visible = false;
+ // Put our 'shot' back to the screen
+ memcpy_pitch(
+ _screen.dst_ptr + _textmessage_box_left + (_screen.height-_textmessage_box_bottom-_textmessage_box_y) * _screen.pitch,
+ _textmessage_backup,
+ _textmessage_width, _textmessage_box_y, _textmessage_width, _screen.pitch);
+
+ // And make sure it is updated next time
+ _video_driver->make_dirty(_textmessage_box_left, _screen.height-_textmessage_box_bottom-_textmessage_box_y, _textmessage_width, _textmessage_box_y);
+
+ _textmessage_dirty = true;
+ }
+}
+
+// Check if a message is expired every day
+void TextMessageDailyLoop()
+{
+ int i = 0;
+ while (i < MAX_CHAT_MESSAGES) {
+ if (_text_message_list[i].message[0] == '\0') break;
+ if (_date > _text_message_list[i].end_date) {
+ memmove(&_text_message_list[i], &_text_message_list[i+1], sizeof(TextMessage) * ((MAX_CHAT_MESSAGES - 1) - i));
+ _text_message_list[MAX_CHAT_MESSAGES - 1].message[0] = '\0';
+ i--;
+ _textmessage_dirty = true;
+ }
+ i++;
+ }
+}
+
+// Draw the textmessage-box
+void DrawTextMessage()
+{
+ int i, j;
+ bool has_message;
+
+ if (!_textmessage_dirty)
+ return;
+
+ // First undraw if needed
+ UndrawTextMessage();
+
+ if (_iconsole_mode == ICONSOLE_FULL)
+ return;
+
+ has_message = false;
+ for ( i = 0; i < MAX_CHAT_MESSAGES; i++) {
+ if (_text_message_list[i].message[0] == '\0') break;
+ has_message = true;
+ }
+ if (!has_message) return;
+
+ // Make a copy of the screen as it is before painting (for undraw)
+ memcpy_pitch(
+ _textmessage_backup,
+ _screen.dst_ptr + _textmessage_box_left + (_screen.height-_textmessage_box_bottom-_textmessage_box_y) * _screen.pitch,
+ _textmessage_width, _textmessage_box_y, _screen.pitch, _textmessage_width);
+
+ // Switch to _screen painting
+ _cur_dpi = &_screen;
+
+ j = 0;
+ // Paint the messages
+ for (i = MAX_CHAT_MESSAGES - 1; i >= 0; i--) {
+ if (_text_message_list[i].message[0] == '\0') continue;
+ j++;
+ GfxFillRect(_textmessage_box_left, _screen.height-_textmessage_box_bottom-j*13-2, _textmessage_box_left+_textmessage_width - 1, _screen.height-_textmessage_box_bottom-j*13+10, /* black, but with some alpha */ 0x4322);
+
+ DoDrawString(_text_message_list[i].message, _textmessage_box_left + 2, _screen.height - _textmessage_box_bottom - j * 13 - 1, 0x10);
+ DoDrawString(_text_message_list[i].message, _textmessage_box_left + 3, _screen.height - _textmessage_box_bottom - j * 13, _text_message_list[i].color);
+ }
+
+ // Make sure the data is updated next flush
+ _video_driver->make_dirty(_textmessage_box_left, _screen.height-_textmessage_box_bottom-_textmessage_box_y, _textmessage_width, _textmessage_box_y);
+
+ _textmessage_visible = true;
+ _textmessage_dirty = false;
+}
+
static void MarkTextEffectAreaDirty(TextEffect *te)
{
MarkAllViewportsDirty(