1 /*        $NetBSD: terminal.c,v 1.8 2021/05/02 12:50:45 rillig Exp $  */
2 /*
3  * Copyright (c) 1983-2003, Regents of the University of California.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  * + Redistributions of source code must retain the above copyright
11  *   notice, this list of conditions and the following disclaimer.
12  * + Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  * + Neither the name of the University of California, San Francisco nor
16  *   the names of its contributors may be used to endorse or promote
17  *   products derived from this software without specific prior written
18  *   permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include <sys/cdefs.h>
34 #ifndef lint
35 __RCSID("$NetBSD: terminal.c,v 1.8 2021/05/02 12:50:45 rillig Exp $");
36 #endif /* not lint */
37 
38 #include <stdarg.h>
39 #include "hunt.h"
40 #define TERM_WIDTH  80        /* Assume terminals are 80-char wide */
41 
42 /*
43  * cgoto:
44  *        Move the cursor to the given position on the given player's
45  *        terminal.
46  */
47 void
cgoto(PLAYER * pp,int y,int x)48 cgoto(PLAYER *pp, int y, int x)
49 {
50           if (x == pp->p_curx && y == pp->p_cury)
51                     return;
52           sendcom(pp, MOVE, y, x);
53           pp->p_cury = y;
54           pp->p_curx = x;
55 }
56 
57 /*
58  * outch:
59  *        Put out a single character.
60  */
61 void
outch(PLAYER * pp,int ch)62 outch(PLAYER *pp, int ch)
63 {
64           if (++pp->p_curx >= TERM_WIDTH) {
65                     pp->p_curx = 0;
66                     pp->p_cury++;
67           }
68           (void) putc(ch, pp->p_output);
69 }
70 
71 /*
72  * outstr:
73  *        Put out a string of the given length.
74  */
75 void
outstr(PLAYER * pp,const char * str,int len)76 outstr(PLAYER *pp, const char *str, int len)
77 {
78           pp->p_curx += len;
79           pp->p_cury += (pp->p_curx / TERM_WIDTH);
80           pp->p_curx %= TERM_WIDTH;
81           while (len--)
82                     (void) putc(*str++, pp->p_output);
83 }
84 
85 /*
86  * clrscr:
87  *        Clear the screen, and reset the current position on the screen.
88  */
89 void
clrscr(PLAYER * pp)90 clrscr(PLAYER *pp)
91 {
92           sendcom(pp, CLEAR);
93           pp->p_cury = 0;
94           pp->p_curx = 0;
95 }
96 
97 /*
98  * ce:
99  *        Clear to the end of the line
100  */
101 void
ce(PLAYER * pp)102 ce(PLAYER *pp)
103 {
104           sendcom(pp, CLRTOEOL);
105 }
106 
107 #if 0               /* XXX lukem */
108 /*
109  * ref;
110  *        Refresh the screen
111  */
112 void
113 ref(PLAYER *pp)
114 {
115           sendcom(pp, REFRESH);
116 }
117 #endif
118 
119 /*
120  * sendcom:
121  *        Send a command to the given user
122  */
123 void
sendcom(PLAYER * pp,int command,...)124 sendcom(PLAYER *pp, int command, ...)
125 {
126           va_list   ap;
127           int arg1, arg2;
128 
129           va_start(ap, command);
130           (void) putc(command, pp->p_output);
131           switch (command & 0377) {
132           case MOVE:
133                     arg1 = va_arg(ap, int);
134                     arg2 = va_arg(ap, int);
135                     (void) putc(arg1, pp->p_output);
136                     (void) putc(arg2, pp->p_output);
137                     break;
138           case ADDCH:
139           case READY:
140                     arg1 = va_arg(ap, int);
141                     (void) putc(arg1, pp->p_output);
142                     break;
143           }
144 
145           va_end(ap);                   /* No return needed for void functions. */
146 }
147