Initial import from FreeBSD RELENG_4:
[games.git] / usr.bin / window / wwframe.c
1 /*
2  * Copyright (c) 1983, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Edward Wang at The University of California, Berkeley.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36
37 #ifndef lint
38 static char sccsid[] = "@(#)wwframe.c   8.1 (Berkeley) 6/6/93";
39 static char rcsid[] =
40   "$FreeBSD: src/usr.bin/window/wwframe.c,v 1.1.1.1.14.1 2001/05/17 09:45:01 obrien Exp $";
41 #endif /* not lint */
42
43 #include "ww.h"
44 #include "tt.h"
45
46 #define frameok(w, r, c) (w1 = wwindex[wwsmap[r][c]], \
47         w1->ww_fmap || w1->ww_order > (w)->ww_order)
48
49 wwframe(w, wframe)
50 register struct ww *w;
51 struct ww *wframe;
52 {
53         register r, c;
54         char a1, a2, a3;
55         char b1, b2, b3;
56         register char *smap;
57         register code;
58         register struct ww *w1;
59
60         if (w->ww_w.t > 0) {
61                 r = w->ww_w.t - 1;
62                 c = w->ww_i.l - 1;
63                 smap = &wwsmap[r + 1][c + 1];
64                 a1 = 0;
65                 a2 = 0;
66                 b1 = 0;
67                 b2 = c < 0 || frameok(w, r, c);
68
69                 for (; c < w->ww_i.r; c++) {
70                         if (c + 1 >= wwncol) {
71                                 a3 = 1;
72                                 b3 = 1;
73                         } else {
74                                 a3 = w->ww_index == *smap++;
75                                 b3 = frameok(w, r, c + 1);
76                         }
77                         if (b2) {
78                                 code = 0;
79                                 if ((a1 || a2) && b1)
80                                         code |= WWF_L;
81                                 if ((a2 || a3) && b3)
82                                         code |= WWF_R;
83                                 if (code)
84                                         wwframec(wframe, r, c, code|WWF_TOP);
85                         }
86                         a1 = a2;
87                         a2 = a3;
88                         b1 = b2;
89                         b2 = b3;
90                 }
91                 if ((a1 || a2) && b1 && b2)
92                         wwframec(wframe, r, c, WWF_L|WWF_TOP);
93         }
94
95         if (w->ww_w.b < wwnrow) {
96                 r = w->ww_w.b;
97                 c = w->ww_i.l - 1;
98                 smap = &wwsmap[r - 1][c + 1];
99                 a1 = 0;
100                 a2 = 0;
101                 b1 = 0;
102                 b2 = c < 0 || frameok(w, r, c);
103
104                 for (; c < w->ww_i.r; c++) {
105                         if (c + 1 >= wwncol) {
106                                 a3 = 1;
107                                 b3 = 1;
108                         } else {
109                                 a3 = w->ww_index == *smap++;
110                                 b3 = frameok(w, r, c + 1);
111                         }
112                         if (b2) {
113                                 code = 0;
114                                 if ((a1 || a2) && b1)
115                                         code |= WWF_L;
116                                 if ((a2 || a3) && b3)
117                                         code |= WWF_R;
118                                 if (code)
119                                         wwframec(wframe, r, c, code);
120                         }
121                         a1 = a2;
122                         a2 = a3;
123                         b1 = b2;
124                         b2 = b3;
125                 }
126                 if ((a1 || a2) && b1 && b2)
127                         wwframec(wframe, r, c, WWF_L);
128         }
129
130         if (w->ww_w.l > 0) {
131                 r = w->ww_i.t - 1;
132                 c = w->ww_w.l - 1;
133                 a1 = 0;
134                 a2 = 0;
135                 b1 = 0;
136                 b2 = r < 0 || frameok(w, r, c);
137
138                 for (; r < w->ww_i.b; r++) {
139                         if (r + 1 >= wwnrow) {
140                                 a3 = 1;
141                                 b3 = 1;
142                         } else {
143                                 a3 = w->ww_index == wwsmap[r + 1][c + 1];
144                                 b3 = frameok(w, r + 1, c);
145                         }
146                         if (b2) {
147                                 code = 0;
148                                 if ((a1 || a2) && b1)
149                                         code |= WWF_U;
150                                 if ((a2 || a3) && b3)
151                                         code |= WWF_D;
152                                 if (code)
153                                         wwframec(wframe, r, c, code);
154                         }
155                         a1 = a2;
156                         a2 = a3;
157                         b1 = b2;
158                         b2 = b3;
159                 }
160                 if ((a1 || a2) && b1 && b2)
161                         wwframec(wframe, r, c, WWF_U);
162         }
163
164         if (w->ww_w.r < wwncol) {
165                 r = w->ww_i.t - 1;
166                 c = w->ww_w.r;
167                 a1 = 0;
168                 a2 = 0;
169                 b1 = 0;
170                 b2 = r < 0 || frameok(w, r, c);
171
172                 for (; r < w->ww_i.b; r++) {
173                         if (r + 1 >= wwnrow) {
174                                 a3 = 1;
175                                 b3 = 1;
176                         } else {
177                                 a3 = w->ww_index == wwsmap[r + 1][c - 1];
178                                 b3 = frameok(w, r + 1, c);
179                         }
180                         if (b2) {
181                                 code = 0;
182                                 if ((a1 || a2) && b1)
183                                         code |= WWF_U;
184                                 if ((a2 || a3) && b3)
185                                         code |= WWF_D;
186                                 if (code)
187                                         wwframec(wframe, r, c, code);
188                         }
189                         a1 = a2;
190                         a2 = a3;
191                         b1 = b2;
192                         b2 = b3;
193                 }
194                 if ((a1 || a2) && b1 && b2)
195                         wwframec(wframe, r, c, WWF_U);
196         }
197 }
198
199 wwframec(f, r, c, code)
200 register struct ww *f;
201 register r, c;
202 char code;
203 {
204         char oldcode;
205         register char *smap;
206
207         if (r < f->ww_i.t || r >= f->ww_i.b || c < f->ww_i.l || c >= f->ww_i.r)
208                 return;
209
210         smap = &wwsmap[r][c];
211
212         {
213                 register struct ww *w;
214
215                 w = wwindex[*smap];
216                 if (w->ww_order > f->ww_order) {
217                         if (w != &wwnobody && w->ww_win[r][c] == 0)
218                                 w->ww_nvis[r]--;
219                         *smap = f->ww_index;
220                 }
221         }
222
223         if (f->ww_fmap != 0) {
224                 register char *fmap;
225
226                 fmap = &f->ww_fmap[r][c];
227                 oldcode = *fmap;
228                 *fmap |= code;
229                 if (code & WWF_TOP)
230                         *fmap &= ~WWF_LABEL;
231                 code = *fmap;
232         } else
233                 oldcode = 0;
234         {
235                 register char *win = &f->ww_win[r][c];
236
237                 if (*win == WWM_GLS && *smap == f->ww_index)
238                         f->ww_nvis[r]++;
239                 *win &= ~WWM_GLS;
240         }
241         if (oldcode != code && (code & WWF_LABEL) == 0) {
242                 register short frame;
243
244                 frame = tt.tt_frame[code & WWF_MASK];
245                 f->ww_buf[r][c].c_w = frame;
246                 if (wwsmap[r][c] == f->ww_index) {
247                         wwtouched[r] |= WWU_TOUCHED;
248                         wwns[r][c].c_w = frame;
249                 }
250         }
251 }