]> git.pond.sub.org Git - empserver/blob - src/lib/subs/pr.c
Indented with src/scripts/indent-emp.
[empserver] / src / lib / subs / pr.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23  *  related information and legal notices. It is expected that any future
24  *  projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  pr.c: Use to do output to a player
29  * 
30  *  Known contributors to this file:
31  *     Dave Pare, 1986, 1989 
32  *     Steve McClure, 1998-2000
33  */
34 /*
35  * The pr routine historically arranged for nonbuffered i/o
36  * because stdio didn't used to automatically flush stdout before
37  * it read something from stdin.  Now pr() prepends an "output id"
38  * in front of each line of text, informing the user interface
39  * what sort of item it is seeing; prompt, noecho prompt,
40  * more input data, etc.
41  */
42
43 #ifdef Rel4
44 #include <string.h>
45 #endif /* Rel4 */
46 #include <fcntl.h>
47 #include <ctype.h>
48 #include <stdarg.h>
49 #include "proto.h"
50 #include "misc.h"
51 #include "player.h"
52 #include "nat.h"
53 #include "empio.h"
54 #include "file.h"
55 #include "com.h"
56 #include "news.h"
57 #include "tel.h"
58 extern int update_pending;
59 #include "prototypes.h"
60
61 void outid(struct player *pl, int n);
62
63 /*VARARGS*/
64 void
65 pr(s_char *format, ...)
66 {
67     s_char buf[4096];
68     va_list ap;
69
70     va_start(ap, format);
71     (void)vsprintf(buf, format, ap);
72     va_end(ap);
73     pr_player(player, C_DATA, buf);
74 }
75
76 void
77 prnf(s_char *buf)
78 {
79     pr_player(player, C_DATA, buf);
80 }
81
82 /*VARARGS*/
83 void
84 pr_id(struct player *p, int id, s_char *format, ...)
85 {
86     s_char buf[4096];
87     va_list ap;
88
89     if (p->curid >= 0) {
90         io_puts(p->iop, "\n");
91         p->curid = -1;
92     }
93     va_start(ap, format);
94     (void)vsprintf(buf, format, ap);
95     va_end(ap);
96     pr_player(p, id, buf);
97 }
98
99 void
100 pr_flash(struct player *pl, s_char *format, ...)
101 {
102     s_char buf[4096];
103     va_list ap;
104
105     if (pl->state != PS_PLAYING)
106         return;
107     va_start(ap, format);
108     (void)vsprintf(buf, format, ap);
109     va_end(ap);
110     pr_player(pl, C_FLASH, buf);
111     io_output(pl->iop, IO_NOWAIT);
112 }
113
114 void
115 pr_inform(struct player *pl, s_char *format, ...)
116 {
117     s_char buf[4096];
118     va_list ap;
119
120     if (pl->state != PS_PLAYING)
121         return;
122     va_start(ap, format);
123     (void)vsprintf(buf, format, ap);
124     va_end(ap);
125     pr_player(pl, C_INFORM, buf);
126     io_output(pl->iop, IO_NOWAIT);
127 }
128
129 void
130 pr_wall(s_char *format, ...)
131 {
132     s_char buf[4096];
133     struct player *p;
134     va_list ap;
135
136     va_start(ap, format);
137     (void)vsprintf(buf, format, ap);
138     va_end(ap);
139     for (p = player_next(0); p; p = player_next(p)) {
140         if (p->state != PS_PLAYING)
141             continue;
142         pr_player(p, C_FLASH, buf);
143         io_output(p->iop, IO_NOWAIT);
144     }
145 }
146
147 void
148 pr_player(struct player *pl, int id, s_char *buf)
149 {
150     register s_char *p;
151     register s_char *bp;
152     register int len;
153
154     bp = buf;
155     while (*bp != '\0') {
156         if (pl->curid != -1 && pl->curid != id) {
157             io_puts(pl->iop, "\n");
158             pl->curid = -1;
159         }
160         if (pl->curid == -1) {
161             outid(pl, id);
162         }
163         p = index(bp, '\n');
164         if (p != 0) {
165             len = (p - bp) + 1;
166             if (pl->command && (pl->command->c_flags & C_MOD))
167                 io_write(pl->iop, bp, len, IO_NOWAIT);
168             else
169                 io_write(pl->iop, bp, len, IO_WAIT);
170             bp += len;
171             pl->curid = -1;
172         } else {
173             len = io_puts(pl->iop, bp);
174             bp += len;
175         }
176     }
177 }
178
179 /*
180  * highlighted characters have hex 80 or'ed in
181  * with them to designate their highlightedness
182  */
183 void
184 pr_hilite(s_char *buf)
185 {
186     register s_char *bp;
187     register s_char c;
188     s_char *p;
189
190     p = (s_char *)malloc(strlen(buf) + 1);
191     strcpy(p, buf);
192     for (bp = p; 0 != (c = *bp); bp++)
193         if (isprint(c))
194             *bp |= 0x80;
195     pr(p);
196     free(p);
197 }
198
199 /*
200  * output hex code + space
201  */
202 void
203 outid(struct player *pl, int n)
204 {
205     s_char c;
206     s_char buf[3];
207
208     if (n > C_LAST) {
209         logerror("outid: %d not valid code\n", n);
210         return;
211     }
212     if (n >= 10)
213         c = 'a' - 10 + n;
214     else
215         c = '0' + n;
216     buf[0] = c;
217     buf[1] = ' ';
218     buf[2] = '\0';
219     io_puts(pl->iop, buf);
220     pl->curid = n;
221 }
222
223 void
224 prredir(s_char *redir)
225 {
226     pr_id(player, *redir == '>' ? C_REDIR : C_PIPE, "%s\n", redir);
227 }
228
229 void
230 prexec(s_char *file)
231 {
232     pr_id(player, C_EXECUTE, "%s\n", file);
233 }
234
235 void
236 prprompt(int min, int btu)
237 {
238     pr_id(player, C_PROMPT, "%d %d\n", min, btu);
239 }
240
241 void
242 showvers(int vers)
243 {
244     pr_id(player, C_INIT, "%d\n", vers);
245 }
246
247 int
248 prmptrd(s_char *prompt, s_char *str, int size)
249 {
250     int r;
251
252     pr_id(player, C_FLUSH, "%s\n", prompt);
253     if ((r = recvclient(str, size)) < 0)
254         return r;
255     time(&player->curup);
256     if (*str == 0)
257         return 1;
258     return strlen(str);
259 }
260
261 void
262 prdate(void)
263 {
264     time_t now;
265
266     (void)time(&now);
267     pr(ctime(&now));
268 }
269
270 /*
271  * print x,y formatting as country
272  */
273 void
274 prxy(s_char *format, coord x, coord y, natid country)
275 {
276     s_char buf[255];
277     struct natstr *np;
278
279     np = getnatp(country);
280     sprintf(buf, format, xrel(np, x), yrel(np, y));
281     pr(buf);
282 }
283
284 /*VARARGS*/
285 void
286 PR(int cn, s_char *format, ...)
287 {
288     /* XXX should really do this on a per-nation basis */
289     static s_char longline[MAXNOC][512];
290     int newline;
291     va_list ap;
292     s_char buf[1024];
293
294     va_start(ap, format);
295     (void)vsprintf(buf, format, ap);
296     va_end(ap);
297     newline = strrchr(buf, '\n') ? 1 : 0;
298     strcat(longline[cn], buf);
299     if (newline) {
300         if (update_pending || (cn && cn != player->cnum))
301             typed_wu(0, cn, longline[cn], TEL_BULLETIN);
302         else
303             pr_player(player, C_DATA, longline[cn]);
304         longline[cn][0] = '\0';
305     }
306 }
307
308 void
309 PRdate(natid cn)
310 {
311     time_t now;
312
313     (void)time(&now);
314     PR(cn, ctime(&now));
315 }
316
317 void
318 pr_beep(void)
319 {
320     struct natstr *np = getnatp(player->cnum);
321
322     if (np->nat_flags & NF_BEEP)
323         pr("\07");
324 }
325
326 void
327 mpr(int cn, s_char *format, ...)
328 {
329     s_char buf[4096];
330     va_list ap;
331
332     va_start(ap, format);
333     (void)vsprintf(buf, format, ap);
334     va_end(ap);
335     if (cn) {
336         if (update_pending || cn != player->cnum)
337             typed_wu(0, cn, buf, TEL_BULLETIN);
338         else
339             pr_player(player, C_DATA, buf);
340     }
341 }