]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - rogue/curses.c
1 /* $NetBSD: curses.c,v 1.3 1995/04/22 10:27:27 cgd 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
41 static char sccsid
[] = "@(#)curses.c 8.1 (Berkeley) 5/31/93";
43 static char rcsid
[] = "$NetBSD: curses.c,v 1.3 1995/04/22 10:27:27 cgd Exp $";
50 * This source herein may be modified and/or distributed by anybody who
51 * so desires, with the following restrictions:
52 * 1.) No portion of this notice shall be removed.
53 * 2.) Credit shall not be taken for the creation of this source.
54 * 3.) This code is not to be traded, sold, or used for personal
61 /* The following is a curses emulation package suitable for the rogue program
62 * in which it is included. No other suitability is claimed or suspected.
63 * Only those routines currently needed by this rogue program are included.
64 * This is being provided for those systems that don't have a suitable
65 * curses package and want to run this rogue program.
67 * Compile the entire program with -DCURSES to incorporate this package.
69 * The following is NOT supported:
70 * "%D", "%B", "%n", or "%>" inside a cursor motion (cm) termcap string.
71 * Terminals in which the cursor motion addresses the row differently from
72 * the column, as in ":cm=\E%2,%3" or ":cm=\EY%+x;%+y"
73 * Termcap database stored in the TERMCAP environ variable as returned
74 * from md_getenv(). Only the termcap file name can be stored there.
75 * See the comments for md_getenv() in machdep.c.
76 * Terminals without non-destructive backspace. Backspace (^H) is used
77 * for cursor motion regardless of any termcap entries.
78 * The ":tc=" termcap entry is ignored.
81 * Use line-feed as your termcap "do" entry: ":do=^J", ":do=\012" or
82 * ":do=\n" This will help cursor motion optimization. If line-feed
83 * won't work, then a short escape sequence will do.
100 char terminal
[DROWS
][DCOLS
];
101 char buffer
[DROWS
][DCOLS
];
107 boolean cm_reverse
= 0;
109 boolean cm_three
= 0;
113 boolean screen_dirty
;
114 boolean lines_dirty
[DROWS
];
115 boolean buf_stand_out
= 0;
116 boolean term_stand_out
= 0;
121 WINDOW
*curscr
= &scr_buf
;
123 char *CL
= (char *) 0;
124 char *CM
= (char *) 0;
125 char *UC
= (char *) 0; /* UP */
126 char *DO
= (char *) 0;
141 printf("%s%s", TI
, VS
);
146 printf("%s%s", TE
, VE
);
147 md_cbreak_no_echo_nonl(0);
158 mvaddstr(row
, col
, str
)
180 col
= curscr
->_curx
++;
185 buffer
[row
][col
] = (char) ch
;
186 lines_dirty
[row
] = 1;
190 mvaddch(row
, col
, ch
)
201 short old_row
, old_col
, first_row
;
205 old_row
= curscr
->_cury
;
206 old_col
= curscr
->_curx
;
209 for (i
= 0; i
< DROWS
; i
++) {
210 line
= (first_row
+ i
) % DROWS
;
211 if (lines_dirty
[line
]) {
212 for (j
= 0; j
< DCOLS
; j
++) {
213 if (buffer
[line
][j
] != terminal
[line
][j
]) {
214 put_char_at(line
, j
, buffer
[line
][j
]);
217 lines_dirty
[line
] = 0;
220 put_cursor(old_row
, old_col
);
232 cur_row
= cur_col
= 0;
234 for (i
= 0; i
< DROWS
; i
++) {
236 while (col
< DCOLS
) {
237 while ((col
< DCOLS
) && (buffer
[i
][col
] == ' ')) {
243 while ((col
< DCOLS
) && (buffer
[i
][col
] != ' ')) {
244 put_st_char((int) buffer
[i
][col
]);
250 put_cursor(curscr
->_cury
, curscr
->_curx
);
252 scr
= scr
; /* make lint happy */
259 return((int) buffer
[row
][col
]);
266 cur_row
= cur_col
= 0;
277 for (col
= curscr
->_curx
; col
< DCOLS
; col
++) {
278 buffer
[row
][col
] = ' ';
280 lines_dirty
[row
] = 1;
295 md_cbreak_no_echo_nonl(1);
300 /* crmode() takes care of this */
305 /* crmode() takes care of this */
314 for (i
= 0; i
< DROWS
; i
++) {
316 for (j
= 0; j
< DCOLS
; j
++) {
317 terminal
[i
][j
] = ' ';
323 put_char_at(row
, col
, ch
)
324 register row
, col
, ch
;
326 put_cursor(row
, col
);
328 terminal
[row
][col
] = (char) ch
;
335 register i
, rdif
, cdif
;
338 rdif
= (row
> cur_row
) ? row
- cur_row
: cur_row
- row
;
339 cdif
= (col
> cur_col
) ? col
- cur_col
: cur_col
- col
;
341 if (((row
> cur_row
) && DO
) || ((cur_row
> row
) && UC
)) {
342 if ((rdif
< 4) && (cdif
< 4)) {
343 for (i
= 0; i
< rdif
; i
++) {
344 printf("%s", ((row
< cur_row
) ? UC
: DO
));
347 if (col
== cur_col
) {
352 if (row
== cur_row
) {
354 for (i
= 0; i
< cdif
; i
++) {
355 ch
= (col
< cur_col
) ? BS
:
356 terminal
[row
][cur_col
+ i
];
357 put_st_char((int) ch
);
376 printf("%s%02d%s%02d%s", cm_esc
, row
, cm_sep
, col
, cm_end
);
377 } else if (cm_three
) {
378 printf("%s%03d%s%03d%s", cm_esc
, row
, cm_sep
, col
, cm_end
);
379 } else if (cm_char
) {
380 printf("%s%c%s%c%s", cm_esc
, row
, cm_sep
, col
, cm_end
);
382 printf("%s%d%s%d%s", cm_esc
, row
, cm_sep
, col
, cm_end
);
389 if ((ch
& ST_MASK
) && (!term_stand_out
)) {
391 printf("%s%c", SO
, ch
);
393 } else if ((!(ch
& ST_MASK
)) && term_stand_out
) {
394 printf("%s%c", SE
, ch
);
408 if (tcf
= md_getenv("TERMCAP")) {
409 if (strlen(tcf
) > 40) {
410 clean_up("TERMCAP file name too long");
414 if (!(tc_file
= md_gdtcf())) {
415 clean_up("I need a termcap file");
419 if (!(term
= md_getenv("TERM"))) {
420 clean_up("Cannot find TERM variable in environ");
422 if ((fp
= fopen(tc_file
, "r")) == NULL
) {
423 sprintf(buf
, "Cannot open TERMCAP file: %s", tc_file
);
427 if (!tc_tname(fp
, term
, buf
)) {
428 sprintf(buf
, "Cannot find TERM type: %s in TERMCAP file: %s", term
,
437 tc_tname(fp
, term
, buf
)
448 fg
= fgets(buf
, BUFLEN
, fp
);
450 if ( (buf
[0] != '#') && (buf
[0] != ' ') && (buf
[0] != TAB
) &&
451 (buf
[0] != CR
) && (buf
[0] != LF
)) {
452 while (buf
[i
] && (!found
)) {
454 while (buf
[i
] == term
[j
]) {
458 if ((!term
[j
]) && ((buf
[i
] == '|') || (buf
[i
] == ':'))) {
461 while (buf
[i
] && (buf
[i
] != '|') && (buf
[i
] != ':')) {
486 if ((buf
[0] != TAB
) && (buf
[0] != ' ')) {
493 while (buf
[i
] && (buf
[i
] != ':')) {
497 if (!strncmp(buf
+ i
, ":cl=", 4)) {
498 tc_gets(buf
+ i
, &CL
);
499 } else if (!strncmp(buf
+ i
, ":cm=", 4)) {
500 tc_gets(buf
+ i
, &CM
);
501 } else if (!strncmp(buf
+ i
, ":up=", 4)) {
502 tc_gets(buf
+ i
, &UC
);
503 } else if (!strncmp(buf
+ i
, ":do=", 4)) {
504 tc_gets(buf
+ i
, &DO
);
505 } else if (!strncmp(buf
+ i
, ":vs=", 4)) {
506 tc_gets(buf
+ i
, &VS
);
507 } else if (!strncmp(buf
+ i
, ":ve=", 4)) {
508 tc_gets(buf
+ i
, &VE
);
509 } else if (!strncmp(buf
+ i
, ":ti=", 4)) {
510 tc_gets(buf
+ i
, &TI
);
511 } else if (!strncmp(buf
+ i
, ":te=", 4)) {
512 tc_gets(buf
+ i
, &TE
);
513 } else if (!strncmp(buf
+ i
, ":vs=", 4)) {
514 tc_gets(buf
+ i
, &VS
);
515 } else if (!strncmp(buf
+ i
, ":ve=", 4)) {
516 tc_gets(buf
+ i
, &VE
);
517 } else if (!strncmp(buf
+ i
, ":so=", 4)) {
518 tc_gets(buf
+ i
, &SO
);
519 } else if (!strncmp(buf
+ i
, ":se=", 4)) {
520 tc_gets(buf
+ i
, &SE
);
521 } else if (!strncmp(buf
+ i
, ":li#", 4)) {
522 tc_gnum(buf
+ i
, &LINES
);
523 } else if (!strncmp(buf
+ i
, ":co#", 4)) {
524 tc_gnum(buf
+ i
, &COLS
);
529 } while (fgets(buf
, BUFLEN
, fp
) != NULL
);
531 if ((!CM
) || (!CL
)) {
532 clean_up("Terminal and termcap must have cm and cl");
547 while (ibuf
[i
] && is_digit(ibuf
[i
])) {
551 while (ibuf
[i
] && (ibuf
[i
] != ':')) {
552 if (ibuf
[i
] == '\\') {
587 while (k
< 3 && ibuf
[i
] && is_digit(ibuf
[i
])) {
588 n
= (8 * n
) + (ibuf
[i
] - '0');
598 } else if (ibuf
[i
] == '^') {
599 obuf
[j
] = ibuf
[i
+1] - 64;
607 if (!(*tcstr
= md_malloc(j
+ 1))) {
608 clean_up("cannot alloc() memory");
610 (void) strcpy(*tcstr
, obuf
);
622 while (is_digit(ibuf
[i
])) {
623 r
= (r
* 10) + (ibuf
[i
] - '0');
635 printf("%s%s", TI
, VS
);
642 short i
= 0, j
= 0, rc_spec
= 0;
644 while (CM
[i
] && (CM
[i
] != '%') && (j
< 15)) {
645 cm_esc
[j
++] = CM
[i
++];
649 while (CM
[i
] && (rc_spec
< 2)) {
684 while (CM
[i
] && (CM
[i
] != '%')) {
685 cm_sep
[j
++] = CM
[i
++];
693 while (CM
[i
] && (j
< 15)) {
694 cm_end
[j
++] = CM
[i
++];