Ansify (silence -Wold-style-definition)
[dragonfly.git] / games / hunt / huntd / terminal.c
1 /*
2  * Copyright (c) 1983-2003, Regents of the University of California.
3  * All rights reserved.
4  * 
5  * Redistribution and use in source and binary forms, with or without 
6  * modification, are permitted provided that the following conditions are 
7  * met:
8  * 
9  * + Redistributions of source code must retain the above copyright 
10  *   notice, this list of conditions and the following disclaimer.
11  * + Redistributions in binary form must reproduce the above copyright 
12  *   notice, this list of conditions and the following disclaimer in the 
13  *   documentation and/or other materials provided with the distribution.
14  * + Neither the name of the University of California, San Francisco nor 
15  *   the names of its contributors may be used to endorse or promote 
16  *   products derived from this software without specific prior written 
17  *   permission.
18  * 
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
22  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  * $OpenBSD: terminal.c,v 1.10 2008/06/20 13:08:44 ragge Exp $
32  * $NetBSD: terminal.c,v 1.2 1997/10/10 16:34:05 lukem Exp $
33  * $DragonFly: src/games/hunt/huntd/terminal.c,v 1.2 2008/09/04 16:12:51 swildner Exp $
34  */
35
36 #include <stdarg.h>
37 #include <syslog.h>
38 #include <err.h>
39 #include <string.h>
40
41 #include "hunt.h"
42 #include "server.h"
43 #include "conf.h"
44
45 #define TERM_WIDTH      80      /* Assume terminals are 80-char wide */
46
47 /*
48  * cgoto:
49  *      Move the cursor to the given position on the given player's
50  *      terminal.
51  */
52 void
53 cgoto(PLAYER *pp, int y, int x)
54 {
55
56         if (pp == ALL_PLAYERS) {
57                 for (pp = Player; pp < End_player; pp++)
58                         cgoto(pp, y, x);
59                 for (pp = Monitor; pp < End_monitor; pp++)
60                         cgoto(pp, y, x);
61                 return;
62         }
63
64         if (x == pp->p_curx && y == pp->p_cury)
65                 return;
66
67         sendcom(pp, MOVE, y, x);
68         pp->p_cury = y;
69         pp->p_curx = x;
70 }
71
72 /*
73  * outch:
74  *      Put out a single character.
75  */
76 void
77 outch(PLAYER *pp, char ch)
78 {
79
80         if (pp == ALL_PLAYERS) {
81                 for (pp = Player; pp < End_player; pp++)
82                         outch(pp, ch);
83                 for (pp = Monitor; pp < End_monitor; pp++)
84                         outch(pp, ch);
85                 return;
86         }
87
88         if (++pp->p_curx >= TERM_WIDTH) {
89                 pp->p_curx = 0;
90                 pp->p_cury++;
91         }
92         (void) putc(ch, pp->p_output);
93 }
94
95 /*
96  * outstr:
97  *      Put out a string of the given length.
98  */
99 void
100 outstr(PLAYER *pp, const char *str, int len)
101 {
102         if (pp == ALL_PLAYERS) {
103                 for (pp = Player; pp < End_player; pp++)
104                         outstr(pp, str, len);
105                 for (pp = Monitor; pp < End_monitor; pp++)
106                         outstr(pp, str, len);
107                 return;
108         }
109
110         pp->p_curx += len;
111         pp->p_cury += (pp->p_curx / TERM_WIDTH);
112         pp->p_curx %= TERM_WIDTH;
113         while (len--)
114                 (void) putc(*str++, pp->p_output);
115 }
116
117 /*
118  * outat:
119  *      draw a string at a location on the client.
120  *      Cursor doesn't move if the location is invalid
121  */
122 void
123 outyx(PLAYER *pp, int y, int x, const char *fmt, ...)
124 {
125         va_list ap;
126         char buf[BUFSIZ];
127         int len;
128
129         va_start(ap, fmt);
130         len = vsnprintf(buf, sizeof(buf), fmt, ap);
131         va_end(ap);
132         if (len == -1)
133                 len = 0;
134         if (len >= (int)sizeof(buf))
135                 len = sizeof(buf) - 1;
136         if (y >= 0 && x >= 0)
137                 cgoto(pp, y, x);
138         if (len > 0)
139                 outstr(pp, buf, len);
140 }
141
142 /*
143  * clrscr:
144  *      Clear the screen, and reset the current position on the screen.
145  */
146 void
147 clrscr(PLAYER *pp)
148 {
149
150         if (pp == ALL_PLAYERS) {
151                 for (pp = Player; pp < End_player; pp++)
152                         clrscr(pp);
153                 for (pp = Monitor; pp < End_monitor; pp++)
154                         clrscr(pp);
155                 return;
156         }
157
158         sendcom(pp, CLEAR);
159         pp->p_cury = 0;
160         pp->p_curx = 0;
161 }
162
163 /*
164  * ce:
165  *      Clear to the end of the line
166  */
167 void
168 ce(PLAYER *pp)
169 {
170         sendcom(pp, CLRTOEOL);
171 }
172
173 /*
174  * sendcom:
175  *      Send a command to the given user
176  */
177 void
178 sendcom(PLAYER *pp, int command, ...)
179 {
180         va_list ap;
181         char    buf[3];
182         int     len = 0;
183
184         va_start(ap, command);
185         buf[len++] = command;
186         switch (command & 0377) {
187         case MOVE:
188                 buf[len++] = va_arg(ap, int);
189                 buf[len++] = va_arg(ap, int);
190                 break;
191         case ADDCH:
192         case READY:
193         case ENDWIN:
194                 buf[len++] = va_arg(ap, int);
195                 break;
196         }
197         va_end(ap);
198
199         if (pp == ALL_PLAYERS) {
200                 for (pp = Player; pp < End_player; pp++)
201                         fwrite(buf, sizeof buf[0], len, pp->p_output);
202                 for (pp = Monitor; pp < End_monitor; pp++)
203                         fwrite(buf, sizeof buf[0], len, pp->p_output);
204                 return;
205         } else
206                 fwrite(buf, sizeof buf[0], len, pp->p_output);
207 }
208
209 /*
210  * sync:
211  *      Flush the output buffer to the player
212  */
213 void
214 flush(PLAYER *pp)
215 {
216         if (pp == ALL_PLAYERS) {
217                 for (pp = Player; pp < End_player; pp++)
218                         fflush(pp->p_output);
219                 for (pp = Monitor; pp < End_monitor; pp++)
220                         fflush(pp->p_output);
221         } else
222                 fflush(pp->p_output);
223 }
224
225 void
226 logx(int prio, const char *fmt, ...)
227 {
228         va_list ap;
229
230         va_start(ap, fmt);
231         if (conf_syslog)
232                 vsyslog(prio, fmt, ap);
233         else if (conf_logerr)
234         /* if (prio < LOG_NOTICE) */
235                 vwarnx(fmt, ap);
236         va_end(ap);
237 }
238
239 void
240 logit(int prio, const char *fmt, ...)
241 {
242         va_list ap;
243         char fmtm[1024];
244
245         va_start(ap, fmt);
246         if (conf_syslog) {
247                 strlcpy(fmtm, fmt, sizeof fmtm);
248                 strlcat(fmtm, ": %m", sizeof fmtm);
249                 vsyslog(prio, fmtm, ap);
250         } else if (conf_logerr)
251         /* if (prio < LOG_NOTICE) */
252                 vwarn(fmt, ap);
253         va_end(ap);
254 }