xref: /csrg-svn/games/rogue/curses.c (revision 32689)
1*32689Sbostic /*
2*32689Sbostic  * curses.c
3*32689Sbostic  *
4*32689Sbostic  * This source herein may be modified and/or distributed by anybody who
5*32689Sbostic  * so desires, with the following restrictions:
6*32689Sbostic  *    1.)  No portion of this notice shall be removed.
7*32689Sbostic  *    2.)  Credit shall not be taken for the creation of this source.
8*32689Sbostic  *    3.)  This code is not to be traded, sold, or used for personal
9*32689Sbostic  *         gain or profit.
10*32689Sbostic  *
11*32689Sbostic  */
12*32689Sbostic 
13*32689Sbostic #ifndef lint
14*32689Sbostic static char sccsid[] = "@(#)curses.c	5.1 (Berkeley) 11/25/87";
15*32689Sbostic #endif /* not lint */
16*32689Sbostic 
17*32689Sbostic #ifdef CURSES
18*32689Sbostic 
19*32689Sbostic /* The following is a curses emulation package suitable for the rogue program
20*32689Sbostic  * in which it is included.  No other suitability is claimed or suspected.
21*32689Sbostic  * Only those routines currently needed by this rogue program are included.
22*32689Sbostic  * This is being provided for those systems that don't have a suitable
23*32689Sbostic  * curses package and want to run this rogue program.
24*32689Sbostic  *
25*32689Sbostic  * Compile the entire program with -DCURSES to incorporate this package.
26*32689Sbostic  *
27*32689Sbostic  * The following is NOT supported:
28*32689Sbostic  *   "%D", "%B", "%n", or "%>" inside a cursor motion (cm) termcap string.
29*32689Sbostic  *   Terminals in which the cursor motion addresses the row differently from
30*32689Sbostic  *       the column, as in ":cm=\E%2,%3" or ":cm=\EY%+x;%+y"
31*32689Sbostic  *   Termcap database stored in the TERMCAP environ variable as returned
32*32689Sbostic  *       from md_getenv().  Only the termcap file name can be stored there.
33*32689Sbostic  *       See the comments for md_getenv() in machdep.c.
34*32689Sbostic  *   Terminals without non-destructive backspace.  Backspace (^H) is used
35*32689Sbostic  *       for cursor motion regardless of any termcap entries.
36*32689Sbostic  *   The ":tc=" termcap entry is ignored.
37*32689Sbostic  *
38*32689Sbostic  * Suggestions:
39*32689Sbostic  *   Use line-feed as your termcap "do" entry: ":do=^J", ":do=\012" or
40*32689Sbostic  *      ":do=\n"  This will help cursor motion optimization.  If line-feed
41*32689Sbostic  *      won't work, then a short escape sequence will do.
42*32689Sbostic  */
43*32689Sbostic 
44*32689Sbostic #include <stdio.h>
45*32689Sbostic #include "rogue.h"
46*32689Sbostic 
47*32689Sbostic boolean tc_tname();
48*32689Sbostic 
49*32689Sbostic #define BS 010
50*32689Sbostic #define LF 012
51*32689Sbostic #define CR 015
52*32689Sbostic #define ESC '\033'
53*32689Sbostic #define TAB '\011'
54*32689Sbostic 
55*32689Sbostic #define ST_MASK 0x80
56*32689Sbostic #define BUFLEN 256
57*32689Sbostic 
58*32689Sbostic char terminal[DROWS][DCOLS];
59*32689Sbostic char buffer[DROWS][DCOLS];
60*32689Sbostic char *tc_file;
61*32689Sbostic 
62*32689Sbostic char cm_esc[16];
63*32689Sbostic char cm_sep[16];
64*32689Sbostic char cm_end[16];
65*32689Sbostic boolean cm_reverse = 0;
66*32689Sbostic boolean cm_two = 0;
67*32689Sbostic boolean cm_three = 0;
68*32689Sbostic boolean cm_char = 0;
69*32689Sbostic short cm_inc = 0;
70*32689Sbostic 
71*32689Sbostic boolean screen_dirty;
72*32689Sbostic boolean lines_dirty[DROWS];
73*32689Sbostic boolean buf_stand_out = 0;
74*32689Sbostic boolean term_stand_out = 0;
75*32689Sbostic 
76*32689Sbostic int LINES = DROWS;
77*32689Sbostic int COLS = DCOLS;
78*32689Sbostic WINDOW scr_buf;
79*32689Sbostic WINDOW *curscr = &scr_buf;
80*32689Sbostic 
81*32689Sbostic char *CL = (char *) 0;
82*32689Sbostic char *CM = (char *) 0;
83*32689Sbostic char *UC = (char *) 0;	/* UP */
84*32689Sbostic char *DO = (char *) 0;
85*32689Sbostic char *VS = "";
86*32689Sbostic char *VE = "";
87*32689Sbostic char *TI = "";
88*32689Sbostic char *TE = "";
89*32689Sbostic char *SO = "";
90*32689Sbostic char *SE = "";
91*32689Sbostic 
92*32689Sbostic short cur_row;
93*32689Sbostic short cur_col;
94*32689Sbostic 
95*32689Sbostic initscr()
96*32689Sbostic {
97*32689Sbostic 	clear();
98*32689Sbostic 	get_term_info();
99*32689Sbostic 	printf("%s%s", TI, VS);
100*32689Sbostic }
101*32689Sbostic 
102*32689Sbostic endwin()
103*32689Sbostic {
104*32689Sbostic 	printf("%s%s", TE, VE);
105*32689Sbostic 	md_cbreak_no_echo_nonl(0);
106*32689Sbostic }
107*32689Sbostic 
108*32689Sbostic move(row, col)
109*32689Sbostic short row, col;
110*32689Sbostic {
111*32689Sbostic 	curscr->_cury = row;
112*32689Sbostic 	curscr->_curx = col;
113*32689Sbostic 	screen_dirty = 1;
114*32689Sbostic }
115*32689Sbostic 
116*32689Sbostic mvaddstr(row, col, str)
117*32689Sbostic short row, col;
118*32689Sbostic char *str;
119*32689Sbostic {
120*32689Sbostic 	move(row, col);
121*32689Sbostic 	addstr(str);
122*32689Sbostic }
123*32689Sbostic 
124*32689Sbostic addstr(str)
125*32689Sbostic char *str;
126*32689Sbostic {
127*32689Sbostic 	while (*str) {
128*32689Sbostic 		addch((int) *str++);
129*32689Sbostic 	}
130*32689Sbostic }
131*32689Sbostic 
132*32689Sbostic addch(ch)
133*32689Sbostic register int ch;
134*32689Sbostic {
135*32689Sbostic 	short row, col;
136*32689Sbostic 
137*32689Sbostic 	row = curscr->_cury;
138*32689Sbostic 	col = curscr->_curx++;
139*32689Sbostic 
140*32689Sbostic 	if (buf_stand_out) {
141*32689Sbostic 		ch |= ST_MASK;
142*32689Sbostic 	}
143*32689Sbostic 	buffer[row][col] = (char) ch;
144*32689Sbostic 	lines_dirty[row] = 1;
145*32689Sbostic 	screen_dirty = 1;
146*32689Sbostic }
147*32689Sbostic 
148*32689Sbostic mvaddch(row, col, ch)
149*32689Sbostic short row, col;
150*32689Sbostic int ch;
151*32689Sbostic {
152*32689Sbostic 	move(row, col);
153*32689Sbostic 	addch(ch);
154*32689Sbostic }
155*32689Sbostic 
156*32689Sbostic refresh()
157*32689Sbostic {
158*32689Sbostic 	register i, j, line;
159*32689Sbostic 	short old_row, old_col, first_row;
160*32689Sbostic 
161*32689Sbostic 	if (screen_dirty) {
162*32689Sbostic 
163*32689Sbostic 		old_row = curscr->_cury;
164*32689Sbostic 		old_col = curscr->_curx;
165*32689Sbostic 		first_row = cur_row;
166*32689Sbostic 
167*32689Sbostic 		for (i = 0; i < DROWS; i++) {
168*32689Sbostic 			line = (first_row + i) % DROWS;
169*32689Sbostic 			if (lines_dirty[line]) {
170*32689Sbostic 				for (j = 0; j < DCOLS; j++) {
171*32689Sbostic 					if (buffer[line][j] != terminal[line][j]) {
172*32689Sbostic 						put_char_at(line, j, buffer[line][j]);
173*32689Sbostic 					}
174*32689Sbostic 				}
175*32689Sbostic 				lines_dirty[line] = 0;
176*32689Sbostic 			}
177*32689Sbostic 		}
178*32689Sbostic 		put_cursor(old_row, old_col);
179*32689Sbostic 		screen_dirty = 0;
180*32689Sbostic 		fflush(stdout);
181*32689Sbostic 	}
182*32689Sbostic }
183*32689Sbostic 
184*32689Sbostic wrefresh(scr)
185*32689Sbostic WINDOW *scr;
186*32689Sbostic {
187*32689Sbostic 	short i, col;
188*32689Sbostic 
189*32689Sbostic 	printf("%s", CL);
190*32689Sbostic 	cur_row = cur_col = 0;
191*32689Sbostic 
192*32689Sbostic 	for (i = 0; i < DROWS; i++) {
193*32689Sbostic 		col = 0;
194*32689Sbostic 		while (col < DCOLS) {
195*32689Sbostic 			while ((col < DCOLS) && (buffer[i][col] == ' ')) {
196*32689Sbostic 				col++;
197*32689Sbostic 			}
198*32689Sbostic 			if (col < DCOLS) {
199*32689Sbostic 				put_cursor(i, col);
200*32689Sbostic 			}
201*32689Sbostic 			while ((col < DCOLS) && (buffer[i][col] != ' ')) {
202*32689Sbostic 				put_st_char((int) buffer[i][col]);
203*32689Sbostic 				cur_col++;
204*32689Sbostic 				col++;
205*32689Sbostic 			}
206*32689Sbostic 		}
207*32689Sbostic 	}
208*32689Sbostic 	put_cursor(curscr->_cury, curscr->_curx);
209*32689Sbostic 	fflush(stdout);
210*32689Sbostic 	scr = scr;		/* make lint happy */
211*32689Sbostic }
212*32689Sbostic 
213*32689Sbostic mvinch(row, col)
214*32689Sbostic short row, col;
215*32689Sbostic {
216*32689Sbostic 	move(row, col);
217*32689Sbostic 	return((int) buffer[row][col]);
218*32689Sbostic }
219*32689Sbostic 
220*32689Sbostic clear()
221*32689Sbostic {
222*32689Sbostic 	printf("%s", CL);
223*32689Sbostic 	fflush(stdout);
224*32689Sbostic 	cur_row = cur_col = 0;
225*32689Sbostic 	move(0, 0);
226*32689Sbostic 	clear_buffers();
227*32689Sbostic }
228*32689Sbostic 
229*32689Sbostic clrtoeol()
230*32689Sbostic {
231*32689Sbostic 	short row, col;
232*32689Sbostic 
233*32689Sbostic 	row = curscr->_cury;
234*32689Sbostic 
235*32689Sbostic 	for (col = curscr->_curx; col < DCOLS; col++) {
236*32689Sbostic 		buffer[row][col] = ' ';
237*32689Sbostic 	}
238*32689Sbostic 	lines_dirty[row] = 1;
239*32689Sbostic }
240*32689Sbostic 
241*32689Sbostic standout()
242*32689Sbostic {
243*32689Sbostic 	buf_stand_out = 1;
244*32689Sbostic }
245*32689Sbostic 
246*32689Sbostic standend()
247*32689Sbostic {
248*32689Sbostic 	buf_stand_out = 0;
249*32689Sbostic }
250*32689Sbostic 
251*32689Sbostic crmode()
252*32689Sbostic {
253*32689Sbostic 	md_cbreak_no_echo_nonl(1);
254*32689Sbostic }
255*32689Sbostic 
256*32689Sbostic noecho()
257*32689Sbostic {
258*32689Sbostic 	/* crmode() takes care of this */
259*32689Sbostic }
260*32689Sbostic 
261*32689Sbostic nonl()
262*32689Sbostic {
263*32689Sbostic 	/* crmode() takes care of this */
264*32689Sbostic }
265*32689Sbostic 
266*32689Sbostic clear_buffers()
267*32689Sbostic {
268*32689Sbostic 	register i, j;
269*32689Sbostic 
270*32689Sbostic 	screen_dirty = 0;
271*32689Sbostic 
272*32689Sbostic 	for (i = 0; i < DROWS; i++) {
273*32689Sbostic 		lines_dirty[i] = 0;
274*32689Sbostic 		for (j = 0; j < DCOLS; j++) {
275*32689Sbostic 			terminal[i][j] = ' ';
276*32689Sbostic 			buffer[i][j] = ' ';
277*32689Sbostic 		}
278*32689Sbostic 	}
279*32689Sbostic }
280*32689Sbostic 
281*32689Sbostic put_char_at(row, col, ch)
282*32689Sbostic register row, col, ch;
283*32689Sbostic {
284*32689Sbostic 	put_cursor(row, col);
285*32689Sbostic 	put_st_char(ch);
286*32689Sbostic 	terminal[row][col] = (char) ch;
287*32689Sbostic 	cur_col++;
288*32689Sbostic }
289*32689Sbostic 
290*32689Sbostic put_cursor(row, col)
291*32689Sbostic register row, col;
292*32689Sbostic {
293*32689Sbostic 	register i, rdif, cdif;
294*32689Sbostic 	short ch, t;
295*32689Sbostic 
296*32689Sbostic 	rdif = (row > cur_row) ? row - cur_row : cur_row - row;
297*32689Sbostic 	cdif = (col > cur_col) ? col - cur_col : cur_col - col;
298*32689Sbostic 
299*32689Sbostic 	if (((row > cur_row) && DO) || ((cur_row > row) && UC)) {
300*32689Sbostic 		if ((rdif < 4) && (cdif < 4)) {
301*32689Sbostic 			for (i = 0; i < rdif; i++) {
302*32689Sbostic 				printf("%s", ((row < cur_row) ? UC : DO));
303*32689Sbostic 			}
304*32689Sbostic 			cur_row = row;
305*32689Sbostic 			if (col == cur_col) {
306*32689Sbostic 				return;
307*32689Sbostic 			}
308*32689Sbostic 		}
309*32689Sbostic 	}
310*32689Sbostic 	if (row == cur_row) {
311*32689Sbostic 		if (cdif <= 6) {
312*32689Sbostic 		for (i = 0; i < cdif; i++) {
313*32689Sbostic 				ch = (col < cur_col) ? BS :
314*32689Sbostic 						terminal[row][cur_col + i];
315*32689Sbostic 				put_st_char((int) ch);
316*32689Sbostic 			}
317*32689Sbostic 			cur_row = row;
318*32689Sbostic 			cur_col = col;
319*32689Sbostic 			return;
320*32689Sbostic 		}
321*32689Sbostic 	}
322*32689Sbostic 	cur_row = row;
323*32689Sbostic 	cur_col = col;
324*32689Sbostic 
325*32689Sbostic 	row += cm_inc;
326*32689Sbostic 	col += cm_inc;
327*32689Sbostic 
328*32689Sbostic 	if (cm_reverse) {
329*32689Sbostic 		t = row;
330*32689Sbostic 		row = col;
331*32689Sbostic 		col = t;
332*32689Sbostic 	}
333*32689Sbostic 	if (cm_two) {
334*32689Sbostic 		printf("%s%02d%s%02d%s", cm_esc, row, cm_sep, col, cm_end);
335*32689Sbostic 	} else if (cm_three) {
336*32689Sbostic 		printf("%s%03d%s%03d%s", cm_esc, row, cm_sep, col, cm_end);
337*32689Sbostic 	} else if (cm_char) {
338*32689Sbostic 		printf("%s%c%s%c%s", cm_esc, row, cm_sep, col, cm_end);
339*32689Sbostic 	} else {
340*32689Sbostic 		printf("%s%d%s%d%s", cm_esc, row, cm_sep, col, cm_end);
341*32689Sbostic 	}
342*32689Sbostic }
343*32689Sbostic 
344*32689Sbostic put_st_char(ch)
345*32689Sbostic register ch;
346*32689Sbostic {
347*32689Sbostic 	if ((ch & ST_MASK) && (!term_stand_out)) {
348*32689Sbostic 		ch &= ~ST_MASK;
349*32689Sbostic 		printf("%s%c", SO, ch);
350*32689Sbostic 		term_stand_out = 1;
351*32689Sbostic 	} else if ((!(ch & ST_MASK)) && term_stand_out) {
352*32689Sbostic 		printf("%s%c", SE, ch);
353*32689Sbostic 		term_stand_out = 0;
354*32689Sbostic 	} else {
355*32689Sbostic 		ch &= ~ST_MASK;
356*32689Sbostic 		putchar(ch);
357*32689Sbostic 	}
358*32689Sbostic }
359*32689Sbostic 
360*32689Sbostic get_term_info()
361*32689Sbostic {
362*32689Sbostic 	FILE *fp;
363*32689Sbostic 	char *term, *tcf;
364*32689Sbostic 	char buf[BUFLEN];
365*32689Sbostic 
366*32689Sbostic 	if (tcf = md_getenv("TERMCAP")) {
367*32689Sbostic 		if (strlen(tcf) > 40) {
368*32689Sbostic 			clean_up("TERMCAP file name too long");
369*32689Sbostic 		}
370*32689Sbostic 		tc_file = tcf;
371*32689Sbostic 	} else {
372*32689Sbostic 		if (!(tc_file = md_gdtcf())) {
373*32689Sbostic 			clean_up("I need a termcap file");
374*32689Sbostic 		}
375*32689Sbostic 	}
376*32689Sbostic 
377*32689Sbostic 	if (!(term = md_getenv("TERM"))) {
378*32689Sbostic 		clean_up("Cannot find TERM variable in environ");
379*32689Sbostic 	}
380*32689Sbostic 	if ((fp = fopen(tc_file, "r")) == NULL) {
381*32689Sbostic 		sprintf(buf, "Cannot open TERMCAP file: %s", tc_file);
382*32689Sbostic 		clean_up(buf);
383*32689Sbostic 	}
384*32689Sbostic 
385*32689Sbostic 	if (!tc_tname(fp, term, buf)) {
386*32689Sbostic 		sprintf(buf, "Cannot find TERM type: %s in TERMCAP file: %s", term,
387*32689Sbostic 			tc_file);
388*32689Sbostic 		clean_up(buf);
389*32689Sbostic 	}
390*32689Sbostic 	tc_gtdata(fp, buf);
391*32689Sbostic 	fclose(fp);
392*32689Sbostic }
393*32689Sbostic 
394*32689Sbostic boolean
395*32689Sbostic tc_tname(fp, term, buf)
396*32689Sbostic FILE *fp;
397*32689Sbostic char *term;
398*32689Sbostic char *buf;
399*32689Sbostic {
400*32689Sbostic 	short i, j;
401*32689Sbostic 	boolean found = 0;
402*32689Sbostic 	char *fg;
403*32689Sbostic 
404*32689Sbostic 	while (!found) {
405*32689Sbostic 		i = 0;
406*32689Sbostic 		fg = fgets(buf, BUFLEN, fp);
407*32689Sbostic 		if (fg != NULL) {
408*32689Sbostic 			if (	(buf[0] != '#') && (buf[0] != ' ') && (buf[0] != TAB) &&
409*32689Sbostic 					(buf[0] != CR) && (buf[0] != LF)) {
410*32689Sbostic 				while (buf[i] && (!found)) {
411*32689Sbostic 					j = 0;
412*32689Sbostic 					while (buf[i] == term[j]) {
413*32689Sbostic 						i++;
414*32689Sbostic 						j++;
415*32689Sbostic 					}
416*32689Sbostic 					if ((!term[j]) && ((buf[i] == '|') || (buf[i] == ':'))) {
417*32689Sbostic 						found = 1;
418*32689Sbostic 					} else {
419*32689Sbostic 						while (buf[i] && (buf[i] != '|') && (buf[i] != ':')) {
420*32689Sbostic 							i++;
421*32689Sbostic 						}
422*32689Sbostic 						if (buf[i]) {
423*32689Sbostic 							i++;
424*32689Sbostic 						}
425*32689Sbostic 					}
426*32689Sbostic 				}
427*32689Sbostic 			}
428*32689Sbostic 		} else {
429*32689Sbostic 			break;
430*32689Sbostic 		}
431*32689Sbostic 	}
432*32689Sbostic 	return(found);
433*32689Sbostic }
434*32689Sbostic 
435*32689Sbostic tc_gtdata(fp, buf)
436*32689Sbostic FILE *fp;
437*32689Sbostic char *buf;
438*32689Sbostic {
439*32689Sbostic 	short i;
440*32689Sbostic 	boolean first = 1;
441*32689Sbostic 
442*32689Sbostic 	do {
443*32689Sbostic 		if (!first) {
444*32689Sbostic 			if ((buf[0] != TAB) && (buf[0] != ' ')) {
445*32689Sbostic 				break;
446*32689Sbostic 			}
447*32689Sbostic 		}
448*32689Sbostic 		first = 0;
449*32689Sbostic 		i = 0;
450*32689Sbostic 		while (buf[i]) {
451*32689Sbostic 			while (buf[i] && (buf[i] != ':')) {
452*32689Sbostic 				i++;
453*32689Sbostic 			}
454*32689Sbostic 			if (buf[i] == ':') {
455*32689Sbostic 				if (!strncmp(buf + i, ":cl=", 4)) {
456*32689Sbostic 					tc_gets(buf + i, &CL);
457*32689Sbostic 				} else if (!strncmp(buf + i, ":cm=", 4)) {
458*32689Sbostic 					tc_gets(buf + i, &CM);
459*32689Sbostic 				} else if (!strncmp(buf + i, ":up=", 4)) {
460*32689Sbostic 					tc_gets(buf + i, &UC);
461*32689Sbostic 				} else if (!strncmp(buf + i, ":do=", 4)) {
462*32689Sbostic 					tc_gets(buf + i, &DO);
463*32689Sbostic 				} else if (!strncmp(buf + i, ":vs=", 4)) {
464*32689Sbostic 					tc_gets(buf + i, &VS);
465*32689Sbostic 				} else if (!strncmp(buf + i, ":ve=", 4)) {
466*32689Sbostic 					tc_gets(buf + i, &VE);
467*32689Sbostic 				} else if (!strncmp(buf + i, ":ti=", 4)) {
468*32689Sbostic 					tc_gets(buf + i, &TI);
469*32689Sbostic 				} else if (!strncmp(buf + i, ":te=", 4)) {
470*32689Sbostic 					tc_gets(buf + i, &TE);
471*32689Sbostic 				} else if (!strncmp(buf + i, ":vs=", 4)) {
472*32689Sbostic 					tc_gets(buf + i, &VS);
473*32689Sbostic 				} else if (!strncmp(buf + i, ":ve=", 4)) {
474*32689Sbostic 					tc_gets(buf + i, &VE);
475*32689Sbostic 				} else if (!strncmp(buf + i, ":so=", 4)) {
476*32689Sbostic 					tc_gets(buf + i, &SO);
477*32689Sbostic 				} else if (!strncmp(buf + i, ":se=", 4)) {
478*32689Sbostic 					tc_gets(buf + i, &SE);
479*32689Sbostic 				} else if (!strncmp(buf + i, ":li#", 4)) {
480*32689Sbostic 					tc_gnum(buf + i, &LINES);
481*32689Sbostic 				} else if (!strncmp(buf + i, ":co#", 4)) {
482*32689Sbostic 					tc_gnum(buf + i, &COLS);
483*32689Sbostic 				}
484*32689Sbostic 				i++;
485*32689Sbostic 			}
486*32689Sbostic 		}
487*32689Sbostic 	} while (fgets(buf, BUFLEN, fp) != NULL);
488*32689Sbostic 
489*32689Sbostic 	if ((!CM) || (!CL)) {
490*32689Sbostic 		clean_up("Terminal and termcap must have cm and cl");
491*32689Sbostic 	}
492*32689Sbostic 	tc_cmget();
493*32689Sbostic }
494*32689Sbostic 
495*32689Sbostic tc_gets(ibuf, tcstr)
496*32689Sbostic char *ibuf;
497*32689Sbostic char **tcstr;
498*32689Sbostic {
499*32689Sbostic 	short i, j, k, n;
500*32689Sbostic 	char obuf[BUFLEN];
501*32689Sbostic 
502*32689Sbostic 	i = 4;
503*32689Sbostic 	j = 0;
504*32689Sbostic 
505*32689Sbostic 	while (ibuf[i] && is_digit(ibuf[i])) {
506*32689Sbostic 		i++;
507*32689Sbostic 	}
508*32689Sbostic 
509*32689Sbostic 	while (ibuf[i] && (ibuf[i] != ':')) {
510*32689Sbostic 		if (ibuf[i] == '\\') {
511*32689Sbostic 			i++;
512*32689Sbostic 			switch(ibuf[i]) {
513*32689Sbostic 			case 'E':
514*32689Sbostic 				obuf[j] = ESC;
515*32689Sbostic 				i++;
516*32689Sbostic 				break;
517*32689Sbostic 			case 'n':
518*32689Sbostic 				obuf[j] = LF;
519*32689Sbostic 				i++;
520*32689Sbostic 				break;
521*32689Sbostic 			case 'r':
522*32689Sbostic 				obuf[j] = CR;
523*32689Sbostic 				i++;
524*32689Sbostic 				break;
525*32689Sbostic 			case 'b':
526*32689Sbostic 				obuf[j] = BS;
527*32689Sbostic 				i++;
528*32689Sbostic 				break;
529*32689Sbostic 			case 't':
530*32689Sbostic 				obuf[j] = TAB;
531*32689Sbostic 				i++;
532*32689Sbostic 				break;
533*32689Sbostic 			case '0':
534*32689Sbostic 			case '1':
535*32689Sbostic 			case '2':
536*32689Sbostic 			case '3':
537*32689Sbostic 			case '4':
538*32689Sbostic 			case '5':
539*32689Sbostic 			case '6':
540*32689Sbostic 			case '7':
541*32689Sbostic 			case '8':
542*32689Sbostic 			case '9':
543*32689Sbostic 				n = 0;
544*32689Sbostic 				k = 0;
545*32689Sbostic 				while (k < 3 && ibuf[i] && is_digit(ibuf[i])) {
546*32689Sbostic 					n = (8 * n) + (ibuf[i] - '0');
547*32689Sbostic 					i++;
548*32689Sbostic 					k++;
549*32689Sbostic 				}
550*32689Sbostic 				obuf[j] = (char) n;
551*32689Sbostic 				break;
552*32689Sbostic 			default:
553*32689Sbostic 				obuf[j] = ibuf[i];
554*32689Sbostic 				i++;
555*32689Sbostic 			}
556*32689Sbostic 		} else if (ibuf[i] == '^') {
557*32689Sbostic 			obuf[j] = ibuf[i+1] - 64;
558*32689Sbostic 			i += 2;
559*32689Sbostic 		} else {
560*32689Sbostic 			obuf[j] = ibuf[i++];
561*32689Sbostic 		}
562*32689Sbostic 		j++;
563*32689Sbostic 	}
564*32689Sbostic 	obuf[j] = 0;
565*32689Sbostic 	if (!(*tcstr = md_malloc(j + 1))) {
566*32689Sbostic 		clean_up("cannot alloc() memory");
567*32689Sbostic 	}
568*32689Sbostic 	(void) strcpy(*tcstr, obuf);
569*32689Sbostic }
570*32689Sbostic 
571*32689Sbostic tc_gnum(ibuf, n)
572*32689Sbostic char *ibuf;
573*32689Sbostic int *n;
574*32689Sbostic {
575*32689Sbostic 	short i;
576*32689Sbostic 	int r = 0;
577*32689Sbostic 
578*32689Sbostic 	i = 4;
579*32689Sbostic 
580*32689Sbostic 	while (is_digit(ibuf[i])) {
581*32689Sbostic 		r = (r * 10) + (ibuf[i] - '0');
582*32689Sbostic 		i++;
583*32689Sbostic 	}
584*32689Sbostic 	*n = r;
585*32689Sbostic }
586*32689Sbostic 
587*32689Sbostic tstp()
588*32689Sbostic {
589*32689Sbostic 	endwin();
590*32689Sbostic 	md_tstp();
591*32689Sbostic 
592*32689Sbostic 	start_window();
593*32689Sbostic 	printf("%s%s", TI, VS);
594*32689Sbostic 	wrefresh(curscr);
595*32689Sbostic 	md_slurp();
596*32689Sbostic }
597*32689Sbostic 
598*32689Sbostic tc_cmget()
599*32689Sbostic {
600*32689Sbostic 	short i = 0, j = 0, rc_spec = 0;
601*32689Sbostic 
602*32689Sbostic 	while (CM[i] && (CM[i] != '%') && (j < 15)) {
603*32689Sbostic 		cm_esc[j++] = CM[i++];
604*32689Sbostic 	}
605*32689Sbostic 	cm_esc[j] = 0;
606*32689Sbostic 
607*32689Sbostic 	while (CM[i] && (rc_spec < 2)) {
608*32689Sbostic 		if (CM[i] == '%') {
609*32689Sbostic 			i++;
610*32689Sbostic 			switch(CM[i]) {
611*32689Sbostic 			case 'd':
612*32689Sbostic 				rc_spec++;
613*32689Sbostic 				break;
614*32689Sbostic 			case 'i':
615*32689Sbostic 				cm_inc = 1;
616*32689Sbostic 				break;
617*32689Sbostic 			case '2':
618*32689Sbostic 				cm_two = 1;
619*32689Sbostic 				rc_spec++;
620*32689Sbostic 				break;
621*32689Sbostic 			case '3':
622*32689Sbostic 				cm_three = 1;
623*32689Sbostic 				rc_spec++;
624*32689Sbostic 				break;
625*32689Sbostic 			case '.':
626*32689Sbostic 				cm_char = 1;
627*32689Sbostic 				rc_spec++;
628*32689Sbostic 				break;
629*32689Sbostic 			case 'r':
630*32689Sbostic 				cm_reverse = 1;
631*32689Sbostic 				break;
632*32689Sbostic 			case '+':
633*32689Sbostic 				i++;
634*32689Sbostic 				cm_inc = CM[i];
635*32689Sbostic 				cm_char = 1;
636*32689Sbostic 				rc_spec++;
637*32689Sbostic 				break;
638*32689Sbostic 			}
639*32689Sbostic 			i++;
640*32689Sbostic 		} else {
641*32689Sbostic 			j = 0;
642*32689Sbostic 			while (CM[i] && (CM[i] != '%')) {
643*32689Sbostic 				cm_sep[j++] = CM[i++];
644*32689Sbostic 			}
645*32689Sbostic 			cm_sep[j] = 0;
646*32689Sbostic 		}
647*32689Sbostic 	}
648*32689Sbostic 
649*32689Sbostic 	j = 0;
650*32689Sbostic 	if (rc_spec == 2) {
651*32689Sbostic 		while (CM[i] && (j < 15)) {
652*32689Sbostic 			cm_end[j++] = CM[i++];
653*32689Sbostic 		}
654*32689Sbostic 	}
655*32689Sbostic 	cm_end[j] = 0;
656*32689Sbostic }
657*32689Sbostic 
658*32689Sbostic #endif
659