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