12 #include "console_internal.h" |
12 #include "console_internal.h" |
13 #include "window_func.h" |
13 #include "window_func.h" |
14 #include "string_func.h" |
14 #include "string_func.h" |
15 #include "gfx_func.h" |
15 #include "gfx_func.h" |
16 #include "core/math_func.hpp" |
16 #include "core/math_func.hpp" |
|
17 #include "settings_type.h" |
17 #include "rev.h" |
18 #include "rev.h" |
18 |
19 |
19 #include "table/strings.h" |
20 #include "table/strings.h" |
20 |
21 |
21 #define ICON_BUFFER 79 |
22 enum { |
22 #define ICON_HISTORY_SIZE 20 |
23 ICON_HISTORY_SIZE = 20, |
23 #define ICON_LINE_HEIGHT 12 |
24 ICON_LINE_HEIGHT = 12, |
24 #define ICON_RIGHT_BORDERWIDTH 10 |
25 ICON_RIGHT_BORDERWIDTH = 10, |
25 #define ICON_BOTTOM_BORDERWIDTH 12 |
26 ICON_BOTTOM_BORDERWIDTH = 12, |
26 #define ICON_MAX_ALIAS_LINES 40 |
27 }; |
27 #define ICON_TOKEN_COUNT 20 |
28 |
28 |
29 /** |
29 /* console modes */ |
30 * Container for a single line of console output |
30 IConsoleModes _iconsole_mode; |
31 */ |
31 |
32 struct IConsoleLine { |
32 /* ** main console ** */ |
33 static IConsoleLine *front; ///< The front of the console backlog buffer |
33 static char *_iconsole_buffer[ICON_BUFFER + 1]; |
34 static int size; ///< The amount of items in the backlog |
34 static uint16 _iconsole_cbuffer[ICON_BUFFER + 1]; |
35 |
|
36 IConsoleLine *previous; ///< The previous console message. |
|
37 char *buffer; ///< The data to store. |
|
38 uint16 colour; ///< The colour of the line. |
|
39 uint16 time; ///< The amount of time the line is in the backlog. |
|
40 |
|
41 /** |
|
42 * Initialize the console line. |
|
43 * @param buffer the data to print. |
|
44 * @param colour the colour of the line. |
|
45 */ |
|
46 IConsoleLine(char *buffer, uint16 colour) : |
|
47 previous(IConsoleLine::front), |
|
48 buffer(buffer), |
|
49 colour(colour), |
|
50 time(0) |
|
51 { |
|
52 IConsoleLine::front = this; |
|
53 IConsoleLine::size++; |
|
54 } |
|
55 |
|
56 /** |
|
57 * Clear this console line and any further ones. |
|
58 */ |
|
59 ~IConsoleLine() |
|
60 { |
|
61 IConsoleLine::size--; |
|
62 free(buffer); |
|
63 |
|
64 delete previous; |
|
65 } |
|
66 |
|
67 /** |
|
68 * Get the index-ed item in the list. |
|
69 */ |
|
70 static const IConsoleLine *Get(uint index) |
|
71 { |
|
72 const IConsoleLine *item = IConsoleLine::front; |
|
73 while (index != 0 && item != NULL) { |
|
74 index--; |
|
75 item = item->previous; |
|
76 } |
|
77 |
|
78 return item; |
|
79 } |
|
80 |
|
81 /** |
|
82 * Truncate the list removing everything older than/more than the amount |
|
83 * as specified in the config file. |
|
84 * As a side effect also increase the time the other lines have been in |
|
85 * the list. |
|
86 * @return true if and only if items got removed. |
|
87 */ |
|
88 static bool Truncate() |
|
89 { |
|
90 IConsoleLine *cur = IConsoleLine::front; |
|
91 if (cur == NULL) return false; |
|
92 |
|
93 int count = 1; |
|
94 for (IConsoleLine *item = cur->previous; item != NULL; count++, cur = item, item = item->previous) { |
|
95 if (item->time > _settings_client.gui.console_backlog_timeout && |
|
96 count > _settings_client.gui.console_backlog_length) { |
|
97 delete item; |
|
98 cur->previous = NULL; |
|
99 return true; |
|
100 } |
|
101 |
|
102 if (item->time != MAX_UVALUE(typeof(item->time))) item->time++; |
|
103 } |
|
104 |
|
105 return false; |
|
106 } |
|
107 |
|
108 /** |
|
109 * Reset the complete console line backlog. |
|
110 */ |
|
111 static void Reset() |
|
112 { |
|
113 delete IConsoleLine::front; |
|
114 IConsoleLine::front = NULL; |
|
115 IConsoleLine::size = 0; |
|
116 } |
|
117 }; |
|
118 |
|
119 /* static */ IConsoleLine *IConsoleLine::front = NULL; |
|
120 /* static */ int IConsoleLine::size = 0; |
|
121 |
|
122 |
|
123 /* ** main console cmd buffer ** */ |
35 static Textbuf _iconsole_cmdline; |
124 static Textbuf _iconsole_cmdline; |
36 |
|
37 /* ** main console cmd buffer ** */ |
|
38 static char *_iconsole_history[ICON_HISTORY_SIZE]; |
125 static char *_iconsole_history[ICON_HISTORY_SIZE]; |
39 static byte _iconsole_historypos; |
126 static byte _iconsole_historypos; |
|
127 IConsoleModes _iconsole_mode; |
40 |
128 |
41 /* *************** * |
129 /* *************** * |
42 * end of header * |
130 * end of header * |
43 * *************** */ |
131 * *************** */ |
44 |
132 |
77 ClrBit(_no_scroll, SCROLL_CON); |
165 ClrBit(_no_scroll, SCROLL_CON); |
78 } |
166 } |
79 |
167 |
80 virtual void OnPaint() |
168 virtual void OnPaint() |
81 { |
169 { |
82 int i = IConsoleWindow::scroll; |
|
83 int max = (this->height / ICON_LINE_HEIGHT) - 1; |
170 int max = (this->height / ICON_LINE_HEIGHT) - 1; |
84 int delta = 0; |
171 const IConsoleLine *print = IConsoleLine::Get(IConsoleWindow::scroll); |
85 GfxFillRect(this->left, this->top, this->width, this->height - 1, 0); |
172 GfxFillRect(this->left, this->top, this->width, this->height - 1, 0); |
86 while ((i > 0) && (i > IConsoleWindow::scroll - max) && (_iconsole_buffer[i] != NULL)) { |
173 for (int i = 0; i < max && print != NULL; i++, print = print->previous) { |
87 DoDrawString(_iconsole_buffer[i], 5, |
174 DoDrawString(print->buffer, 5, |
88 this->height - (IConsoleWindow::scroll + 2 - i) * ICON_LINE_HEIGHT, _iconsole_cbuffer[i]); |
175 this->height - (2 + i) * ICON_LINE_HEIGHT, print->colour); |
89 i--; |
|
90 } |
176 } |
91 /* If the text is longer than the window, don't show the starting ']' */ |
177 /* If the text is longer than the window, don't show the starting ']' */ |
92 delta = this->width - 10 - _iconsole_cmdline.width - ICON_RIGHT_BORDERWIDTH; |
178 int delta = this->width - 10 - _iconsole_cmdline.width - ICON_RIGHT_BORDERWIDTH; |
93 if (delta > 0) { |
179 if (delta > 0) { |
94 DoDrawString("]", 5, this->height - ICON_LINE_HEIGHT, CC_COMMAND); |
180 DoDrawString("]", 5, this->height - ICON_LINE_HEIGHT, CC_COMMAND); |
95 delta = 0; |
181 delta = 0; |
96 } |
182 } |
97 |
183 |
100 if (_iconsole_cmdline.caret) { |
186 if (_iconsole_cmdline.caret) { |
101 DoDrawString("_", 10 + delta + _iconsole_cmdline.caretxoffs, this->height - ICON_LINE_HEIGHT, TC_WHITE); |
187 DoDrawString("_", 10 + delta + _iconsole_cmdline.caretxoffs, this->height - ICON_LINE_HEIGHT, TC_WHITE); |
102 } |
188 } |
103 } |
189 } |
104 |
190 |
|
191 virtual void OnHundredthTick() |
|
192 { |
|
193 if (IConsoleLine::Truncate() && |
|
194 (IConsoleWindow::scroll > IConsoleLine::size)) { |
|
195 IConsoleWindow::scroll = max(0, IConsoleLine::size - (this->height / ICON_LINE_HEIGHT) + 1); |
|
196 this->SetDirty(); |
|
197 } |
|
198 } |
|
199 |
105 virtual void OnMouseLoop() |
200 virtual void OnMouseLoop() |
106 { |
201 { |
107 if (HandleCaret(&_iconsole_cmdline)) this->SetDirty(); |
202 if (HandleCaret(&_iconsole_cmdline)) this->SetDirty(); |
108 } |
203 } |
109 |
204 |
110 virtual EventState OnKeyPress(uint16 key, uint16 keycode) |
205 virtual EventState OnKeyPress(uint16 key, uint16 keycode) |
111 { |
206 { |
|
207 const int scroll_height = (this->height / ICON_LINE_HEIGHT) - 1; |
112 switch (keycode) { |
208 switch (keycode) { |
113 case WKC_UP: |
209 case WKC_UP: |
114 IConsoleHistoryNavigate(+1); |
210 IConsoleHistoryNavigate(+1); |
115 this->SetDirty(); |
211 this->SetDirty(); |
116 break; |
212 break; |
118 case WKC_DOWN: |
214 case WKC_DOWN: |
119 IConsoleHistoryNavigate(-1); |
215 IConsoleHistoryNavigate(-1); |
120 this->SetDirty(); |
216 this->SetDirty(); |
121 break; |
217 break; |
122 |
218 |
123 case WKC_SHIFT | WKC_PAGEUP: |
219 case WKC_SHIFT | WKC_PAGEDOWN: |
124 if (IConsoleWindow::scroll - (this->height / ICON_LINE_HEIGHT) - 1 < 0) { |
220 if (IConsoleWindow::scroll - scroll_height < 0) { |
125 IConsoleWindow::scroll = 0; |
221 IConsoleWindow::scroll = 0; |
126 } else { |
222 } else { |
127 IConsoleWindow::scroll -= (this->height / ICON_LINE_HEIGHT) - 1; |
223 IConsoleWindow::scroll -= scroll_height; |
128 } |
224 } |
129 this->SetDirty(); |
225 this->SetDirty(); |
130 break; |
226 break; |
131 |
227 |
132 case WKC_SHIFT | WKC_PAGEDOWN: |
228 case WKC_SHIFT | WKC_PAGEUP: |
133 if (IConsoleWindow::scroll + (this->height / ICON_LINE_HEIGHT) - 1 > ICON_BUFFER) { |
229 if (IConsoleWindow::scroll + scroll_height > IConsoleLine::size - scroll_height) { |
134 IConsoleWindow::scroll = ICON_BUFFER; |
230 IConsoleWindow::scroll = IConsoleLine::size - scroll_height; |
135 } else { |
231 } else { |
136 IConsoleWindow::scroll += (this->height / ICON_LINE_HEIGHT) - 1; |
232 IConsoleWindow::scroll += scroll_height; |
137 } |
233 } |
138 this->SetDirty(); |
234 this->SetDirty(); |
139 break; |
235 break; |
140 |
236 |
141 case WKC_SHIFT | WKC_UP: |
237 case WKC_SHIFT | WKC_DOWN: |
142 if (IConsoleWindow::scroll <= 0) { |
238 if (IConsoleWindow::scroll <= 0) { |
143 IConsoleWindow::scroll = 0; |
239 IConsoleWindow::scroll = 0; |
144 } else { |
240 } else { |
145 --IConsoleWindow::scroll; |
241 --IConsoleWindow::scroll; |
146 } |
242 } |
147 this->SetDirty(); |
243 this->SetDirty(); |
148 break; |
244 break; |
149 |
245 |
150 case WKC_SHIFT | WKC_DOWN: |
246 case WKC_SHIFT | WKC_UP: |
151 if (IConsoleWindow::scroll >= ICON_BUFFER) { |
247 if (IConsoleWindow::scroll >= IConsoleLine::size) { |
152 IConsoleWindow::scroll = ICON_BUFFER; |
248 IConsoleWindow::scroll = IConsoleLine::size; |
153 } else { |
249 } else { |
154 ++IConsoleWindow::scroll; |
250 ++IConsoleWindow::scroll; |
155 } |
251 } |
156 this->SetDirty(); |
252 this->SetDirty(); |
157 break; |
253 break; |
234 void IConsoleGUIInit() |
330 void IConsoleGUIInit() |
235 { |
331 { |
236 _iconsole_historypos = ICON_HISTORY_SIZE - 1; |
332 _iconsole_historypos = ICON_HISTORY_SIZE - 1; |
237 _iconsole_mode = ICONSOLE_CLOSED; |
333 _iconsole_mode = ICONSOLE_CLOSED; |
238 |
334 |
|
335 IConsoleLine::Reset(); |
239 memset(_iconsole_history, 0, sizeof(_iconsole_history)); |
336 memset(_iconsole_history, 0, sizeof(_iconsole_history)); |
240 memset(_iconsole_buffer, 0, sizeof(_iconsole_buffer)); |
337 |
241 memset(_iconsole_cbuffer, 0, sizeof(_iconsole_cbuffer)); |
|
242 _iconsole_cmdline.buf = CallocT<char>(ICON_CMDLN_SIZE); // create buffer and zero it |
338 _iconsole_cmdline.buf = CallocT<char>(ICON_CMDLN_SIZE); // create buffer and zero it |
243 _iconsole_cmdline.maxlength = ICON_CMDLN_SIZE; |
339 _iconsole_cmdline.maxlength = ICON_CMDLN_SIZE; |
244 |
340 |
245 IConsolePrintF(CC_WARNING, "OpenTTD Game Console Revision 7 - %s", _openttd_revision); |
341 IConsolePrintF(CC_WARNING, "OpenTTD Game Console Revision 7 - %s", _openttd_revision); |
246 IConsolePrint(CC_WHITE, "------------------------------------"); |
342 IConsolePrint(CC_WHITE, "------------------------------------"); |
351 * @param color_code the colour of the command. Red in case of errors, etc. |
443 * @param color_code the colour of the command. Red in case of errors, etc. |
352 * @param string the message entered or output on the console (notice, error, etc.) |
444 * @param string the message entered or output on the console (notice, error, etc.) |
353 */ |
445 */ |
354 void IConsoleGUIPrint(ConsoleColour color_code, char *str) |
446 void IConsoleGUIPrint(ConsoleColour color_code, char *str) |
355 { |
447 { |
356 /* move up all the strings in the buffer one place and do the same for colour |
448 new IConsoleLine(str, color_code); |
357 * to accomodate for the new command/message */ |
|
358 free(_iconsole_buffer[0]); |
|
359 memmove(&_iconsole_buffer[0], &_iconsole_buffer[1], sizeof(_iconsole_buffer[0]) * ICON_BUFFER); |
|
360 _iconsole_buffer[ICON_BUFFER] = str; |
|
361 |
|
362 memmove(&_iconsole_cbuffer[0], &_iconsole_cbuffer[1], sizeof(_iconsole_cbuffer[0]) * ICON_BUFFER); |
|
363 _iconsole_cbuffer[ICON_BUFFER] = color_code; |
|
364 |
|
365 SetWindowDirty(FindWindowById(WC_CONSOLE, 0)); |
449 SetWindowDirty(FindWindowById(WC_CONSOLE, 0)); |
366 } |
450 } |