]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - rogue/curses.c
1 /* $NetBSD: curses.c,v 1.4 1997/10/12 11:45:01 lukem Exp $ */
4 * Copyright (c) 1988, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 #include <sys/cdefs.h>
42 static char sccsid
[] = "@(#)curses.c 8.1 (Berkeley) 5/31/93";
44 __RCSID("$NetBSD: curses.c,v 1.4 1997/10/12 11:45:01 lukem Exp $");
51 * This source herein may be modified and/or distributed by anybody who
52 * so desires, with the following restrictions:
53 * 1.) No portion of this notice shall be removed.
54 * 2.) Credit shall not be taken for the creation of this source.
55 * 3.) This code is not to be traded, sold, or used for personal
62 /* The following is a curses emulation package suitable for the rogue program
63 * in which it is included. No other suitability is claimed or suspected.
64 * Only those routines currently needed by this rogue program are included.
65 * This is being provided for those systems that don't have a suitable
66 * curses package and want to run this rogue program.
68 * Compile the entire program with -DCURSES to incorporate this package.
70 * The following is NOT supported:
71 * "%D", "%B", "%n", or "%>" inside a cursor motion (cm) termcap string.
72 * Terminals in which the cursor motion addresses the row differently from
73 * the column, as in ":cm=\E%2,%3" or ":cm=\EY%+x;%+y"
74 * Termcap database stored in the TERMCAP environ variable as returned
75 * from md_getenv(). Only the termcap file name can be stored there.
76 * See the comments for md_getenv() in machdep.c.
77 * Terminals without non-destructive backspace. Backspace (^H) is used
78 * for cursor motion regardless of any termcap entries.
79 * The ":tc=" termcap entry is ignored.
82 * Use line-feed as your termcap "do" entry: ":do=^J", ":do=\012" or
83 * ":do=\n" This will help cursor motion optimization. If line-feed
84 * won't work, then a short escape sequence will do.
101 char terminal
[DROWS
][DCOLS
];
102 char buffer
[DROWS
][DCOLS
];
108 boolean cm_reverse
= 0;
110 boolean cm_three
= 0;
114 boolean screen_dirty
;
115 boolean lines_dirty
[DROWS
];
116 boolean buf_stand_out
= 0;
117 boolean term_stand_out
= 0;
122 WINDOW
*curscr
= &scr_buf
;
124 char *CL
= (char *) 0;
125 char *CM
= (char *) 0;
126 char *UC
= (char *) 0; /* UP */
127 char *DO
= (char *) 0;
142 printf("%s%s", TI
, VS
);
147 printf("%s%s", TE
, VE
);
148 md_cbreak_no_echo_nonl(0);
159 mvaddstr(row
, col
, str
)
181 col
= curscr
->_curx
++;
186 buffer
[row
][col
] = (char) ch
;
187 lines_dirty
[row
] = 1;
191 mvaddch(row
, col
, ch
)
202 short old_row
, old_col
, first_row
;
206 old_row
= curscr
->_cury
;
207 old_col
= curscr
->_curx
;
210 for (i
= 0; i
< DROWS
; i
++) {
211 line
= (first_row
+ i
) % DROWS
;
212 if (lines_dirty
[line
]) {
213 for (j
= 0; j
< DCOLS
; j
++) {
214 if (buffer
[line
][j
] != terminal
[line
][j
]) {
215 put_char_at(line
, j
, buffer
[line
][j
]);
218 lines_dirty
[line
] = 0;
221 put_cursor(old_row
, old_col
);
233 cur_row
= cur_col
= 0;
235 for (i
= 0; i
< DROWS
; i
++) {
237 while (col
< DCOLS
) {
238 while ((col
< DCOLS
) && (buffer
[i
][col
] == ' ')) {
244 while ((col
< DCOLS
) && (buffer
[i
][col
] != ' ')) {
245 put_st_char((int) buffer
[i
][col
]);
251 put_cursor(curscr
->_cury
, curscr
->_curx
);
253 scr
= scr
; /* make lint happy */
260 return((int) buffer
[row
][col
]);
267 cur_row
= cur_col
= 0;
278 for (col
= curscr
->_curx
; col
< DCOLS
; col
++) {
279 buffer
[row
][col
] = ' ';
281 lines_dirty
[row
] = 1;
296 md_cbreak_no_echo_nonl(1);
301 /* crmode() takes care of this */
306 /* crmode() takes care of this */
315 for (i
= 0; i
< DROWS
; i
++) {
317 for (j
= 0; j
< DCOLS
; j
++) {
318 terminal
[i
][j
] = ' ';
324 put_char_at(row
, col
, ch
)
327 put_cursor(row
, col
);
329 terminal
[row
][col
] = (char) ch
;
339 rdif
= (row
> cur_row
) ? row
- cur_row
: cur_row
- row
;
340 cdif
= (col
> cur_col
) ? col
- cur_col
: cur_col
- col
;
342 if (((row
> cur_row
) && DO
) || ((cur_row
> row
) && UC
)) {
343 if ((rdif
< 4) && (cdif
< 4)) {
344 for (i
= 0; i
< rdif
; i
++) {
345 printf("%s", ((row
< cur_row
) ? UC
: DO
));
348 if (col
== cur_col
) {
353 if (row
== cur_row
) {
355 for (i
= 0; i
< cdif
; i
++) {
356 ch
= (col
< cur_col
) ? BS
:
357 terminal
[row
][cur_col
+ i
];
358 put_st_char((int) ch
);
377 printf("%s%02d%s%02d%s", cm_esc
, row
, cm_sep
, col
, cm_end
);
378 } else if (cm_three
) {
379 printf("%s%03d%s%03d%s", cm_esc
, row
, cm_sep
, col
, cm_end
);
380 } else if (cm_char
) {
381 printf("%s%c%s%c%s", cm_esc
, row
, cm_sep
, col
, cm_end
);
383 printf("%s%d%s%d%s", cm_esc
, row
, cm_sep
, col
, cm_end
);
390 if ((ch
& ST_MASK
) && (!term_stand_out
)) {
392 printf("%s%c", SO
, ch
);
394 } else if ((!(ch
& ST_MASK
)) && term_stand_out
) {
395 printf("%s%c", SE
, ch
);
409 if (tcf
= md_getenv("TERMCAP")) {
410 if (strlen(tcf
) > 40) {
411 clean_up("TERMCAP file name too long");
415 if (!(tc_file
= md_gdtcf())) {
416 clean_up("I need a termcap file");
420 if (!(term
= md_getenv("TERM"))) {
421 clean_up("Cannot find TERM variable in environ");
423 if ((fp
= fopen(tc_file
, "r")) == NULL
) {
424 sprintf(buf
, "Cannot open TERMCAP file: %s", tc_file
);
428 if (!tc_tname(fp
, term
, buf
)) {
429 sprintf(buf
, "Cannot find TERM type: %s in TERMCAP file: %s", term
,
438 tc_tname(fp
, term
, buf
)
449 fg
= fgets(buf
, BUFLEN
, fp
);
451 if ( (buf
[0] != '#') && (buf
[0] != ' ') && (buf
[0] != TAB
) &&
452 (buf
[0] != CR
) && (buf
[0] != LF
)) {
453 while (buf
[i
] && (!found
)) {
455 while (buf
[i
] == term
[j
]) {
459 if ((!term
[j
]) && ((buf
[i
] == '|') || (buf
[i
] == ':'))) {
462 while (buf
[i
] && (buf
[i
] != '|') && (buf
[i
] != ':')) {
487 if ((buf
[0] != TAB
) && (buf
[0] != ' ')) {
494 while (buf
[i
] && (buf
[i
] != ':')) {
498 if (!strncmp(buf
+ i
, ":cl=", 4)) {
499 tc_gets(buf
+ i
, &CL
);
500 } else if (!strncmp(buf
+ i
, ":cm=", 4)) {
501 tc_gets(buf
+ i
, &CM
);
502 } else if (!strncmp(buf
+ i
, ":up=", 4)) {
503 tc_gets(buf
+ i
, &UC
);
504 } else if (!strncmp(buf
+ i
, ":do=", 4)) {
505 tc_gets(buf
+ i
, &DO
);
506 } else if (!strncmp(buf
+ i
, ":vs=", 4)) {
507 tc_gets(buf
+ i
, &VS
);
508 } else if (!strncmp(buf
+ i
, ":ve=", 4)) {
509 tc_gets(buf
+ i
, &VE
);
510 } else if (!strncmp(buf
+ i
, ":ti=", 4)) {
511 tc_gets(buf
+ i
, &TI
);
512 } else if (!strncmp(buf
+ i
, ":te=", 4)) {
513 tc_gets(buf
+ i
, &TE
);
514 } else if (!strncmp(buf
+ i
, ":vs=", 4)) {
515 tc_gets(buf
+ i
, &VS
);
516 } else if (!strncmp(buf
+ i
, ":ve=", 4)) {
517 tc_gets(buf
+ i
, &VE
);
518 } else if (!strncmp(buf
+ i
, ":so=", 4)) {
519 tc_gets(buf
+ i
, &SO
);
520 } else if (!strncmp(buf
+ i
, ":se=", 4)) {
521 tc_gets(buf
+ i
, &SE
);
522 } else if (!strncmp(buf
+ i
, ":li#", 4)) {
523 tc_gnum(buf
+ i
, &LINES
);
524 } else if (!strncmp(buf
+ i
, ":co#", 4)) {
525 tc_gnum(buf
+ i
, &COLS
);
530 } while (fgets(buf
, BUFLEN
, fp
) != NULL
);
532 if ((!CM
) || (!CL
)) {
533 clean_up("Terminal and termcap must have cm and cl");
548 while (ibuf
[i
] && is_digit(ibuf
[i
])) {
552 while (ibuf
[i
] && (ibuf
[i
] != ':')) {
553 if (ibuf
[i
] == '\\') {
588 while (k
< 3 && ibuf
[i
] && is_digit(ibuf
[i
])) {
589 n
= (8 * n
) + (ibuf
[i
] - '0');
599 } else if (ibuf
[i
] == '^') {
600 obuf
[j
] = ibuf
[i
+1] - 64;
608 if (!(*tcstr
= md_malloc(j
+ 1))) {
609 clean_up("cannot alloc() memory");
611 (void) strcpy(*tcstr
, obuf
);
623 while (is_digit(ibuf
[i
])) {
624 r
= (r
* 10) + (ibuf
[i
] - '0');
636 printf("%s%s", TI
, VS
);
643 short i
= 0, j
= 0, rc_spec
= 0;
645 while (CM
[i
] && (CM
[i
] != '%') && (j
< 15)) {
646 cm_esc
[j
++] = CM
[i
++];
650 while (CM
[i
] && (rc_spec
< 2)) {
685 while (CM
[i
] && (CM
[i
] != '%')) {
686 cm_sep
[j
++] = CM
[i
++];
694 while (CM
[i
] && (j
< 15)) {
695 cm_end
[j
++] = CM
[i
++];