xref: /csrg-svn/games/rogue/room.c (revision 60842)
132689Sbostic /*
2*60842Sbostic  * Copyright (c) 1988, 1993
3*60842Sbostic  *	The Regents of the University of California.  All rights reserved.
436704Sbostic  *
536704Sbostic  * This code is derived from software contributed to Berkeley by
636704Sbostic  * Timothy C. Stoehr.
736704Sbostic  *
842603Sbostic  * %sccs.include.redist.c%
936704Sbostic  */
1036704Sbostic 
1136704Sbostic #ifndef lint
12*60842Sbostic static char sccsid[] = "@(#)room.c	8.1 (Berkeley) 05/31/93";
1336704Sbostic #endif /* not lint */
1436704Sbostic 
1536704Sbostic /*
1632689Sbostic  * room.c
1732689Sbostic  *
1832689Sbostic  * This source herein may be modified and/or distributed by anybody who
1932689Sbostic  * so desires, with the following restrictions:
2032689Sbostic  *    1.)  No portion of this notice shall be removed.
2132689Sbostic  *    2.)  Credit shall not be taken for the creation of this source.
2232689Sbostic  *    3.)  This code is not to be traded, sold, or used for personal
2332689Sbostic  *         gain or profit.
2432689Sbostic  *
2532689Sbostic  */
2632689Sbostic 
2732689Sbostic #include "rogue.h"
2832689Sbostic 
2932689Sbostic room rooms[MAXROOMS];
3032689Sbostic boolean rooms_visited[MAXROOMS];
3132689Sbostic 
3232689Sbostic extern short blind;
3332689Sbostic extern boolean detect_monster, jump, passgo, no_skull, ask_quit;
3432689Sbostic extern char *nick_name, *fruit, *save_file, *press_space;
3532689Sbostic 
3632689Sbostic #define NOPTS 7
3732689Sbostic 
3832689Sbostic struct option {
3932689Sbostic 	char *prompt;
4032689Sbostic 	boolean is_bool;
4132689Sbostic 	char **strval;
4232689Sbostic 	boolean *bval;
4332689Sbostic } options[NOPTS] = {
4432689Sbostic 	{
4532689Sbostic 		"Show position only at end of run (\"jump\"): ",
4632689Sbostic 		1, (char **) 0, &jump
4732689Sbostic 	},
4832689Sbostic 	{
4932689Sbostic 		"Follow turnings in passageways (\"passgo\"): ",
5032689Sbostic 		1, (char **) 0, &passgo
5132689Sbostic 	},
5232689Sbostic 	{
5332689Sbostic 		"Don't print skull when killed (\"noskull\" or \"notombstone\"): ",
5432689Sbostic 		1, (char **) 0, &no_skull
5532689Sbostic 	},
5632689Sbostic 	{
5732689Sbostic 		"Ask player before saying 'Okay, bye-bye!' (\"askquit\"): ",
5832689Sbostic 		1, (char **) 0, &ask_quit
5932689Sbostic 	},
6032689Sbostic 	{
6132689Sbostic 		"Name (\"name\"): ",
6232689Sbostic 		0, &nick_name
6332689Sbostic 	},
6432689Sbostic 	{
6532689Sbostic 		"Fruit (\"fruit\"): ",
6632689Sbostic 		0, &fruit
6732689Sbostic 	},
6832689Sbostic 	{
6932689Sbostic 		"Save file (\"file\"): ",
7032689Sbostic 		0, &save_file
7132689Sbostic 	}
7232689Sbostic };
7332689Sbostic 
light_up_room(rn)7432689Sbostic light_up_room(rn)
7532689Sbostic int rn;
7632689Sbostic {
7732689Sbostic 	short i, j;
7832689Sbostic 
7932689Sbostic 	if (!blind) {
8032689Sbostic 		for (i = rooms[rn].top_row;
8132689Sbostic 			i <= rooms[rn].bottom_row; i++) {
8232689Sbostic 			for (j = rooms[rn].left_col;
8332689Sbostic 				j <= rooms[rn].right_col; j++) {
8432689Sbostic 				if (dungeon[i][j] & MONSTER) {
8532689Sbostic 					object *monster;
8632689Sbostic 
8732689Sbostic 					if (monster = object_at(&level_monsters, i, j)) {
8832689Sbostic 						dungeon[monster->row][monster->col] &= (~MONSTER);
8932689Sbostic 						monster->trail_char =
9032689Sbostic 							get_dungeon_char(monster->row, monster->col);
9132689Sbostic 						dungeon[monster->row][monster->col] |= MONSTER;
9232689Sbostic 					}
9332689Sbostic 				}
9432689Sbostic 				mvaddch(i, j, get_dungeon_char(i, j));
9532689Sbostic 			}
9632689Sbostic 		}
9732689Sbostic 		mvaddch(rogue.row, rogue.col, rogue.fchar);
9832689Sbostic 	}
9932689Sbostic }
10032689Sbostic 
light_passage(row,col)10132689Sbostic light_passage(row, col)
10232689Sbostic {
10332689Sbostic 	short i, j, i_end, j_end;
10432689Sbostic 
10532689Sbostic 	if (blind) {
10632689Sbostic 		return;
10732689Sbostic 	}
10832689Sbostic 	i_end = (row < (DROWS-2)) ? 1 : 0;
10932689Sbostic 	j_end = (col < (DCOLS-1)) ? 1 : 0;
11032689Sbostic 
11132689Sbostic 	for (i = ((row > MIN_ROW) ? -1 : 0); i <= i_end; i++) {
11232689Sbostic 		for (j = ((col > 0) ? -1 : 0); j <= j_end; j++) {
11332689Sbostic 			if (can_move(row, col, row+i, col+j)) {
11432689Sbostic 				mvaddch(row+i, col+j, get_dungeon_char(row+i, col+j));
11532689Sbostic 			}
11632689Sbostic 		}
11732689Sbostic 	}
11832689Sbostic }
11932689Sbostic 
darken_room(rn)12032689Sbostic darken_room(rn)
12132689Sbostic short rn;
12232689Sbostic {
12332689Sbostic 	short i, j;
12432689Sbostic 
12532689Sbostic 	for (i = rooms[rn].top_row + 1; i < rooms[rn].bottom_row; i++) {
12632689Sbostic 		for (j = rooms[rn].left_col + 1; j < rooms[rn].right_col; j++) {
12732689Sbostic 			if (blind) {
12832689Sbostic 				mvaddch(i, j, ' ');
12932689Sbostic 			} else {
13032689Sbostic 				if (!(dungeon[i][j] & (OBJECT | STAIRS)) &&
13132689Sbostic 					!(detect_monster && (dungeon[i][j] & MONSTER))) {
13232689Sbostic 					if (!imitating(i, j)) {
13332689Sbostic 						mvaddch(i, j, ' ');
13432689Sbostic 					}
13532689Sbostic 					if ((dungeon[i][j] & TRAP) && (!(dungeon[i][j] & HIDDEN))) {
13632689Sbostic 						mvaddch(i, j, '^');
13732689Sbostic 					}
13832689Sbostic 				}
13932689Sbostic 			}
14032689Sbostic 		}
14132689Sbostic 	}
14232689Sbostic }
14332689Sbostic 
get_dungeon_char(row,col)14432689Sbostic get_dungeon_char(row, col)
14532689Sbostic register row, col;
14632689Sbostic {
14732689Sbostic 	register unsigned short mask = dungeon[row][col];
14832689Sbostic 
14932689Sbostic 	if (mask & MONSTER) {
15032689Sbostic 		return(gmc_row_col(row, col));
15132689Sbostic 	}
15232689Sbostic 	if (mask & OBJECT) {
15332689Sbostic 		object *obj;
15432689Sbostic 
15532689Sbostic 		obj = object_at(&level_objects, row, col);
15632689Sbostic 		return(get_mask_char(obj->what_is));
15732689Sbostic 	}
15832689Sbostic 	if (mask & (TUNNEL | STAIRS | HORWALL | VERTWALL | FLOOR | DOOR)) {
15932689Sbostic 		if ((mask & (TUNNEL| STAIRS)) && (!(mask & HIDDEN))) {
16032689Sbostic 			return(((mask & STAIRS) ? '%' : '#'));
16132689Sbostic 		}
16232689Sbostic 		if (mask & HORWALL) {
16332689Sbostic 			return('-');
16432689Sbostic 		}
16532689Sbostic 		if (mask & VERTWALL) {
16632689Sbostic 			return('|');
16732689Sbostic 		}
16832689Sbostic 		if (mask & FLOOR) {
16932689Sbostic 			if (mask & TRAP) {
17032689Sbostic 				if (!(dungeon[row][col] & HIDDEN)) {
17132689Sbostic 					return('^');
17232689Sbostic 				}
17332689Sbostic 			}
17432689Sbostic 			return('.');
17532689Sbostic 		}
17632689Sbostic 		if (mask & DOOR) {
17732689Sbostic 			if (mask & HIDDEN) {
17832689Sbostic 				if (((col > 0) && (dungeon[row][col-1] & HORWALL)) ||
17932689Sbostic 					((col < (DCOLS-1)) && (dungeon[row][col+1] & HORWALL))) {
18032689Sbostic 					return('-');
18132689Sbostic 				} else {
18232689Sbostic 					return('|');
18332689Sbostic 				}
18432689Sbostic 			} else {
18532689Sbostic 				return('+');
18632689Sbostic 			}
18732689Sbostic 		}
18832689Sbostic 	}
18932689Sbostic 	return(' ');
19032689Sbostic }
19132689Sbostic 
get_mask_char(mask)19232689Sbostic get_mask_char(mask)
19332689Sbostic register unsigned short mask;
19432689Sbostic {
19532689Sbostic 		switch(mask) {
19632689Sbostic 		case SCROL:
19732689Sbostic 			return('?');
19832689Sbostic 		case POTION:
19932689Sbostic 			return('!');
20032689Sbostic 		case GOLD:
20132689Sbostic 			return('*');
20232689Sbostic 		case FOOD:
20332689Sbostic 			return(':');
20432689Sbostic 		case WAND:
20532689Sbostic 			return('/');
20632689Sbostic 		case ARMOR:
20732689Sbostic 			return(']');
20832689Sbostic 		case WEAPON:
20932689Sbostic 			return(')');
21032689Sbostic 		case RING:
21132689Sbostic 			return('=');
21232689Sbostic 		case AMULET:
21332689Sbostic 			return(',');
21432689Sbostic 		default:
21532689Sbostic 			return('~');	/* unknown, something is wrong */
21632689Sbostic 		}
21732689Sbostic }
21832689Sbostic 
gr_row_col(row,col,mask)21932689Sbostic gr_row_col(row, col, mask)
22032689Sbostic short *row, *col;
22132689Sbostic unsigned short mask;
22232689Sbostic {
22332689Sbostic 	short rn;
22432689Sbostic 	short r, c;
22532689Sbostic 
22632689Sbostic 	do {
22732689Sbostic 		r = get_rand(MIN_ROW, DROWS-2);
22832689Sbostic 		c = get_rand(0, DCOLS-1);
22932689Sbostic 		rn = get_room_number(r, c);
23032689Sbostic 	} while ((rn == NO_ROOM) ||
23132689Sbostic 		(!(dungeon[r][c] & mask)) ||
23232689Sbostic 		(dungeon[r][c] & (~mask)) ||
23332689Sbostic 		(!(rooms[rn].is_room & (R_ROOM | R_MAZE))) ||
23432689Sbostic 		((r == rogue.row) && (c == rogue.col)));
23532689Sbostic 
23632689Sbostic 	*row = r;
23732689Sbostic 	*col = c;
23832689Sbostic }
23932689Sbostic 
gr_room()24032689Sbostic gr_room()
24132689Sbostic {
24232689Sbostic 	short i;
24332689Sbostic 
24432689Sbostic 	do {
24532689Sbostic 		i = get_rand(0, MAXROOMS-1);
24632689Sbostic 	} while (!(rooms[i].is_room & (R_ROOM | R_MAZE)));
24732689Sbostic 
24832689Sbostic 	return(i);
24932689Sbostic }
25032689Sbostic 
party_objects(rn)25132689Sbostic party_objects(rn)
25232689Sbostic {
25332689Sbostic 	short i, j, nf = 0;
25432689Sbostic 	object *obj;
25532689Sbostic 	short n, N, row, col;
25632689Sbostic 	boolean found;
25732689Sbostic 
25832689Sbostic 	N = ((rooms[rn].bottom_row - rooms[rn].top_row) - 1) *
25932689Sbostic 		((rooms[rn].right_col - rooms[rn].left_col) - 1);
26032689Sbostic 	n =  get_rand(5, 10);
26132689Sbostic 	if (n > N) {
26232689Sbostic 		n = N - 2;
26332689Sbostic 	}
26432689Sbostic 	for (i = 0; i < n; i++) {
26532689Sbostic 		for (j = found = 0; ((!found) && (j < 250)); j++) {
26632689Sbostic 			row = get_rand(rooms[rn].top_row+1,
26732689Sbostic 					   rooms[rn].bottom_row-1);
26832689Sbostic 			col = get_rand(rooms[rn].left_col+1,
26932689Sbostic 					   rooms[rn].right_col-1);
27032689Sbostic 			if ((dungeon[row][col] == FLOOR) || (dungeon[row][col] == TUNNEL)) {
27132689Sbostic 				found = 1;
27232689Sbostic 			}
27332689Sbostic 		}
27432689Sbostic 		if (found) {
27532689Sbostic 			obj = gr_object();
27632689Sbostic 			place_at(obj, row, col);
27732689Sbostic 			nf++;
27832689Sbostic 		}
27932689Sbostic 	}
28032689Sbostic 	return(nf);
28132689Sbostic }
28232689Sbostic 
get_room_number(row,col)28332689Sbostic get_room_number(row, col)
28432689Sbostic register row, col;
28532689Sbostic {
28632689Sbostic 	short i;
28732689Sbostic 
28832689Sbostic 	for (i = 0; i < MAXROOMS; i++) {
28932689Sbostic 		if ((row >= rooms[i].top_row) && (row <= rooms[i].bottom_row) &&
29032689Sbostic 			(col >= rooms[i].left_col) && (col <= rooms[i].right_col)) {
29132689Sbostic 			return(i);
29232689Sbostic 		}
29332689Sbostic 	}
29432689Sbostic 	return(NO_ROOM);
29532689Sbostic }
29632689Sbostic 
is_all_connected()29732689Sbostic is_all_connected()
29832689Sbostic {
29932689Sbostic 	short i, starting_room;
30032689Sbostic 
30132689Sbostic 	for (i = 0; i < MAXROOMS; i++) {
30232689Sbostic 		rooms_visited[i] = 0;
30332689Sbostic 		if (rooms[i].is_room & (R_ROOM | R_MAZE)) {
30432689Sbostic 			starting_room = i;
30532689Sbostic 		}
30632689Sbostic 	}
30732689Sbostic 
30832689Sbostic 	visit_rooms(starting_room);
30932689Sbostic 
31032689Sbostic 	for (i = 0; i < MAXROOMS; i++) {
31132689Sbostic 		if ((rooms[i].is_room & (R_ROOM | R_MAZE)) && (!rooms_visited[i])) {
31232689Sbostic 			return(0);
31332689Sbostic 		}
31432689Sbostic 	}
31532689Sbostic 	return(1);
31632689Sbostic }
31732689Sbostic 
visit_rooms(rn)31832689Sbostic visit_rooms(rn)
31932689Sbostic int rn;
32032689Sbostic {
32132689Sbostic 	short i;
32232689Sbostic 	short oth_rn;
32332689Sbostic 
32432689Sbostic 	rooms_visited[rn] = 1;
32532689Sbostic 
32632689Sbostic 	for (i = 0; i < 4; i++) {
32732689Sbostic 		oth_rn = rooms[rn].doors[i].oth_room;
32832689Sbostic 		if ((oth_rn >= 0) && (!rooms_visited[oth_rn])) {
32932689Sbostic 			visit_rooms(oth_rn);
33032689Sbostic 		}
33132689Sbostic 	}
33232689Sbostic }
33332689Sbostic 
draw_magic_map()33432689Sbostic draw_magic_map()
33532689Sbostic {
33632689Sbostic 	short i, j, ch, och;
33732689Sbostic 	unsigned short mask = (HORWALL | VERTWALL | DOOR | TUNNEL | TRAP | STAIRS |
33832689Sbostic 			MONSTER);
33932689Sbostic 	unsigned short s;
34032689Sbostic 
34132689Sbostic 	for (i = 0; i < DROWS; i++) {
34232689Sbostic 		for (j = 0; j < DCOLS; j++) {
34332689Sbostic 			s = dungeon[i][j];
34432689Sbostic 			if (s & mask) {
34532689Sbostic 				if (((ch = mvinch(i, j)) == ' ') ||
34632689Sbostic 					((ch >= 'A') && (ch <= 'Z')) || (s & (TRAP | HIDDEN))) {
34732689Sbostic 					och = ch;
34832689Sbostic 					dungeon[i][j] &= (~HIDDEN);
34932689Sbostic 					if (s & HORWALL) {
35032689Sbostic 						ch = '-';
35132689Sbostic 					} else if (s & VERTWALL) {
35232689Sbostic 						ch = '|';
35332689Sbostic 					} else if (s & DOOR) {
35432689Sbostic 						ch = '+';
35532689Sbostic 					} else if (s & TRAP) {
35632689Sbostic 						ch = '^';
35732689Sbostic 					} else if (s & STAIRS) {
35832689Sbostic 						ch = '%';
35932689Sbostic 					} else if (s & TUNNEL) {
36032689Sbostic 						ch = '#';
36132689Sbostic 					} else {
36232689Sbostic 						continue;
36332689Sbostic 					}
36432689Sbostic 					if ((!(s & MONSTER)) || (och == ' ')) {
36532689Sbostic 						addch(ch);
36632689Sbostic 					}
36732689Sbostic 					if (s & MONSTER) {
36832689Sbostic 						object *monster;
36932689Sbostic 
37032689Sbostic 						if (monster = object_at(&level_monsters, i, j)) {
37132689Sbostic 							monster->trail_char = ch;
37232689Sbostic 						}
37332689Sbostic 					}
37432689Sbostic 				}
37532689Sbostic 			}
37632689Sbostic 		}
37732689Sbostic 	}
37832689Sbostic }
37932689Sbostic 
dr_course(monster,entering,row,col)38032689Sbostic dr_course(monster, entering, row, col)
38132689Sbostic object *monster;
38232689Sbostic boolean entering;
38332689Sbostic short row, col;
38432689Sbostic {
38532689Sbostic 	short i, j, k, rn;
38632689Sbostic 	short r, rr;
38732689Sbostic 
38832689Sbostic 	monster->row = row;
38932689Sbostic 	monster->col = col;
39032689Sbostic 
39132689Sbostic 	if (mon_sees(monster, rogue.row, rogue.col)) {
39232689Sbostic 		monster->trow = NO_ROOM;
39332689Sbostic 		return;
39432689Sbostic 	}
39532689Sbostic 	rn = get_room_number(row, col);
39632689Sbostic 
39732689Sbostic 	if (entering) {		/* entering room */
39832689Sbostic 		/* look for door to some other room */
39932689Sbostic 		r = get_rand(0, MAXROOMS-1);
40032689Sbostic 		for (i = 0; i < MAXROOMS; i++) {
40132689Sbostic 			rr = (r + i) % MAXROOMS;
40232689Sbostic 			if ((!(rooms[rr].is_room & (R_ROOM | R_MAZE))) || (rr == rn)) {
40332689Sbostic 				continue;
40432689Sbostic 			}
40532689Sbostic 			for (k = 0; k < 4; k++) {
40632689Sbostic 				if (rooms[rr].doors[k].oth_room == rn) {
40732689Sbostic 					monster->trow = rooms[rr].doors[k].oth_row;
40832689Sbostic 					monster->tcol = rooms[rr].doors[k].oth_col;
40932689Sbostic 					if ((monster->trow == row) &&
41032689Sbostic 						(monster->tcol == col)) {
41132689Sbostic 						continue;
41232689Sbostic 					}
41332689Sbostic 					return;
41432689Sbostic 				}
41532689Sbostic 			}
41632689Sbostic 		}
41732689Sbostic 		/* look for door to dead end */
41832689Sbostic 		for (i = rooms[rn].top_row; i <= rooms[rn].bottom_row; i++) {
41932689Sbostic 			for (j = rooms[rn].left_col; j <= rooms[rn].right_col; j++) {
42032689Sbostic 				if ((i != monster->row) && (j != monster->col) &&
42132689Sbostic 					(dungeon[i][j] & DOOR)) {
42232689Sbostic 					monster->trow = i;
42332689Sbostic 					monster->tcol = j;
42432689Sbostic 					return;
42532689Sbostic 				}
42632689Sbostic 			}
42732689Sbostic 		}
42832689Sbostic 		/* return monster to room that he came from */
42932689Sbostic 		for (i = 0; i < MAXROOMS; i++) {
43032689Sbostic 			for (j = 0; j < 4; j++) {
43132689Sbostic 				if (rooms[i].doors[j].oth_room == rn) {
43232689Sbostic 					for (k = 0; k < 4; k++) {
43332689Sbostic 						if (rooms[rn].doors[k].oth_room == i) {
43432689Sbostic 							monster->trow = rooms[rn].doors[k].oth_row;
43532689Sbostic 							monster->tcol = rooms[rn].doors[k].oth_col;
43632689Sbostic 							return;
43732689Sbostic 						}
43832689Sbostic 					}
43932689Sbostic 				}
44032689Sbostic 			}
44132689Sbostic 		}
44232689Sbostic 		/* no place to send monster */
44332689Sbostic 		monster->trow = NO_ROOM;
44432689Sbostic 	} else {		/* exiting room */
44532689Sbostic 		if (!get_oth_room(rn, &row, &col)) {
44632689Sbostic 			monster->trow = NO_ROOM;
44732689Sbostic 		} else {
44832689Sbostic 			monster->trow = row;
44932689Sbostic 			monster->tcol = col;
45032689Sbostic 		}
45132689Sbostic 	}
45232689Sbostic }
45332689Sbostic 
get_oth_room(rn,row,col)45432689Sbostic get_oth_room(rn, row, col)
45532689Sbostic short rn, *row, *col;
45632689Sbostic {
45732689Sbostic 	short d = -1;
45832689Sbostic 
45932689Sbostic 	if (*row == rooms[rn].top_row) {
46032689Sbostic 		d = UPWARD/2;
46132689Sbostic 	} else if (*row == rooms[rn].bottom_row) {
46232689Sbostic 		d = DOWN/2;
46332689Sbostic 	} else if (*col == rooms[rn].left_col) {
46432689Sbostic 		d = LEFT/2;
46532689Sbostic 	} else if (*col == rooms[rn].right_col) {
46632689Sbostic 		d = RIGHT/2;
46732689Sbostic 	}
46832689Sbostic 	if ((d != -1) && (rooms[rn].doors[d].oth_room >= 0)) {
46932689Sbostic 		*row = rooms[rn].doors[d].oth_row;
47032689Sbostic 		*col = rooms[rn].doors[d].oth_col;
47132689Sbostic 		return(1);
47232689Sbostic 	}
47332689Sbostic 	return(0);
47432689Sbostic }
47532689Sbostic 
edit_opts()47632689Sbostic edit_opts()
47732689Sbostic {
47832689Sbostic 	char save[NOPTS+1][DCOLS];
47932689Sbostic 	short i, j;
48032689Sbostic 	short ch;
48132689Sbostic 	boolean done = 0;
48232689Sbostic 	char buf[MAX_OPT_LEN + 2];
48332689Sbostic 
48432689Sbostic 	for (i = 0; i < NOPTS+1; i++) {
48532689Sbostic 		for (j = 0; j < DCOLS; j++) {
48632689Sbostic 			save[i][j] = mvinch(i, j);
48732689Sbostic 		}
48832689Sbostic 		if (i < NOPTS) {
48932689Sbostic 			opt_show(i);
49032689Sbostic 		}
49132689Sbostic 	}
49232689Sbostic 	opt_go(0);
49332689Sbostic 	i = 0;
49432689Sbostic 
49532689Sbostic 	while (!done) {
49632689Sbostic 		refresh();
49732689Sbostic 		ch = rgetchar();
49832689Sbostic CH:
49932689Sbostic 		switch(ch) {
50032689Sbostic 		case '\033':
50132689Sbostic 			done = 1;
50232689Sbostic 			break;
50332689Sbostic 		case '\012':
50432689Sbostic 		case '\015':
50532689Sbostic 			if (i == (NOPTS - 1)) {
50632689Sbostic 				mvaddstr(NOPTS, 0, press_space);
50732689Sbostic 				refresh();
50832689Sbostic 				wait_for_ack();
50932689Sbostic 				done = 1;
51032689Sbostic 			} else {
51132689Sbostic 				i++;
51232689Sbostic 				opt_go(i);
51332689Sbostic 			}
51432689Sbostic 			break;
51532689Sbostic 		case '-':
51632689Sbostic 			if (i > 0) {
51732689Sbostic 				opt_go(--i);
51832689Sbostic 			} else {
51932689Sbostic 				sound_bell();
52032689Sbostic 			}
52132689Sbostic 			break;
52232689Sbostic 		case 't':
52332689Sbostic 		case 'T':
52432689Sbostic 		case 'f':
52532689Sbostic 		case 'F':
52632689Sbostic 			if (options[i].is_bool) {
52732689Sbostic 				*(options[i].bval) = (((ch == 't') || (ch == 'T')) ? 1 : 0);
52832689Sbostic 				opt_show(i);
52932689Sbostic 				opt_go(++i);
53032689Sbostic 				break;
53132689Sbostic 			}
53232689Sbostic 		default:
53332689Sbostic 			if (options[i].is_bool) {
53432689Sbostic 				sound_bell();
53532689Sbostic 				break;
53632689Sbostic 			}
53732689Sbostic 			j = 0;
53832689Sbostic 			if ((ch == '\010') || ((ch >= ' ') && (ch <= '~'))) {
53932689Sbostic 				opt_erase(i);
54032689Sbostic 				do {
54132689Sbostic 					if ((ch >= ' ') && (ch <= '~') && (j < MAX_OPT_LEN)) {
54232689Sbostic 						buf[j++] = ch;
54332689Sbostic 						buf[j] = '\0';
54432689Sbostic 						addch(ch);
54532689Sbostic 					} else if ((ch == '\010') && (j > 0)) {
54632689Sbostic 						buf[--j] = '\0';
54732689Sbostic 						move(i, j + strlen(options[i].prompt));
54832689Sbostic 						addch(' ');
54932689Sbostic 						move(i, j + strlen(options[i].prompt));
55032689Sbostic 					}
55132689Sbostic 					refresh();
55232689Sbostic 					ch = rgetchar();
55332689Sbostic 				} while ((ch != '\012') && (ch != '\015') && (ch != '\033'));
55432689Sbostic 				if (j != 0) {
55532689Sbostic 					(void) strcpy(*(options[i].strval), buf);
55632689Sbostic 				}
55732689Sbostic 				opt_show(i);
55832689Sbostic 				goto CH;
55932689Sbostic 			} else {
56032689Sbostic 				sound_bell();
56132689Sbostic 			}
56232689Sbostic 			break;
56332689Sbostic 		}
56432689Sbostic 	}
56532689Sbostic 
56632689Sbostic 	for (i = 0; i < NOPTS+1; i++) {
56732689Sbostic 		move(i, 0);
56832689Sbostic 		for (j = 0; j < DCOLS; j++) {
56932689Sbostic 			addch(save[i][j]);
57032689Sbostic 		}
57132689Sbostic 	}
57232689Sbostic }
57332689Sbostic 
opt_show(i)57432689Sbostic opt_show(i)
57532689Sbostic int i;
57632689Sbostic {
57732689Sbostic 	char *s;
57832689Sbostic 	struct option *opt = &options[i];
57932689Sbostic 
58032689Sbostic 	opt_erase(i);
58132689Sbostic 
58232689Sbostic 	if (opt->is_bool) {
58332689Sbostic 		s = *(opt->bval) ? "True" : "False";
58432689Sbostic 	} else {
58532689Sbostic 		s = *(opt->strval);
58632689Sbostic 	}
58732689Sbostic 	addstr(s);
58832689Sbostic }
58932689Sbostic 
opt_erase(i)59032689Sbostic opt_erase(i)
59132689Sbostic int i;
59232689Sbostic {
59332689Sbostic 	struct option *opt = &options[i];
59432689Sbostic 
59532689Sbostic 	mvaddstr(i, 0, opt->prompt);
59632689Sbostic 	clrtoeol();
59732689Sbostic }
59832689Sbostic 
opt_go(i)59932689Sbostic opt_go(i)
60032689Sbostic int i;
60132689Sbostic {
60232689Sbostic 	move(i, strlen(options[i].prompt));
60332689Sbostic }
60432689Sbostic 
do_shell()60532689Sbostic do_shell()
60632689Sbostic {
60732689Sbostic #ifdef UNIX
60832689Sbostic 	char *sh;
60932689Sbostic 
61032689Sbostic 	md_ignore_signals();
61132689Sbostic 	if (!(sh = md_getenv("SHELL"))) {
61232689Sbostic 		sh = "/bin/sh";
61332689Sbostic 	}
61432689Sbostic 	move(LINES-1, 0);
61532689Sbostic 	refresh();
61632689Sbostic 	stop_window();
61732689Sbostic 	printf("\nCreating new shell...\n");
61832689Sbostic 	md_shell(sh);
61932689Sbostic 	start_window();
62032689Sbostic 	wrefresh(curscr);
62132689Sbostic 	md_heed_signals();
62232689Sbostic #endif
62332689Sbostic }
624