Index: functions.h =================================================================== --- functions.h (revision 3342) +++ functions.h (working copy) @@ -133,12 +133,7 @@ void InitTextEffects(void); void DrawTextEffects(DrawPixelInfo *dpi); -void InitTextMessage(void); -void DrawTextMessage(void); -void CDECL AddTextMessage(uint16 color, uint8 duration, const char *message, ...); -void UndrawTextMessage(void); -void TextMessageDailyLoop(void); - +/* animated_tiles.c */ bool AddAnimatedTile(TileIndex tile); void DeleteAnimatedTile(TileIndex tile); void AnimateAnimatedTiles(void); Index: video/cocoa_v.m =================================================================== --- video/cocoa_v.m (revision 3342) +++ video/cocoa_v.m (working copy) @@ -61,6 +61,7 @@ #include "../network.h" #include "../variables.h" #include "../os/macosx/splash.h" +#include "../textmessagebox.h" #include "cocoa_v.h" @@ -741,6 +742,7 @@ QZ_CheckPaletteAnim(); pal_tick = 1; } + TextMessageBoxesFrameLoop(cur_ticks); QZ_Draw(); } else { #ifdef _DEBUG @@ -751,7 +753,7 @@ st+= GetTick() - st0; #endif _screen.dst_ptr = _cocoa_video_data.pixels; - DrawTextMessage(); + DrawTextMessageBoxes(); DrawMouseCursor(); QZ_Draw(); } Index: video/sdl_v.c =================================================================== --- video/sdl_v.c (revision 3342) +++ video/sdl_v.c (working copy) @@ -13,6 +13,7 @@ #include "../window.h" #include "../network.h" #include "../variables.h" +#include "../textmessagebox.h" #include "sdl_v.h" #include @@ -458,11 +459,12 @@ CheckPaletteAnim(); pal_tick = 1; } + TextMessageBoxesFrameLoop(cur_ticks); DrawSurfaceToScreen(); } else { SDL_CALL SDL_Delay(1); _screen.dst_ptr = _sdl_screen->pixels; - DrawTextMessage(); + DrawTextMessageBoxes(); DrawMouseCursor(); DrawSurfaceToScreen(); } Index: video/win32_v.c =================================================================== --- video/win32_v.c (revision 3342) +++ video/win32_v.c (working copy) @@ -759,6 +759,7 @@ if (_force_full_redraw) MarkWholeScreenDirty(); + TextMessageBoxesFrameLoop(cur_ticks); GdiFlush(); _screen.dst_ptr = _wnd.buffer_bits; UpdateWindows(); @@ -767,7 +768,7 @@ Sleep(1); GdiFlush(); _screen.dst_ptr = _wnd.buffer_bits; - DrawTextMessage(); + DrawTextMessageBoxes(); DrawMouseCursor(); } } Index: network.c =================================================================== --- network.c (revision 3342) +++ network.c (working copy) @@ -31,6 +31,7 @@ #include "console.h" /* IConsoleCmdExec */ #include /* va_list */ #include "md5.h" +#include "textmessagebox.h" #ifdef __MORPHOS__ // the library base is required here @@ -158,7 +159,7 @@ } IConsolePrintF(color, "%s", message); - AddTextMessage(color, duration, "%s", message); + ChatAddMessage(color, duration, "%s", message); } // Calculate the frame-lag of a client Index: openttd.c =================================================================== --- openttd.c (revision 3342) +++ openttd.c (working copy) @@ -40,6 +40,7 @@ #include "depot.h" #include "waypoint.h" #include "ai/ai.h" +#include "textmessagebox.h" #include @@ -460,6 +461,7 @@ // initialize the ingame console IConsoleInit(); + InitializeTextMessageBoxes(); InitializeGUI(); IConsoleCmdExec("exec scripts/autoexec.scr 0"); @@ -489,6 +491,7 @@ _video_driver->main_loop(); WaitTillSaved(); + UnInitializeTextMessageBoxes(); IConsoleFree(); #ifdef ENABLE_NETWORK Index: gfx.c =================================================================== --- gfx.c (revision 3342) +++ gfx.c (working copy) @@ -12,6 +12,7 @@ #include "table/sprites.h" #include "hal.h" #include "variables.h" +#include "textmessagebox.h" #ifdef _DEBUG bool _dbg_screen_rect; @@ -56,7 +57,7 @@ if (xo == 0 && yo == 0) return; if (_cursor.visible) UndrawMouseCursor(); - UndrawTextMessage(); + UndrawTextMessageBoxes(); p = _screen.pitch; @@ -1725,7 +1726,7 @@ UndrawMouseCursor(); } } - UndrawTextMessage(); + UndrawTextMessageBoxes(); #if defined(_DEBUG) if (_dbg_screen_rect) Index: texteff.c =================================================================== --- texteff.c (revision 3342) +++ texteff.c (working copy) @@ -25,196 +25,8 @@ 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]; - -static int _textmessage_width = 0; -static bool _textmessage_dirty = true; -static bool _textmessage_visible = false; - -static const int _textmessage_box_left = 10; // Pixels from left -static const int _textmessage_box_y = 150; // Height of box -static const int _textmessage_box_bottom = 30; // Pixels from bottom -static const int _textmessage_box_max_width = 400; // Max width of box - -static Pixel _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 CDECL AddTextMessage(uint16 color, uint8 duration, const char *message, ...) -{ - char buf[MAX_TEXTMESSAGE_LENGTH]; - va_list va; - size_t length; - uint i; - - 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 (GetStringWidth(buf) > _textmessage_width - 9) buf[--length] = '\0'; - - /* Find an empty spot and put the message there */ - for (i = 0; i < MAX_CHAT_MESSAGES; i++) { - if (_text_message_list[i].message[0] == '\0') { - // Empty spot - ttd_strlcpy(_text_message_list[i].message, buf, sizeof(_text_message_list[i].message)); - _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(_text_message_list[0]) * (MAX_CHAT_MESSAGES - 1)); - ttd_strlcpy(_text_message_list[MAX_CHAT_MESSAGES - 1].message, buf, sizeof(_text_message_list[MAX_CHAT_MESSAGES - 1].message)); - _text_message_list[MAX_CHAT_MESSAGES - 1].color = color; - _text_message_list[MAX_CHAT_MESSAGES - 1].end_date = _date + duration; - - _textmessage_dirty = true; -} - -void InitTextMessage(void) -{ - uint 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(void) -{ - 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(void) -{ - uint i; - - for (i = 0; i < MAX_CHAT_MESSAGES; i++) { - if (_text_message_list[i].message[0] == '\0') continue; - - if (_date > _text_message_list[i].end_date) { - /* Move the remaining messages over the current message */ - if (i != MAX_CHAT_MESSAGES - 1) - memmove(&_text_message_list[i], &_text_message_list[i + 1], sizeof(_text_message_list[i]) * (MAX_CHAT_MESSAGES - i - 1)); - - /* Mark the last item as empty */ - _text_message_list[MAX_CHAT_MESSAGES - 1].message[0] = '\0'; - _textmessage_dirty = true; - - /* Go one item back, because we moved the array 1 to the left */ - i--; - } - } -} - -// Draw the textmessage-box -void DrawTextMessage(void) -{ - int i, j; - bool has_message; - - if (!_textmessage_dirty) return; - - // First undraw if needed - UndrawTextMessage(); - - if (_iconsole_mode == ICONSOLE_FULL) - return; - - /* Check if we have anything to draw at all */ - 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 */ 0x322 | USE_COLORTABLE); - - 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( @@ -316,63 +128,3 @@ } } - -void DeleteAnimatedTile(TileIndex tile) -{ - TileIndex* ti; - - for (ti = _animated_tile_list; ti != endof(_animated_tile_list); ti++) { - if (tile == *ti) { - /* remove the hole */ - memmove(ti, ti + 1, endof(_animated_tile_list) - 1 - ti); - /* and clear last item */ - endof(_animated_tile_list)[-1] = 0; - MarkTileDirtyByTile(tile); - return; - } - } -} - -bool AddAnimatedTile(TileIndex tile) -{ - TileIndex* ti; - - for (ti = _animated_tile_list; ti != endof(_animated_tile_list); ti++) { - if (tile == *ti || *ti == 0) { - *ti = tile; - MarkTileDirtyByTile(tile); - return true; - } - } - - return false; -} - -void AnimateAnimatedTiles(void) -{ - const TileIndex* ti; - - for (ti = _animated_tile_list; ti != endof(_animated_tile_list) && *ti != 0; ti++) { - AnimateTile(*ti); - } -} - -void InitializeAnimatedTiles(void) -{ - memset(_animated_tile_list, 0, sizeof(_animated_tile_list)); -} - -static void SaveLoad_ANIT(void) -{ - // In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) - if (CheckSavegameVersion(6)) { - SlArray(_animated_tile_list, lengthof(_animated_tile_list), SLE_FILE_U16 | SLE_VAR_U32); - } else { - SlArray(_animated_tile_list, lengthof(_animated_tile_list), SLE_UINT32); - } -} - - -const ChunkHandler _animated_tile_chunk_handlers[] = { - { 'ANIT', SaveLoad_ANIT, SaveLoad_ANIT, CH_RIFF | CH_LAST}, -}; Index: misc.c =================================================================== --- misc.c (revision 3342) +++ misc.c (working copy) @@ -19,6 +19,7 @@ #include "vehicle_gui.h" #include "variables.h" #include "ai/ai.h" +#include "textmessagebox.h" extern void StartupEconomy(void); @@ -173,7 +174,6 @@ InitializeCheats(); InitTextEffects(); - InitTextMessage(); InitializeAnimatedTiles(); InitializeLandscapeVariables(false); @@ -515,7 +515,7 @@ /* yeah, increse day counter and call various daily loops */ _date++; - TextMessageDailyLoop(); + TextMessageBoxesDailyLoop(); DisasterDailyLoop(); WaypointsDailyLoop(); @@ -580,7 +580,7 @@ /* Because the _date wraps here, and text-messages expire by game-days, we have to clean out * all of them if the date is set back, else those messages will hang for ever */ - InitTextMessage(); + ChatClearMessages(); } if (_patches.auto_euro) Index: main_gui.c =================================================================== --- main_gui.c (revision 3342) +++ main_gui.c (working copy) @@ -27,6 +27,7 @@ #include "waypoint.h" #include "variables.h" #include "train.h" +#include "textmessagebox.h" #include "network_data.h" #include "network_client.h" @@ -2470,5 +2471,6 @@ _cur_resolution[1] = _screen.height; RelocateAllWindows(_screen.width, _screen.height); ScreenSizeChanged(); + TextMessageBoxesScreenSizeChanged(); MarkWholeScreenDirty(); } Index: Makefile =================================================================== --- Makefile (revision 3342) +++ Makefile (working copy) @@ -621,6 +621,7 @@ SRCS += aircraft_gui.c SRCS += airport.c SRCS += airport_gui.c +SRCS += animated_tiles.c SRCS += aystar.c SRCS += bridge_gui.c SRCS += callback_table.c @@ -705,6 +706,7 @@ SRCS += subsidy_gui.c SRCS += terraform_gui.c SRCS += texteff.c +SRCS += textmessagebox.c SRCS += thread.c SRCS += tile.c SRCS += town_cmd.c Index: console_cmds.c =================================================================== --- console_cmds.c (revision 3342) +++ console_cmds.c (working copy) @@ -17,6 +17,7 @@ #include "settings.h" #include "hal.h" /* for file list */ #include "vehicle.h" +#include "textmessagebox.h" // ** scriptfile handling ** // static FILE *_script_file; @@ -143,6 +144,25 @@ return false; } + +DEF_CONSOLE_CMD(ConDisplayInfo) +{ + if (argc == 0) { + IConsoleHelp("Shor or hide info box. Usage: 'display_info <1 | 0>'"); + return true; + } + + if (argc == 2) { + uint32 result; + if (GetArgumentInteger(&result, argv[1])) { + EnableTextMessageBox(TMB_INFO, (result == 1) ? true : false); + return true; + } + } + + return false; +} + #endif /* _DEBUG */ DEF_CONSOLE_CMD(ConScrollToTile) @@ -1254,6 +1274,7 @@ IConsoleVarRegister("con_developer", &_stdlib_con_developer, ICONSOLE_VAR_BOOLEAN, "Enable/disable console debugging information (internal)"); IConsoleCmdRegister("resettile", ConResetTile); + IConsoleCmdRegister("display_info", ConDisplayInfo); IConsoleAliasRegister("dbg_echo", "echo %A; echo %B"); IConsoleAliasRegister("dbg_echo2", "echo %!"); } Index: window.c =================================================================== --- window.c (revision 3342) +++ window.c (working copy) @@ -12,6 +12,7 @@ #include "console.h" #include "variables.h" #include "table/sprites.h" +#include "textmessagebox.h" // delta between mouse cursor and upper left corner of dragged window static Point _drag_delta; @@ -1534,7 +1535,7 @@ for (w = _windows; w != _last_window; w++) { if (w->viewport != NULL) UpdateViewportPosition(w); } - DrawTextMessage(); + DrawTextMessageBoxes(); // Redraw mouse cursor in case it was hidden DrawMouseCursor(); }