display.c revision 1.1 1 1.1 cgd /* display.c Larn is copyrighted 1986 by Noah Morgan. */
2 1.1 cgd #include "header.h"
3 1.1 cgd #define makecode(_a,_b,_c) (((_a)<<16) + ((_b)<<8) + (_c))
4 1.1 cgd
5 1.1 cgd static int minx,maxx,miny,maxy,k,m;
6 1.1 cgd static char bot1f=0,bot2f=0,bot3f=0;
7 1.1 cgd char always=0;
8 1.1 cgd /*
9 1.1 cgd bottomline()
10 1.1 cgd
11 1.1 cgd now for the bottom line of the display
12 1.1 cgd */
13 1.1 cgd bottomline()
14 1.1 cgd { recalc(); bot1f=1; }
15 1.1 cgd bottomhp()
16 1.1 cgd { bot2f=1; }
17 1.1 cgd bottomspell()
18 1.1 cgd { bot3f=1; }
19 1.1 cgd bottomdo()
20 1.1 cgd {
21 1.1 cgd if (bot1f) { bot3f=bot1f=bot2f=0; bot_linex(); return; }
22 1.1 cgd if (bot2f) { bot2f=0; bot_hpx(); }
23 1.1 cgd if (bot3f) { bot3f=0; bot_spellx(); }
24 1.1 cgd }
25 1.1 cgd
26 1.1 cgd static void botsub();
27 1.1 cgd
28 1.1 cgd bot_linex()
29 1.1 cgd {
30 1.1 cgd register int i;
31 1.1 cgd if (cbak[SPELLS] <= -50 || (always))
32 1.1 cgd {
33 1.1 cgd cursor( 1,18);
34 1.1 cgd if (c[SPELLMAX]>99) lprintf("Spells:%3d(%3d)",(long)c[SPELLS],(long)c[SPELLMAX]);
35 1.1 cgd else lprintf("Spells:%3d(%2d) ",(long)c[SPELLS],(long)c[SPELLMAX]);
36 1.1 cgd lprintf(" AC: %-3d WC: %-3d Level",(long)c[AC],(long)c[WCLASS]);
37 1.1 cgd if (c[LEVEL]>99) lprintf("%3d",(long)c[LEVEL]);
38 1.1 cgd else lprintf(" %-2d",(long)c[LEVEL]);
39 1.1 cgd lprintf(" Exp: %-9d %s\n",(long)c[EXPERIENCE],class[c[LEVEL]-1]);
40 1.1 cgd lprintf("HP: %3d(%3d) STR=%-2d INT=%-2d ",
41 1.1 cgd (long)c[HP],(long)c[HPMAX],(long)(c[STRENGTH]+c[STREXTRA]),(long)c[INTELLIGENCE]);
42 1.1 cgd lprintf("WIS=%-2d CON=%-2d DEX=%-2d CHA=%-2d LV:",
43 1.1 cgd (long)c[WISDOM],(long)c[CONSTITUTION],(long)c[DEXTERITY],(long)c[CHARISMA]);
44 1.1 cgd
45 1.1 cgd if ((level==0) || (wizard)) c[TELEFLAG]=0;
46 1.1 cgd if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]);
47 1.1 cgd lprintf(" Gold: %-6d",(long)c[GOLD]);
48 1.1 cgd always=1; botside();
49 1.1 cgd c[TMP] = c[STRENGTH]+c[STREXTRA];
50 1.1 cgd for (i=0; i<100; i++) cbak[i]=c[i];
51 1.1 cgd return;
52 1.1 cgd }
53 1.1 cgd
54 1.1 cgd botsub(makecode(SPELLS,8,18),"%3d");
55 1.1 cgd if (c[SPELLMAX]>99) botsub(makecode(SPELLMAX,12,18),"%3d)");
56 1.1 cgd else botsub(makecode(SPELLMAX,12,18),"%2d) ");
57 1.1 cgd botsub(makecode(HP,5,19),"%3d");
58 1.1 cgd botsub(makecode(HPMAX,9,19),"%3d");
59 1.1 cgd botsub(makecode(AC,21,18),"%-3d");
60 1.1 cgd botsub(makecode(WCLASS,30,18),"%-3d");
61 1.1 cgd botsub(makecode(EXPERIENCE,49,18),"%-9d");
62 1.1 cgd if (c[LEVEL] != cbak[LEVEL])
63 1.1 cgd { cursor(59,18); lprcat(class[c[LEVEL]-1]); }
64 1.1 cgd if (c[LEVEL]>99) botsub(makecode(LEVEL,40,18),"%3d");
65 1.1 cgd else botsub(makecode(LEVEL,40,18)," %-2d");
66 1.1 cgd c[TMP] = c[STRENGTH]+c[STREXTRA]; botsub(makecode(TMP,18,19),"%-2d");
67 1.1 cgd botsub(makecode(INTELLIGENCE,25,19),"%-2d");
68 1.1 cgd botsub(makecode(WISDOM,32,19),"%-2d");
69 1.1 cgd botsub(makecode(CONSTITUTION,39,19),"%-2d");
70 1.1 cgd botsub(makecode(DEXTERITY,46,19),"%-2d");
71 1.1 cgd botsub(makecode(CHARISMA,53,19),"%-2d");
72 1.1 cgd if ((level != cbak[CAVELEVEL]) || (c[TELEFLAG] != cbak[TELEFLAG]))
73 1.1 cgd {
74 1.1 cgd if ((level==0) || (wizard)) c[TELEFLAG]=0;
75 1.1 cgd cbak[TELEFLAG] = c[TELEFLAG];
76 1.1 cgd cbak[CAVELEVEL] = level; cursor(59,19);
77 1.1 cgd if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]);
78 1.1 cgd }
79 1.1 cgd botsub(makecode(GOLD,69,19),"%-6d");
80 1.1 cgd botside();
81 1.1 cgd }
82 1.1 cgd
83 1.1 cgd /*
84 1.1 cgd special subroutine to update only the gold number on the bottomlines
85 1.1 cgd called from ogold()
86 1.1 cgd */
87 1.1 cgd bottomgold()
88 1.1 cgd {
89 1.1 cgd botsub(makecode(GOLD,69,19),"%-6d");
90 1.1 cgd /* botsub(GOLD,"%-6d",69,19); */
91 1.1 cgd }
92 1.1 cgd
93 1.1 cgd /*
94 1.1 cgd special routine to update hp and level fields on bottom lines
95 1.1 cgd called in monster.c hitplayer() and spattack()
96 1.1 cgd */
97 1.1 cgd bot_hpx()
98 1.1 cgd {
99 1.1 cgd if (c[EXPERIENCE] != cbak[EXPERIENCE])
100 1.1 cgd {
101 1.1 cgd recalc(); bot_linex();
102 1.1 cgd }
103 1.1 cgd else botsub(makecode(HP,5,19),"%3d");
104 1.1 cgd }
105 1.1 cgd
106 1.1 cgd /*
107 1.1 cgd special routine to update number of spells called from regen()
108 1.1 cgd */
109 1.1 cgd bot_spellx()
110 1.1 cgd {
111 1.1 cgd botsub(makecode(SPELLS,9,18),"%2d");
112 1.1 cgd }
113 1.1 cgd
114 1.1 cgd /*
115 1.1 cgd common subroutine for a more economical bottomline()
116 1.1 cgd */
117 1.1 cgd static struct bot_side_def
118 1.1 cgd {
119 1.1 cgd int typ;
120 1.1 cgd char *string;
121 1.1 cgd }
122 1.1 cgd bot_data[] =
123 1.1 cgd {
124 1.1 cgd STEALTH,"stealth", UNDEADPRO,"undead pro", SPIRITPRO,"spirit pro",
125 1.1 cgd CHARMCOUNT,"Charm", TIMESTOP,"Time Stop", HOLDMONST,"Hold Monst",
126 1.1 cgd GIANTSTR,"Giant Str", FIRERESISTANCE,"Fire Resit", DEXCOUNT,"Dexterity",
127 1.1 cgd STRCOUNT,"Strength", SCAREMONST,"Scare", HASTESELF,"Haste Self",
128 1.1 cgd CANCELLATION,"Cancel", INVISIBILITY,"Invisible", ALTPRO,"Protect 3",
129 1.1 cgd PROTECTIONTIME,"Protect 2", WTW,"Wall-Walk"
130 1.1 cgd };
131 1.1 cgd
132 1.1 cgd botside()
133 1.1 cgd {
134 1.1 cgd register int i,idx;
135 1.1 cgd for (i=0; i<17; i++)
136 1.1 cgd {
137 1.1 cgd idx = bot_data[i].typ;
138 1.1 cgd if ((always) || (c[idx] != cbak[idx]))
139 1.1 cgd {
140 1.1 cgd if ((always) || (cbak[idx] == 0))
141 1.1 cgd { if (c[idx]) { cursor(70,i+1); lprcat(bot_data[i].string); } } else
142 1.1 cgd if (c[idx]==0) { cursor(70,i+1); lprcat(" "); }
143 1.1 cgd cbak[idx]=c[idx];
144 1.1 cgd }
145 1.1 cgd }
146 1.1 cgd always=0;
147 1.1 cgd }
148 1.1 cgd
149 1.1 cgd static void
150 1.1 cgd botsub(idx,str)
151 1.1 cgd register int idx;
152 1.1 cgd char *str;
153 1.1 cgd {
154 1.1 cgd register int x,y;
155 1.1 cgd y = idx & 0xff; x = (idx>>8) & 0xff; idx >>= 16;
156 1.1 cgd if (c[idx] != cbak[idx])
157 1.1 cgd { cbak[idx]=c[idx]; cursor(x,y); lprintf(str,(long)c[idx]); }
158 1.1 cgd }
159 1.1 cgd
160 1.1 cgd /*
161 1.1 cgd * subroutine to draw only a section of the screen
162 1.1 cgd * only the top section of the screen is updated. If entire lines are being
163 1.1 cgd * drawn, then they will be cleared first.
164 1.1 cgd */
165 1.1 cgd int d_xmin=0,d_xmax=MAXX,d_ymin=0,d_ymax=MAXY; /* for limited screen drawing */
166 1.1 cgd draws(xmin,xmax,ymin,ymax)
167 1.1 cgd int xmin,xmax,ymin,ymax;
168 1.1 cgd {
169 1.1 cgd register int i,idx;
170 1.1 cgd if (xmin==0 && xmax==MAXX) /* clear section of screen as needed */
171 1.1 cgd {
172 1.1 cgd if (ymin==0) cl_up(79,ymax);
173 1.1 cgd else for (i=ymin; i<ymin; i++) cl_line(1,i+1);
174 1.1 cgd xmin = -1;
175 1.1 cgd }
176 1.1 cgd d_xmin=xmin; d_xmax=xmax; d_ymin=ymin; d_ymax=ymax; /* for limited screen drawing */
177 1.1 cgd drawscreen();
178 1.1 cgd if (xmin<=0 && xmax==MAXX) /* draw stuff on right side of screen as needed*/
179 1.1 cgd {
180 1.1 cgd for (i=ymin; i<ymax; i++)
181 1.1 cgd {
182 1.1 cgd idx = bot_data[i].typ;
183 1.1 cgd if (c[idx])
184 1.1 cgd {
185 1.1 cgd cursor(70,i+1); lprcat(bot_data[i].string);
186 1.1 cgd }
187 1.1 cgd cbak[idx]=c[idx];
188 1.1 cgd }
189 1.1 cgd }
190 1.1 cgd }
191 1.1 cgd
192 1.1 cgd /*
193 1.1 cgd drawscreen()
194 1.1 cgd
195 1.1 cgd subroutine to redraw the whole screen as the player knows it
196 1.1 cgd */
197 1.1 cgd char screen[MAXX][MAXY],d_flag; /* template for the screen */
198 1.1 cgd drawscreen()
199 1.1 cgd {
200 1.1 cgd register int i,j,k;
201 1.1 cgd int lastx,lasty; /* variables used to optimize the object printing */
202 1.1 cgd if (d_xmin==0 && d_xmax==MAXX && d_ymin==0 && d_ymax==MAXY)
203 1.1 cgd {
204 1.1 cgd d_flag=1; clear(); /* clear the screen */
205 1.1 cgd }
206 1.1 cgd else
207 1.1 cgd {
208 1.1 cgd d_flag=0; cursor(1,1);
209 1.1 cgd }
210 1.1 cgd if (d_xmin<0)
211 1.1 cgd d_xmin=0; /* d_xmin=-1 means display all without bottomline */
212 1.1 cgd
213 1.1 cgd for (i=d_ymin; i<d_ymax; i++)
214 1.1 cgd for (j=d_xmin; j<d_xmax; j++)
215 1.1 cgd if (know[j][i]==0) screen[j][i] = ' '; else
216 1.1 cgd if (k=mitem[j][i]) screen[j][i] = monstnamelist[k]; else
217 1.1 cgd if ((k=item[j][i])==OWALL) screen[j][i] = '#';
218 1.1 cgd else screen[j][i] = ' ';
219 1.1 cgd
220 1.1 cgd for (i=d_ymin; i<d_ymax; i++)
221 1.1 cgd {
222 1.1 cgd j=d_xmin; while ((screen[j][i]==' ') && (j<d_xmax)) j++;
223 1.1 cgd /* was m=0 */
224 1.1 cgd if (j >= d_xmax) m=d_xmin; /* don't search backwards if blank line */
225 1.1 cgd else
226 1.1 cgd { /* search backwards for end of line */
227 1.1 cgd m=d_xmax-1; while ((screen[m][i]==' ') && (m>d_xmin)) --m;
228 1.1 cgd if (j<=m) cursor(j+1,i+1); else continue;
229 1.1 cgd }
230 1.1 cgd while (j <= m)
231 1.1 cgd {
232 1.1 cgd if (j <= m-3)
233 1.1 cgd {
234 1.1 cgd for (k=j; k<=j+3; k++) if (screen[k][i] != ' ') k=1000;
235 1.1 cgd if (k < 1000)
236 1.1 cgd { while(screen[j][i]==' ' && j<=m) j++; cursor(j+1,i+1); }
237 1.1 cgd }
238 1.1 cgd lprc(screen[j++][i]);
239 1.1 cgd }
240 1.1 cgd }
241 1.1 cgd setbold(); /* print out only bold objects now */
242 1.1 cgd
243 1.1 cgd for (lastx=lasty=127, i=d_ymin; i<d_ymax; i++)
244 1.1 cgd for (j=d_xmin; j<d_xmax; j++)
245 1.1 cgd {
246 1.1 cgd if (k=item[j][i])
247 1.1 cgd if (k != OWALL)
248 1.1 cgd if ((know[j][i]) && (mitem[j][i]==0))
249 1.1 cgd if (objnamelist[k]!=' ')
250 1.1 cgd {
251 1.1 cgd if (lasty!=i+1 || lastx!=j)
252 1.1 cgd cursor(lastx=j+1,lasty=i+1); else lastx++;
253 1.1 cgd lprc(objnamelist[k]);
254 1.1 cgd }
255 1.1 cgd }
256 1.1 cgd
257 1.1 cgd resetbold(); if (d_flag) { always=1; botside(); always=1; bot_linex(); }
258 1.1 cgd oldx=99;
259 1.1 cgd d_xmin = 0 , d_xmax = MAXX , d_ymin = 0 , d_ymax = MAXY; /* for limited screen drawing */
260 1.1 cgd }
261 1.1 cgd
262 1.1 cgd /*
264 1.1 cgd showcell(x,y)
265 1.1 cgd
266 1.1 cgd subroutine to display a cell location on the screen
267 1.1 cgd */
268 1.1 cgd showcell(x,y)
269 1.1 cgd int x,y;
270 1.1 cgd {
271 1.1 cgd register int i,j,k,m;
272 1.1 cgd if (c[BLINDCOUNT]) return; /* see nothing if blind */
273 1.1 cgd if (c[AWARENESS]) { minx = x-3; maxx = x+3; miny = y-3; maxy = y+3; }
274 1.1 cgd else { minx = x-1; maxx = x+1; miny = y-1; maxy = y+1; }
275 1.1 cgd
276 1.1 cgd if (minx < 0) minx=0; if (maxx > MAXX-1) maxx = MAXX-1;
277 1.1 cgd if (miny < 0) miny=0; if (maxy > MAXY-1) maxy = MAXY-1;
278 1.1 cgd
279 1.1 cgd for (j=miny; j<=maxy; j++)
280 1.1 cgd for (m=minx; m<=maxx; m++)
281 1.1 cgd if (know[m][j]==0)
282 1.1 cgd {
283 1.1 cgd cursor(m+1,j+1);
284 1.1 cgd x=maxx; while (know[x][j]) --x;
285 1.1 cgd for (i=m; i<=x; i++)
286 1.1 cgd {
287 1.1 cgd if ((k=mitem[i][j]) != 0) lprc(monstnamelist[k]);
288 1.1 cgd else switch(k=item[i][j])
289 1.1 cgd {
290 1.1 cgd case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV:
291 1.1 cgd case OIVDARTRAP: case OIVTRAPDOOR:
292 1.1 cgd lprc(objnamelist[k]); break;
293 1.1 cgd
294 1.1 cgd default: setbold(); lprc(objnamelist[k]); resetbold();
295 1.1 cgd };
296 1.1 cgd know[i][j]=1;
297 1.1 cgd }
298 1.1 cgd m = maxx;
299 1.1 cgd }
300 1.1 cgd }
301 1.1 cgd
302 1.1 cgd /*
303 1.1 cgd this routine shows only the spot that is given it. the spaces around
304 1.1 cgd these coordinated are not shown
305 1.1 cgd used in godirect() in monster.c for missile weapons display
306 1.1 cgd */
307 1.1 cgd show1cell(x,y)
308 1.1 cgd int x,y;
309 1.1 cgd {
310 1.1 cgd if (c[BLINDCOUNT]) return; /* see nothing if blind */
311 1.1 cgd cursor(x+1,y+1);
312 1.1 cgd if ((k=mitem[x][y]) != 0) lprc(monstnamelist[k]);
313 1.1 cgd else switch(k=item[x][y])
314 1.1 cgd {
315 1.1 cgd case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV:
316 1.1 cgd case OIVDARTRAP: case OIVTRAPDOOR:
317 1.1 cgd lprc(objnamelist[k]); break;
318 1.1 cgd
319 1.1 cgd default: setbold(); lprc(objnamelist[k]); resetbold();
320 1.1 cgd };
321 1.1 cgd know[x][y]|=1; /* we end up knowing about it */
322 1.1 cgd }
323 1.1 cgd
324 1.1 cgd /*
325 1.1 cgd showplayer()
326 1.1 cgd
327 1.1 cgd subroutine to show where the player is on the screen
328 1.1 cgd cursor values start from 1 up
329 1.1 cgd */
330 1.1 cgd showplayer()
331 1.1 cgd {
332 1.1 cgd cursor(playerx+1,playery+1);
333 1.1 cgd oldx=playerx; oldy=playery;
334 1.1 cgd }
335 1.1 cgd
336 1.1 cgd /*
337 1.1 cgd moveplayer(dir)
338 1.1 cgd
339 1.1 cgd subroutine to move the player from one room to another
340 1.1 cgd returns 0 if can't move in that direction or hit a monster or on an object
341 1.1 cgd else returns 1
342 1.1 cgd nomove is set to 1 to stop the next move (inadvertent monsters hitting
343 1.1 cgd players when walking into walls) if player walks off screen or into wall
344 1.1 cgd */
345 1.1 cgd short diroffx[] = { 0, 0, 1, 0, -1, 1, -1, 1, -1 };
346 1.1 cgd short diroffy[] = { 0, 1, 0, -1, 0, -1, -1, 1, 1 };
347 1.1 cgd moveplayer(dir)
348 1.1 cgd int dir; /* from = present room # direction = [1-north]
349 1.1 cgd [2-east] [3-south] [4-west] [5-northeast]
350 1.1 cgd [6-northwest] [7-southeast] [8-southwest]
351 1.1 cgd if direction=0, don't move--just show where he is */
352 1.1 cgd {
353 1.1 cgd register int k,m,i,j;
354 1.1 cgd if (c[CONFUSE]) if (c[LEVEL]<rnd(30)) dir=rund(9); /*if confused any dir*/
355 1.1 cgd k = playerx + diroffx[dir]; m = playery + diroffy[dir];
356 1.1 cgd if (k<0 || k>=MAXX || m<0 || m>=MAXY) { nomove=1; return(yrepcount = 0); }
357 1.1 cgd i = item[k][m]; j = mitem[k][m];
358 1.1 cgd if (i==OWALL && c[WTW]==0) { nomove=1; return(yrepcount = 0); } /* hit a wall */
359 1.1 cgd if (k==33 && m==MAXY-1 && level==1)
360 1.1 cgd {
361 1.1 cgd newcavelevel(0); for (k=0; k<MAXX; k++) for (m=0; m<MAXY; m++)
362 1.1 cgd if (item[k][m]==OENTRANCE)
363 1.1 cgd { playerx=k; playery=m; positionplayer(); drawscreen(); return(0); }
364 1.1 cgd }
365 1.1 cgd if (j>0) { hitmonster(k,m); return(yrepcount = 0); } /* hit a monster*/
366 1.1 cgd lastpx = playerx; lastpy = playery;
367 1.1 cgd playerx = k; playery = m;
368 1.1 cgd if (i && i!=OTRAPARROWIV && i!=OIVTELETRAP && i!=OIVDARTRAP && i!=OIVTRAPDOOR) return(yrepcount = 0); else return(1);
369 1.1 cgd }
370 1.1 cgd
371 1.1 cgd /*
373 1.1 cgd * function to show what magic items have been discovered thus far
374 1.1 cgd * enter with -1 for just spells, anything else will give scrolls & potions
375 1.1 cgd */
376 1.1 cgd static int lincount,count;
377 1.1 cgd seemagic(arg)
378 1.1 cgd int arg;
379 1.1 cgd {
380 1.1 cgd register int i,number;
381 1.1 cgd count = lincount = 0; nosignal=1;
382 1.1 cgd
383 1.1 cgd if (arg== -1) /* if display spells while casting one */
384 1.1 cgd {
385 1.1 cgd for (number=i=0; i<SPNUM; i++) if (spelknow[i]) number++;
386 1.1 cgd number = (number+2)/3 + 4; /* # lines needed to display */
387 1.1 cgd cl_up(79,number); cursor(1,1);
388 1.1 cgd }
389 1.1 cgd else
390 1.1 cgd {
391 1.1 cgd resetscroll(); clear();
392 1.1 cgd }
393 1.1 cgd
394 1.1 cgd lprcat("The magic spells you have discovered thus far:\n\n");
395 1.1 cgd for (i=0; i<SPNUM; i++)
396 1.1 cgd if (spelknow[i])
397 1.1 cgd { lprintf("%s %-20s ",spelcode[i],spelname[i]); seepage(); }
398 1.1 cgd
399 1.1 cgd if (arg== -1)
400 1.1 cgd {
401 1.1 cgd seepage(); more(); nosignal=0;
402 1.1 cgd draws(0,MAXX,0,number); return;
403 1.1 cgd }
404 1.1 cgd
405 1.1 cgd lincount += 3; if (count!=0) { count=2; seepage(); }
406 1.1 cgd
407 1.1 cgd lprcat("\nThe magic scrolls you have found to date are:\n\n");
408 1.1 cgd count=0;
409 1.1 cgd for (i=0; i<MAXSCROLL; i++)
410 1.1 cgd if (scrollname[i][0])
411 1.1 cgd if (scrollname[i][1]!=' ')
412 1.1 cgd { lprintf("%-26s",&scrollname[i][1]); seepage(); }
413 1.1 cgd
414 1.1 cgd lincount += 3; if (count!=0) { count=2; seepage(); }
415 1.1 cgd
416 1.1 cgd lprcat("\nThe magic potions you have found to date are:\n\n");
417 1.1 cgd count=0;
418 1.1 cgd for (i=0; i<MAXPOTION; i++)
419 1.1 cgd if (potionname[i][0])
420 1.1 cgd if (potionname[i][1]!=' ')
421 1.1 cgd { lprintf("%-26s",&potionname[i][1]); seepage(); }
422 1.1 cgd
423 1.1 cgd if (lincount!=0) more(); nosignal=0; setscroll(); drawscreen();
424 1.1 cgd }
425 1.1 cgd
426 1.1 cgd /*
427 1.1 cgd * subroutine to paginate the seemagic function
428 1.1 cgd */
429 1.1 cgd seepage()
430 1.1 cgd {
431 1.1 cgd if (++count==3)
432 1.1 cgd {
433 1.1 cgd lincount++; count=0; lprc('\n');
434 1.1 cgd if (lincount>17) { lincount=0; more(); clear(); }
435 }
436 }
437