1 /*
2 * chat.c - this file will do everything what have to do with the chat..
3 */
4
5 #include "bomberclone.h"
6 #include "network.h"
7 #include "packets.h"
8 #include "gfx.h"
9 #include "keybinput.h"
10 #include "chat.h"
11
12 _chat chat;
13
14 static void chat_drawlines ();
15 static void chat_drawinput ();
16
17 /* find a free line or delete the oldest one */
18 int
chat_findfreeline()19 chat_findfreeline ()
20 {
21 int i;
22 i = chat.curline;
23
24 if (i >= CHAT_MAX_LINES-1) {
25 memcpy (&chat.lines[0], &chat.lines[1], sizeof (chat.lines[1]) * (CHAT_MAX_LINES - 1));
26 i = CHAT_MAX_LINES - 2;
27 }
28 else
29 chat.curline++;
30
31 chat.changed = 1;
32
33 return i;
34 }
35
36
37 /*
38 * add a new line to the chat, if a line is bigger as the X Space,
39 * split the line in more
40 */
41 void
chat_addline(char * text,int color)42 chat_addline (char *text, int color)
43 {
44 char *pos = text;
45 int l, i;
46 int maxlen = chat.window.w/font[0].size.x;
47 if (maxlen > KEYBI_LINE_LEN-1 || maxlen <= 0) maxlen = KEYBI_LINE_LEN;
48
49 while (pos != NULL) {
50 l = chat_findfreeline ();
51 if (color == -1)
52 chat.lines[l].color = CHAT_TEXTCOLOR;
53 else
54 chat.lines[l].color = color;
55 chat.lines[l].end = 1;
56 strncpy (chat.lines[l].text, pos, maxlen);
57 if ((i = strlen (pos)) > maxlen) {
58 pos = pos + maxlen;
59 chat.lines[l].end = 0;
60 chat.lines[l].text[maxlen] = 0;
61 }
62 else pos = NULL;
63 }
64
65 chat.changed = 1;
66 }
67
68
69 /*
70 * draw the empty chat box
71 */
72 void
chat_drawbox()73 chat_drawbox ()
74 {
75 SDL_Rect src;
76 int i;
77
78 if (gfx_locksurface (gfx.screen))
79 return;
80
81 src = chat.window;
82 SDL_BlitSurface (chat.oldscreen, NULL, gfx.screen, &src);
83
84 for (i = 0; i < 2; i++) {
85 src.x = chat.window.x + i;
86 src.w = src.x + chat.window.w - 2;
87 src.y = chat.window.y + i;
88 src.h = src.y + chat.window.h - 2;
89 if (chat.active) draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_BRIGHT);
90 else draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_DARK >> 2);
91 }
92
93 src = chat.window;
94 src.x += 2;
95 src.y += 2;
96 src.h -= 4;
97 src.w -= 4;
98 SDL_BlitSurface (chat.oldscreen, NULL, gfx.screen, &src);
99
100 src.x = chat.window.x + 2;
101 src.y = chat.window.y + 2;
102 src.w = src.x + chat.window.w - 4;
103 src.h = src.y + chat.window.h - 4;
104 draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_DARK);
105
106 gfx_unlocksurface (gfx.screen);
107 };
108
109
110
111 /*
112 * Draw the chatscreen
113 */
114 void
chat_draw()115 chat_draw ()
116 {
117 if (chat.oldscreen != NULL) {
118 chat_drawbox ();
119 chat_drawlines ();
120 chat_drawinput ();
121 }
122
123 chat.changed = 0;
124 chat.input.changed = 0;
125 };
126
127
128 /*
129 * Draw all the textlines
130 */
131 void
chat_drawlines()132 chat_drawlines ()
133 {
134 int vislines = (chat.window.h - 20) / font[0].size.y; // number of visible lines
135 int i = chat.curline - vislines;
136 int nr;
137
138 if (i < 0) i = 0;
139
140 for (nr = 0; i <= chat.curline; i++, nr++)
141 font_gfxdraw (chat.window.x + 4, chat.window.y + 4 + font[0].size.y * nr, chat.lines[i].text, 0, chat.lines[i].color, 0x1000);
142 };
143
144
145 /*
146 * draw the input field
147 */
148 void
chat_drawinput()149 chat_drawinput ()
150 {
151 SDL_Rect src, dest;
152 int maxlen = chat.window.x / font[0].size.x;
153 int start;
154 if (maxlen > KEYBI_LINE_LEN-1 || maxlen <= 0) maxlen = KEYBI_LINE_LEN;
155
156 dest.x = chat.window.x + 2;
157 dest.y = chat.window.y + chat.window.h - (font[0].size.y + 2);
158 dest.w = chat.window.w - 4;
159 dest.h = font[0].size.y;
160
161 src.x = 2;
162 src.y = chat.window.h - (font[0].size.y + 2);
163 src.w = chat.window.w - 4;
164 src.h = font[0].size.y;
165 SDL_BlitSurface (chat.oldscreen, &src, gfx.screen, &dest);
166
167 src.x = chat.window.x + 2;
168 src.y = chat.window.y + chat.window.h - (font[0].size.y + 2);
169 src.w = chat.window.x + chat.window.w - 4;
170 src.h = chat.window.y + chat.window.h - 4;
171
172 if (chat.active)
173 draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_BRIGHT);
174 else
175 draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_DARK);
176 gfx_blitupdaterectadd (&chat.window);
177
178 start = strlen (chat.input.text) - maxlen;
179 if (start < 0) start = 0;
180
181 font_gfxdraw (chat.window.x + 2, (chat.window.y + chat.window.h) - (2 + font[0].size.y), chat.input.text, 0, COLOR_black, 0x1000);
182
183 chat.input.changed = 0;
184 }
185
186 /*
187 * set a new position for the chat window,
188 * or delete the chat windows if it's out of range
189 */
190 void
chat_show(int x,int y,int w,int h)191 chat_show (int x, int y, int w, int h)
192 {
193 /* restore the old screen */
194 if (chat.oldscreen != NULL) {
195 gfx_blitupdaterectadd (&chat.window);
196 SDL_BlitSurface (chat.oldscreen, NULL, gfx.screen, &chat.window);
197 SDL_FreeSurface (chat.oldscreen);
198 chat.oldscreen = NULL;
199 }
200
201 /* 1) save the old screen
202 * 2) draw chatbox
203 */
204 if (x >= 0 && x < gfx.res.x && y >= 0 && y < gfx.res.y && w > 0 && h > 0) {
205 chat.window.x = x;
206 chat.window.y = y;
207 chat.window.w = w;
208 chat.window.h = h;
209
210 chat.oldscreen = gfx_copyscreen (&chat.window);
211
212 chat_draw ();
213
214 gfx_blitupdaterectadd (&chat.window);
215 }
216 };
217
218
219
220 /*
221 * loop through the chat and draw it
222 */
223 void
chat_loop(SDL_Event * event)224 chat_loop (SDL_Event * event)
225 {
226 int i;
227 char text[255];
228
229 if (chat.active) { /* the chat mode is active */
230 if (event != NULL)
231 i = keybinput_loop (&chat.input, event);
232 else {
233 i = 0;
234 chat.input.changed = 1;
235 }
236
237 if (i == 1 && chat.input.text[0] != 0) {
238 sprintf (text, "%s: %s", bman.playername, chat.input.text);
239 net_send_chat (text, 1);
240 chat_addline (text, CHAT_TEXTCOLOR);
241 keybinput_new (&chat.input, KEYBI_text, 255);
242 i = 0;
243 if (!chat.keepactive)
244 chat.active = 0;
245 chat.changed = 1;
246 }
247 }
248 else
249 i = 0;
250
251 /*
252 * check if we have to redraw the input line
253 */
254 if (chat.changed)
255 chat_draw ();
256
257 if (chat.input.changed)
258 chat_drawinput ();
259 };
260
261
262 /*
263 * activeate the chat and set up that the chat keeps
264 * active after we have pressed the Return Key
265 */
266 void
chat_setactive(int active,int keepactive)267 chat_setactive (int active, int keepactive)
268 {
269 chat.active = active;
270 chat.changed = 1;
271 chat_draw ();
272 chat.keepactive = keepactive;
273 };
274