1 /* $NetBSD: display.c,v 1.8 2008/02/03 19:20:41 dholland Exp $ */
3 /* display.c Larn is copyrighted 1986 by Noah Morgan. */
6 __RCSID("$NetBSD: display.c,v 1.8 2008/02/03 19:20:41 dholland Exp $");
12 #define makecode(_a,_b,_c) (((_a)<<16) + ((_b)<<8) + (_c))
14 static void bot_hpx(void);
15 static void bot_spellx(void);
16 static void botside(void);
17 static void botsub(int, const char *);
18 static void seepage(void);
20 static int minx
, maxx
, miny
, maxy
, k
, m
;
21 static char bot1f
= 0, bot2f
= 0, bot3f
= 0;
22 static char always
= 0;
26 now for the bottom line of the display
51 bot3f
= bot1f
= bot2f
= 0;
69 if (cbak
[SPELLS
] <= -50 || (always
)) {
72 lprintf("Spells:%3ld(%3ld)", (long) c
[SPELLS
], (long) c
[SPELLMAX
]);
74 lprintf("Spells:%3ld(%2ld) ", (long) c
[SPELLS
], (long) c
[SPELLMAX
]);
75 lprintf(" AC: %-3ld WC: %-3ld Level", (long) c
[AC
], (long) c
[WCLASS
]);
77 lprintf("%3ld", (long) c
[LEVEL
]);
79 lprintf(" %-2ld", (long) c
[LEVEL
]);
80 lprintf(" Exp: %-9ld %s\n", (long) c
[EXPERIENCE
], class[c
[LEVEL
] - 1]);
81 lprintf("HP: %3ld(%3ld) STR=%-2ld INT=%-2ld ",
82 (long) c
[HP
], (long) c
[HPMAX
], (long) (c
[STRENGTH
] + c
[STREXTRA
]), (long) c
[INTELLIGENCE
]);
83 lprintf("WIS=%-2ld CON=%-2ld DEX=%-2ld CHA=%-2ld LV:",
84 (long) c
[WISDOM
], (long) c
[CONSTITUTION
], (long) c
[DEXTERITY
], (long) c
[CHARISMA
]);
86 if ((level
== 0) || (wizard
))
91 lprcat(levelname
[level
]);
92 lprintf(" Gold: %-6ld", (long) c
[GOLD
]);
95 c
[TMP
] = c
[STRENGTH
] + c
[STREXTRA
];
96 for (i
= 0; i
< 100; i
++)
100 botsub(makecode(SPELLS
, 8, 18), "%3ld");
101 if (c
[SPELLMAX
] > 99)
102 botsub(makecode(SPELLMAX
, 12, 18), "%3ld)");
104 botsub(makecode(SPELLMAX
, 12, 18), "%2ld) ");
105 botsub(makecode(HP
, 5, 19), "%3ld");
106 botsub(makecode(HPMAX
, 9, 19), "%3ld");
107 botsub(makecode(AC
, 21, 18), "%-3ld");
108 botsub(makecode(WCLASS
, 30, 18), "%-3ld");
109 botsub(makecode(EXPERIENCE
, 49, 18), "%-9ld");
110 if (c
[LEVEL
] != cbak
[LEVEL
]) {
112 lprcat(class[c
[LEVEL
] - 1]);
115 botsub(makecode(LEVEL
, 40, 18), "%3ld");
117 botsub(makecode(LEVEL
, 40, 18), " %-2ld");
118 c
[TMP
] = c
[STRENGTH
] + c
[STREXTRA
];
119 botsub(makecode(TMP
, 18, 19), "%-2ld");
120 botsub(makecode(INTELLIGENCE
, 25, 19), "%-2ld");
121 botsub(makecode(WISDOM
, 32, 19), "%-2ld");
122 botsub(makecode(CONSTITUTION
, 39, 19), "%-2ld");
123 botsub(makecode(DEXTERITY
, 46, 19), "%-2ld");
124 botsub(makecode(CHARISMA
, 53, 19), "%-2ld");
125 if ((level
!= cbak
[CAVELEVEL
]) || (c
[TELEFLAG
] != cbak
[TELEFLAG
])) {
126 if ((level
== 0) || (wizard
))
128 cbak
[TELEFLAG
] = c
[TELEFLAG
];
129 cbak
[CAVELEVEL
] = level
;
134 lprcat(levelname
[level
]);
136 botsub(makecode(GOLD
, 69, 19), "%-6ld");
141 special subroutine to update only the gold number on the bottomlines
147 botsub(makecode(GOLD
, 69, 19), "%-6ld");
148 /* botsub(GOLD,"%-6ld",69,19); */
152 special routine to update hp and level fields on bottom lines
153 called in monster.c hitplayer() and spattack()
158 if (c
[EXPERIENCE
] != cbak
[EXPERIENCE
]) {
162 botsub(makecode(HP
, 5, 19), "%3ld");
166 special routine to update number of spells called from regen()
171 botsub(makecode(SPELLS
, 9, 18), "%2ld");
175 common subroutine for a more economical bottomline()
177 static struct bot_side_def
{
183 { STEALTH
, "stealth"},
184 { UNDEADPRO
, "undead pro" },
185 { SPIRITPRO
, "spirit pro" },
186 { CHARMCOUNT
, "Charm"},
187 { TIMESTOP
, "Time Stop" },
188 { HOLDMONST
, "Hold Monst" },
189 { GIANTSTR
, "Giant Str"},
190 { FIRERESISTANCE
, "Fire Resit" },
191 { DEXCOUNT
, "Dexterity" },
192 { STRCOUNT
, "Strength"},
193 { SCAREMONST
, "Scare" },
194 { HASTESELF
, "Haste Self" },
195 { CANCELLATION
, "Cancel"},
196 { INVISIBILITY
, "Invisible" },
197 { ALTPRO
, "Protect 3" },
198 { PROTECTIONTIME
, "Protect 2"},
206 for (i
= 0; i
< 17; i
++) {
207 idx
= bot_data
[i
].typ
;
208 if ((always
) || (c
[idx
] != cbak
[idx
])) {
209 if ((always
) || (cbak
[idx
] == 0)) {
212 lprcat(bot_data
[i
].string
);
214 } else if (c
[idx
] == 0) {
225 botsub(int idx
, const char *str
)
229 x
= (idx
>> 8) & 0xff;
231 if (c
[idx
] != cbak
[idx
]) {
234 lprintf(str
, (long) c
[idx
]);
239 * subroutine to draw only a section of the screen
240 * only the top section of the screen is updated.
241 * If entire lines are being drawn, then they will be cleared first.
243 /* for limited screen drawing */
244 static int d_xmin
= 0, d_xmax
= MAXX
, d_ymin
= 0, d_ymax
= MAXY
;
247 draws(xmin
, xmax
, ymin
, ymax
)
248 int xmin
, xmax
, ymin
, ymax
;
251 if (xmin
== 0 && xmax
== MAXX
) { /* clear section of screen as
256 for (i
= ymin
; i
< ymin
; i
++)
263 d_ymax
= ymax
; /* for limited screen drawing */
265 if (xmin
<= 0 && xmax
== MAXX
) { /* draw stuff on right side
266 * of screen as needed */
267 for (i
= ymin
; i
< ymax
; i
++) {
268 idx
= bot_data
[i
].typ
;
271 lprcat(bot_data
[i
].string
);
281 subroutine to redraw the whole screen as the player knows it
283 u_char screen
[MAXX
][MAXY
]; /* template for the screen */
284 static u_char d_flag
;
289 int lastx
, lasty
; /* variables used to optimize the
291 if (d_xmin
== 0 && d_xmax
== MAXX
&& d_ymin
== 0 && d_ymax
== MAXY
) {
293 clear(); /* clear the screen */
299 d_xmin
= 0; /* d_xmin=-1 means display all without
302 for (i
= d_ymin
; i
< d_ymax
; i
++)
303 for (j
= d_xmin
; j
< d_xmax
; j
++)
306 else if ((kk
= mitem
[j
][i
]) != 0)
307 screen
[j
][i
] = monstnamelist
[kk
];
308 else if ((kk
= item
[j
][i
]) == OWALL
)
313 for (i
= d_ymin
; i
< d_ymax
; i
++) {
315 while ((screen
[j
][i
] == ' ') && (j
< d_xmax
))
319 m
= d_xmin
; /* don't search backwards if blank
321 else { /* search backwards for end of line */
323 while ((screen
[m
][i
] == ' ') && (m
> d_xmin
))
326 cursor(j
+ 1, i
+ 1);
332 for (kk
= j
; kk
<= j
+ 3; kk
++)
333 if (screen
[kk
][i
] != ' ')
336 while (screen
[j
][i
] == ' ' && j
<= m
)
338 cursor(j
+ 1, i
+ 1);
341 lprc(screen
[j
++][i
]);
344 setbold(); /* print out only bold objects now */
346 for (lastx
= lasty
= 127, i
= d_ymin
; i
< d_ymax
; i
++)
347 for (j
= d_xmin
; j
< d_xmax
; j
++) {
348 if ((kk
= item
[j
][i
]) != 0)
350 if ((know
[j
][i
]) && (mitem
[j
][i
] == 0))
351 if (objnamelist
[kk
] != ' ') {
352 if (lasty
!= i
+ 1 || lastx
!= j
)
353 cursor(lastx
= j
+ 1, lasty
= i
+ 1);
356 lprc(objnamelist
[kk
]);
368 d_xmin
= 0, d_xmax
= MAXX
, d_ymin
= 0, d_ymax
= MAXY
; /* for limited screen
376 subroutine to display a cell location on the screen
384 return; /* see nothing if blind */
406 for (j
= miny
; j
<= maxy
; j
++)
407 for (mm
= minx
; mm
<= maxx
; mm
++)
408 if (know
[mm
][j
] == 0) {
409 cursor(mm
+ 1, j
+ 1);
413 for (i
= mm
; i
<= x
; i
++) {
414 if ((kk
= mitem
[i
][j
]) != 0)
415 lprc(monstnamelist
[kk
]);
417 switch (kk
= item
[i
][j
]) {
424 lprc(objnamelist
[kk
]);
429 lprc(objnamelist
[kk
]);
439 this routine shows only the spot that is given it. the spaces around
440 these coordinated are not shown
441 used in godirect() in monster.c for missile weapons display
448 return; /* see nothing if blind */
449 cursor(x
+ 1, y
+ 1);
450 if ((k
= mitem
[x
][y
]) != 0)
451 lprc(monstnamelist
[k
]);
453 switch (k
= item
[x
][y
]) {
460 lprc(objnamelist
[k
]);
465 lprc(objnamelist
[k
]);
468 know
[x
][y
] |= 1; /* we end up knowing about it */
474 subroutine to show where the player is on the screen
475 cursor values start from 1 up
480 cursor(playerx
+ 1, playery
+ 1);
488 subroutine to move the player from one room to another
489 returns 0 if can't move in that direction or hit a monster or on an object
491 nomove is set to 1 to stop the next move (inadvertent monsters hitting
492 players when walking into walls) if player walks off screen or into wall
494 short diroffx
[] = {0, 0, 1, 0, -1, 1, -1, 1, -1};
495 short diroffy
[] = {0, 1, 0, -1, 0, -1, -1, 1, 1};
498 int dir
; /* from = present room # direction =
499 * [1-north] [2-east] [3-south] [4-west]
500 * [5-northeast] [6-northwest] [7-southeast]
501 * [8-southwest] if direction=0, don't
502 * move--just show where he is */
506 if (c
[LEVEL
] < rnd(30))
507 dir
= rund(9); /* if confused any dir */
508 kk
= playerx
+ diroffx
[dir
];
509 mm
= playery
+ diroffy
[dir
];
510 if (kk
< 0 || kk
>= MAXX
|| mm
< 0 || mm
>= MAXY
) {
512 return (yrepcount
= 0);
516 if (i
== OWALL
&& c
[WTW
] == 0) {
518 return (yrepcount
= 0);
520 if (kk
== 33 && mm
== MAXY
- 1 && level
== 1) {
522 for (kk
= 0; kk
< MAXX
; kk
++)
523 for (mm
= 0; mm
< MAXY
; mm
++)
524 if (item
[kk
][mm
] == OENTRANCE
) {
534 return (yrepcount
= 0);
535 } /* hit a monster */
540 if (i
&& i
!= OTRAPARROWIV
&& i
!= OIVTELETRAP
&& i
!= OIVDARTRAP
&& i
!= OIVTRAPDOOR
)
541 return (yrepcount
= 0);
548 * function to show what magic items have been discovered thus far
549 * enter with -1 for just spells, anything else will give scrolls & potions
551 static int lincount
, count
;
557 count
= lincount
= 0;
560 if (arg
== -1) { /* if display spells while casting one */
561 for (number
= i
= 0; i
< SPNUM
; i
++)
564 number
= (number
+ 2) / 3 + 4; /* # lines needed to display */
572 lprcat("The magic spells you have discovered thus far:\n\n");
573 for (i
= 0; i
< SPNUM
; i
++)
575 lprintf("%s %-20s ", spelcode
[i
], spelname
[i
]);
582 draws(0, MAXX
, 0, number
);
590 lprcat("\nThe magic scrolls you have found to date are:\n\n");
592 for (i
= 0; i
< MAXSCROLL
; i
++)
593 if (scrollname
[i
][0])
594 if (scrollname
[i
][1] != ' ') {
595 lprintf("%-26s", &scrollname
[i
][1]);
603 lprcat("\nThe magic potions you have found to date are:\n\n");
605 for (i
= 0; i
< MAXPOTION
; i
++)
606 if (potionname
[i
][0])
607 if (potionname
[i
][1] != ' ') {
608 lprintf("%-26s", &potionname
[i
][1]);
619 * subroutine to paginate the seemagic function