]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - rogue/curses.c
2 * Copyright (c) 1988 The Regents of the University of California.
5 * This code is derived from software contributed to Berkeley by
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 /*static char sccsid[] = "from: @(#)curses.c 5.3 (Berkeley) 6/1/90";*/
39 static char rcsid
[] = "$Id: curses.c,v 1.2 1993/08/01 18:52:32 mycroft Exp $";
45 * This source herein may be modified and/or distributed by anybody who
46 * so desires, with the following restrictions:
47 * 1.) No portion of this notice shall be removed.
48 * 2.) Credit shall not be taken for the creation of this source.
49 * 3.) This code is not to be traded, sold, or used for personal
56 /* The following is a curses emulation package suitable for the rogue program
57 * in which it is included. No other suitability is claimed or suspected.
58 * Only those routines currently needed by this rogue program are included.
59 * This is being provided for those systems that don't have a suitable
60 * curses package and want to run this rogue program.
62 * Compile the entire program with -DCURSES to incorporate this package.
64 * The following is NOT supported:
65 * "%D", "%B", "%n", or "%>" inside a cursor motion (cm) termcap string.
66 * Terminals in which the cursor motion addresses the row differently from
67 * the column, as in ":cm=\E%2,%3" or ":cm=\EY%+x;%+y"
68 * Termcap database stored in the TERMCAP environ variable as returned
69 * from md_getenv(). Only the termcap file name can be stored there.
70 * See the comments for md_getenv() in machdep.c.
71 * Terminals without non-destructive backspace. Backspace (^H) is used
72 * for cursor motion regardless of any termcap entries.
73 * The ":tc=" termcap entry is ignored.
76 * Use line-feed as your termcap "do" entry: ":do=^J", ":do=\012" or
77 * ":do=\n" This will help cursor motion optimization. If line-feed
78 * won't work, then a short escape sequence will do.
95 char terminal
[DROWS
][DCOLS
];
96 char buffer
[DROWS
][DCOLS
];
102 boolean cm_reverse
= 0;
104 boolean cm_three
= 0;
108 boolean screen_dirty
;
109 boolean lines_dirty
[DROWS
];
110 boolean buf_stand_out
= 0;
111 boolean term_stand_out
= 0;
116 WINDOW
*curscr
= &scr_buf
;
118 char *CL
= (char *) 0;
119 char *CM
= (char *) 0;
120 char *UC
= (char *) 0; /* UP */
121 char *DO
= (char *) 0;
136 printf("%s%s", TI
, VS
);
141 printf("%s%s", TE
, VE
);
142 md_cbreak_no_echo_nonl(0);
153 mvaddstr(row
, col
, str
)
175 col
= curscr
->_curx
++;
180 buffer
[row
][col
] = (char) ch
;
181 lines_dirty
[row
] = 1;
185 mvaddch(row
, col
, ch
)
196 short old_row
, old_col
, first_row
;
200 old_row
= curscr
->_cury
;
201 old_col
= curscr
->_curx
;
204 for (i
= 0; i
< DROWS
; i
++) {
205 line
= (first_row
+ i
) % DROWS
;
206 if (lines_dirty
[line
]) {
207 for (j
= 0; j
< DCOLS
; j
++) {
208 if (buffer
[line
][j
] != terminal
[line
][j
]) {
209 put_char_at(line
, j
, buffer
[line
][j
]);
212 lines_dirty
[line
] = 0;
215 put_cursor(old_row
, old_col
);
227 cur_row
= cur_col
= 0;
229 for (i
= 0; i
< DROWS
; i
++) {
231 while (col
< DCOLS
) {
232 while ((col
< DCOLS
) && (buffer
[i
][col
] == ' ')) {
238 while ((col
< DCOLS
) && (buffer
[i
][col
] != ' ')) {
239 put_st_char((int) buffer
[i
][col
]);
245 put_cursor(curscr
->_cury
, curscr
->_curx
);
247 scr
= scr
; /* make lint happy */
254 return((int) buffer
[row
][col
]);
261 cur_row
= cur_col
= 0;
272 for (col
= curscr
->_curx
; col
< DCOLS
; col
++) {
273 buffer
[row
][col
] = ' ';
275 lines_dirty
[row
] = 1;
290 md_cbreak_no_echo_nonl(1);
295 /* crmode() takes care of this */
300 /* crmode() takes care of this */
309 for (i
= 0; i
< DROWS
; i
++) {
311 for (j
= 0; j
< DCOLS
; j
++) {
312 terminal
[i
][j
] = ' ';
318 put_char_at(row
, col
, ch
)
319 register row
, col
, ch
;
321 put_cursor(row
, col
);
323 terminal
[row
][col
] = (char) ch
;
330 register i
, rdif
, cdif
;
333 rdif
= (row
> cur_row
) ? row
- cur_row
: cur_row
- row
;
334 cdif
= (col
> cur_col
) ? col
- cur_col
: cur_col
- col
;
336 if (((row
> cur_row
) && DO
) || ((cur_row
> row
) && UC
)) {
337 if ((rdif
< 4) && (cdif
< 4)) {
338 for (i
= 0; i
< rdif
; i
++) {
339 printf("%s", ((row
< cur_row
) ? UC
: DO
));
342 if (col
== cur_col
) {
347 if (row
== cur_row
) {
349 for (i
= 0; i
< cdif
; i
++) {
350 ch
= (col
< cur_col
) ? BS
:
351 terminal
[row
][cur_col
+ i
];
352 put_st_char((int) ch
);
371 printf("%s%02d%s%02d%s", cm_esc
, row
, cm_sep
, col
, cm_end
);
372 } else if (cm_three
) {
373 printf("%s%03d%s%03d%s", cm_esc
, row
, cm_sep
, col
, cm_end
);
374 } else if (cm_char
) {
375 printf("%s%c%s%c%s", cm_esc
, row
, cm_sep
, col
, cm_end
);
377 printf("%s%d%s%d%s", cm_esc
, row
, cm_sep
, col
, cm_end
);
384 if ((ch
& ST_MASK
) && (!term_stand_out
)) {
386 printf("%s%c", SO
, ch
);
388 } else if ((!(ch
& ST_MASK
)) && term_stand_out
) {
389 printf("%s%c", SE
, ch
);
403 if (tcf
= md_getenv("TERMCAP")) {
404 if (strlen(tcf
) > 40) {
405 clean_up("TERMCAP file name too long");
409 if (!(tc_file
= md_gdtcf())) {
410 clean_up("I need a termcap file");
414 if (!(term
= md_getenv("TERM"))) {
415 clean_up("Cannot find TERM variable in environ");
417 if ((fp
= fopen(tc_file
, "r")) == NULL
) {
418 sprintf(buf
, "Cannot open TERMCAP file: %s", tc_file
);
422 if (!tc_tname(fp
, term
, buf
)) {
423 sprintf(buf
, "Cannot find TERM type: %s in TERMCAP file: %s", term
,
432 tc_tname(fp
, term
, buf
)
443 fg
= fgets(buf
, BUFLEN
, fp
);
445 if ( (buf
[0] != '#') && (buf
[0] != ' ') && (buf
[0] != TAB
) &&
446 (buf
[0] != CR
) && (buf
[0] != LF
)) {
447 while (buf
[i
] && (!found
)) {
449 while (buf
[i
] == term
[j
]) {
453 if ((!term
[j
]) && ((buf
[i
] == '|') || (buf
[i
] == ':'))) {
456 while (buf
[i
] && (buf
[i
] != '|') && (buf
[i
] != ':')) {
481 if ((buf
[0] != TAB
) && (buf
[0] != ' ')) {
488 while (buf
[i
] && (buf
[i
] != ':')) {
492 if (!strncmp(buf
+ i
, ":cl=", 4)) {
493 tc_gets(buf
+ i
, &CL
);
494 } else if (!strncmp(buf
+ i
, ":cm=", 4)) {
495 tc_gets(buf
+ i
, &CM
);
496 } else if (!strncmp(buf
+ i
, ":up=", 4)) {
497 tc_gets(buf
+ i
, &UC
);
498 } else if (!strncmp(buf
+ i
, ":do=", 4)) {
499 tc_gets(buf
+ i
, &DO
);
500 } else if (!strncmp(buf
+ i
, ":vs=", 4)) {
501 tc_gets(buf
+ i
, &VS
);
502 } else if (!strncmp(buf
+ i
, ":ve=", 4)) {
503 tc_gets(buf
+ i
, &VE
);
504 } else if (!strncmp(buf
+ i
, ":ti=", 4)) {
505 tc_gets(buf
+ i
, &TI
);
506 } else if (!strncmp(buf
+ i
, ":te=", 4)) {
507 tc_gets(buf
+ i
, &TE
);
508 } else if (!strncmp(buf
+ i
, ":vs=", 4)) {
509 tc_gets(buf
+ i
, &VS
);
510 } else if (!strncmp(buf
+ i
, ":ve=", 4)) {
511 tc_gets(buf
+ i
, &VE
);
512 } else if (!strncmp(buf
+ i
, ":so=", 4)) {
513 tc_gets(buf
+ i
, &SO
);
514 } else if (!strncmp(buf
+ i
, ":se=", 4)) {
515 tc_gets(buf
+ i
, &SE
);
516 } else if (!strncmp(buf
+ i
, ":li#", 4)) {
517 tc_gnum(buf
+ i
, &LINES
);
518 } else if (!strncmp(buf
+ i
, ":co#", 4)) {
519 tc_gnum(buf
+ i
, &COLS
);
524 } while (fgets(buf
, BUFLEN
, fp
) != NULL
);
526 if ((!CM
) || (!CL
)) {
527 clean_up("Terminal and termcap must have cm and cl");
542 while (ibuf
[i
] && is_digit(ibuf
[i
])) {
546 while (ibuf
[i
] && (ibuf
[i
] != ':')) {
547 if (ibuf
[i
] == '\\') {
582 while (k
< 3 && ibuf
[i
] && is_digit(ibuf
[i
])) {
583 n
= (8 * n
) + (ibuf
[i
] - '0');
593 } else if (ibuf
[i
] == '^') {
594 obuf
[j
] = ibuf
[i
+1] - 64;
602 if (!(*tcstr
= md_malloc(j
+ 1))) {
603 clean_up("cannot alloc() memory");
605 (void) strcpy(*tcstr
, obuf
);
617 while (is_digit(ibuf
[i
])) {
618 r
= (r
* 10) + (ibuf
[i
] - '0');
630 printf("%s%s", TI
, VS
);
637 short i
= 0, j
= 0, rc_spec
= 0;
639 while (CM
[i
] && (CM
[i
] != '%') && (j
< 15)) {
640 cm_esc
[j
++] = CM
[i
++];
644 while (CM
[i
] && (rc_spec
< 2)) {
679 while (CM
[i
] && (CM
[i
] != '%')) {
680 cm_sep
[j
++] = CM
[i
++];
688 while (CM
[i
] && (j
< 15)) {
689 cm_end
[j
++] = CM
[i
++];