xref: /dragonfly/games/hunt/huntd/terminal.c (revision f746689a)
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 }
255