summaryrefslogtreecommitdiffstats
path: root/games/rogue/curses.c
diff options
context:
space:
mode:
Diffstat (limited to 'games/rogue/curses.c')
-rw-r--r--games/rogue/curses.c694
1 files changed, 694 insertions, 0 deletions
diff --git a/games/rogue/curses.c b/games/rogue/curses.c
new file mode 100644
index 0000000..95fd11e
--- /dev/null
+++ b/games/rogue/curses.c
@@ -0,0 +1,694 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Timothy C. Stoehr.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)curses.c 8.1 (Berkeley) 5/31/93";
+#endif /* not lint */
+
+/*
+ * curses.c
+ *
+ * This source herein may be modified and/or distributed by anybody who
+ * so desires, with the following restrictions:
+ * 1.) No portion of this notice shall be removed.
+ * 2.) Credit shall not be taken for the creation of this source.
+ * 3.) This code is not to be traded, sold, or used for personal
+ * gain or profit.
+ *
+ */
+
+#ifdef CURSES
+
+/* The following is a curses emulation package suitable for the rogue program
+ * in which it is included. No other suitability is claimed or suspected.
+ * Only those routines currently needed by this rogue program are included.
+ * This is being provided for those systems that don't have a suitable
+ * curses package and want to run this rogue program.
+ *
+ * Compile the entire program with -DCURSES to incorporate this package.
+ *
+ * The following is NOT supported:
+ * "%D", "%B", "%n", or "%>" inside a cursor motion (cm) termcap string.
+ * Terminals in which the cursor motion addresses the row differently from
+ * the column, as in ":cm=\E%2,%3" or ":cm=\EY%+x;%+y"
+ * Termcap database stored in the TERMCAP environ variable as returned
+ * from md_getenv(). Only the termcap file name can be stored there.
+ * See the comments for md_getenv() in machdep.c.
+ * Terminals without non-destructive backspace. Backspace (^H) is used
+ * for cursor motion regardless of any termcap entries.
+ * The ":tc=" termcap entry is ignored.
+ *
+ * Suggestions:
+ * Use line-feed as your termcap "do" entry: ":do=^J", ":do=\012" or
+ * ":do=\n" This will help cursor motion optimization. If line-feed
+ * won't work, then a short escape sequence will do.
+ */
+
+#include <stdio.h>
+#include "rogue.h"
+
+boolean tc_tname();
+
+#define BS 010
+#define LF 012
+#define CR 015
+#define ESC '\033'
+#define TAB '\011'
+
+#define ST_MASK 0x80
+#define BUFLEN 256
+
+char terminal[DROWS][DCOLS];
+char buffer[DROWS][DCOLS];
+char *tc_file;
+
+char cm_esc[16];
+char cm_sep[16];
+char cm_end[16];
+boolean cm_reverse = 0;
+boolean cm_two = 0;
+boolean cm_three = 0;
+boolean cm_char = 0;
+short cm_inc = 0;
+
+boolean screen_dirty;
+boolean lines_dirty[DROWS];
+boolean buf_stand_out = 0;
+boolean term_stand_out = 0;
+
+int LINES = DROWS;
+int COLS = DCOLS;
+WINDOW scr_buf;
+WINDOW *curscr = &scr_buf;
+
+char *CL = (char *) 0;
+char *CM = (char *) 0;
+char *UC = (char *) 0; /* UP */
+char *DO = (char *) 0;
+char *VS = "";
+char *VE = "";
+char *TI = "";
+char *TE = "";
+char *SO = "";
+char *SE = "";
+
+short cur_row;
+short cur_col;
+
+initscr()
+{
+ clear();
+ get_term_info();
+ printf("%s%s", TI, VS);
+}
+
+endwin()
+{
+ printf("%s%s", TE, VE);
+ md_cbreak_no_echo_nonl(0);
+}
+
+move(row, col)
+short row, col;
+{
+ curscr->_cury = row;
+ curscr->_curx = col;
+ screen_dirty = 1;
+}
+
+mvaddstr(row, col, str)
+short row, col;
+char *str;
+{
+ move(row, col);
+ addstr(str);
+}
+
+addstr(str)
+char *str;
+{
+ while (*str) {
+ addch((int) *str++);
+ }
+}
+
+addch(ch)
+register int ch;
+{
+ short row, col;
+
+ row = curscr->_cury;
+ col = curscr->_curx++;
+
+ if (buf_stand_out) {
+ ch |= ST_MASK;
+ }
+ buffer[row][col] = (char) ch;
+ lines_dirty[row] = 1;
+ screen_dirty = 1;
+}
+
+mvaddch(row, col, ch)
+short row, col;
+int ch;
+{
+ move(row, col);
+ addch(ch);
+}
+
+refresh()
+{
+ register i, j, line;
+ short old_row, old_col, first_row;
+
+ if (screen_dirty) {
+
+ old_row = curscr->_cury;
+ old_col = curscr->_curx;
+ first_row = cur_row;
+
+ for (i = 0; i < DROWS; i++) {
+ line = (first_row + i) % DROWS;
+ if (lines_dirty[line]) {
+ for (j = 0; j < DCOLS; j++) {
+ if (buffer[line][j] != terminal[line][j]) {
+ put_char_at(line, j, buffer[line][j]);
+ }
+ }
+ lines_dirty[line] = 0;
+ }
+ }
+ put_cursor(old_row, old_col);
+ screen_dirty = 0;
+ fflush(stdout);
+ }
+}
+
+wrefresh(scr)
+WINDOW *scr;
+{
+ short i, col;
+
+ printf("%s", CL);
+ cur_row = cur_col = 0;
+
+ for (i = 0; i < DROWS; i++) {
+ col = 0;
+ while (col < DCOLS) {
+ while ((col < DCOLS) && (buffer[i][col] == ' ')) {
+ col++;
+ }
+ if (col < DCOLS) {
+ put_cursor(i, col);
+ }
+ while ((col < DCOLS) && (buffer[i][col] != ' ')) {
+ put_st_char((int) buffer[i][col]);
+ cur_col++;
+ col++;
+ }
+ }
+ }
+ put_cursor(curscr->_cury, curscr->_curx);
+ fflush(stdout);
+ scr = scr; /* make lint happy */
+}
+
+mvinch(row, col)
+short row, col;
+{
+ move(row, col);
+ return((int) buffer[row][col]);
+}
+
+clear()
+{
+ printf("%s", CL);
+ fflush(stdout);
+ cur_row = cur_col = 0;
+ move(0, 0);
+ clear_buffers();
+}
+
+clrtoeol()
+{
+ short row, col;
+
+ row = curscr->_cury;
+
+ for (col = curscr->_curx; col < DCOLS; col++) {
+ buffer[row][col] = ' ';
+ }
+ lines_dirty[row] = 1;
+}
+
+standout()
+{
+ buf_stand_out = 1;
+}
+
+standend()
+{
+ buf_stand_out = 0;
+}
+
+crmode()
+{
+ md_cbreak_no_echo_nonl(1);
+}
+
+noecho()
+{
+ /* crmode() takes care of this */
+}
+
+nonl()
+{
+ /* crmode() takes care of this */
+}
+
+clear_buffers()
+{
+ register i, j;
+
+ screen_dirty = 0;
+
+ for (i = 0; i < DROWS; i++) {
+ lines_dirty[i] = 0;
+ for (j = 0; j < DCOLS; j++) {
+ terminal[i][j] = ' ';
+ buffer[i][j] = ' ';
+ }
+ }
+}
+
+put_char_at(row, col, ch)
+register row, col, ch;
+{
+ put_cursor(row, col);
+ put_st_char(ch);
+ terminal[row][col] = (char) ch;
+ cur_col++;
+}
+
+put_cursor(row, col)
+register row, col;
+{
+ register i, rdif, cdif;
+ short ch, t;
+
+ rdif = (row > cur_row) ? row - cur_row : cur_row - row;
+ cdif = (col > cur_col) ? col - cur_col : cur_col - col;
+
+ if (((row > cur_row) && DO) || ((cur_row > row) && UC)) {
+ if ((rdif < 4) && (cdif < 4)) {
+ for (i = 0; i < rdif; i++) {
+ printf("%s", ((row < cur_row) ? UC : DO));
+ }
+ cur_row = row;
+ if (col == cur_col) {
+ return;
+ }
+ }
+ }
+ if (row == cur_row) {
+ if (cdif <= 6) {
+ for (i = 0; i < cdif; i++) {
+ ch = (col < cur_col) ? BS :
+ terminal[row][cur_col + i];
+ put_st_char((int) ch);
+ }
+ cur_row = row;
+ cur_col = col;
+ return;
+ }
+ }
+ cur_row = row;
+ cur_col = col;
+
+ row += cm_inc;
+ col += cm_inc;
+
+ if (cm_reverse) {
+ t = row;
+ row = col;
+ col = t;
+ }
+ if (cm_two) {
+ printf("%s%02d%s%02d%s", cm_esc, row, cm_sep, col, cm_end);
+ } else if (cm_three) {
+ printf("%s%03d%s%03d%s", cm_esc, row, cm_sep, col, cm_end);
+ } else if (cm_char) {
+ printf("%s%c%s%c%s", cm_esc, row, cm_sep, col, cm_end);
+ } else {
+ printf("%s%d%s%d%s", cm_esc, row, cm_sep, col, cm_end);
+ }
+}
+
+put_st_char(ch)
+register ch;
+{
+ if ((ch & ST_MASK) && (!term_stand_out)) {
+ ch &= ~ST_MASK;
+ printf("%s%c", SO, ch);
+ term_stand_out = 1;
+ } else if ((!(ch & ST_MASK)) && term_stand_out) {
+ printf("%s%c", SE, ch);
+ term_stand_out = 0;
+ } else {
+ ch &= ~ST_MASK;
+ putchar(ch);
+ }
+}
+
+get_term_info()
+{
+ FILE *fp;
+ char *term, *tcf;
+ char buf[BUFLEN];
+
+ if (tcf = md_getenv("TERMCAP")) {
+ if (strlen(tcf) > 40) {
+ clean_up("TERMCAP file name too long");
+ }
+ tc_file = tcf;
+ } else {
+ if (!(tc_file = md_gdtcf())) {
+ clean_up("I need a termcap file");
+ }
+ }
+
+ if (!(term = md_getenv("TERM"))) {
+ clean_up("Cannot find TERM variable in environ");
+ }
+ if ((fp = fopen(tc_file, "r")) == NULL) {
+ sprintf(buf, "Cannot open TERMCAP file: %s", tc_file);
+ clean_up(buf);
+ }
+
+ if (!tc_tname(fp, term, buf)) {
+ sprintf(buf, "Cannot find TERM type: %s in TERMCAP file: %s", term,
+ tc_file);
+ clean_up(buf);
+ }
+ tc_gtdata(fp, buf);
+ fclose(fp);
+}
+
+boolean
+tc_tname(fp, term, buf)
+FILE *fp;
+char *term;
+char *buf;
+{
+ short i, j;
+ boolean found = 0;
+ char *fg;
+
+ while (!found) {
+ i = 0;
+ fg = fgets(buf, BUFLEN, fp);
+ if (fg != NULL) {
+ if ( (buf[0] != '#') && (buf[0] != ' ') && (buf[0] != TAB) &&
+ (buf[0] != CR) && (buf[0] != LF)) {
+ while (buf[i] && (!found)) {
+ j = 0;
+ while (buf[i] == term[j]) {
+ i++;
+ j++;
+ }
+ if ((!term[j]) && ((buf[i] == '|') || (buf[i] == ':'))) {
+ found = 1;
+ } else {
+ while (buf[i] && (buf[i] != '|') && (buf[i] != ':')) {
+ i++;
+ }
+ if (buf[i]) {
+ i++;
+ }
+ }
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ return(found);
+}
+
+tc_gtdata(fp, buf)
+FILE *fp;
+char *buf;
+{
+ short i;
+ boolean first = 1;
+
+ do {
+ if (!first) {
+ if ((buf[0] != TAB) && (buf[0] != ' ')) {
+ break;
+ }
+ }
+ first = 0;
+ i = 0;
+ while (buf[i]) {
+ while (buf[i] && (buf[i] != ':')) {
+ i++;
+ }
+ if (buf[i] == ':') {
+ if (!strncmp(buf + i, ":cl=", 4)) {
+ tc_gets(buf + i, &CL);
+ } else if (!strncmp(buf + i, ":cm=", 4)) {
+ tc_gets(buf + i, &CM);
+ } else if (!strncmp(buf + i, ":up=", 4)) {
+ tc_gets(buf + i, &UC);
+ } else if (!strncmp(buf + i, ":do=", 4)) {
+ tc_gets(buf + i, &DO);
+ } else if (!strncmp(buf + i, ":vs=", 4)) {
+ tc_gets(buf + i, &VS);
+ } else if (!strncmp(buf + i, ":ve=", 4)) {
+ tc_gets(buf + i, &VE);
+ } else if (!strncmp(buf + i, ":ti=", 4)) {
+ tc_gets(buf + i, &TI);
+ } else if (!strncmp(buf + i, ":te=", 4)) {
+ tc_gets(buf + i, &TE);
+ } else if (!strncmp(buf + i, ":vs=", 4)) {
+ tc_gets(buf + i, &VS);
+ } else if (!strncmp(buf + i, ":ve=", 4)) {
+ tc_gets(buf + i, &VE);
+ } else if (!strncmp(buf + i, ":so=", 4)) {
+ tc_gets(buf + i, &SO);
+ } else if (!strncmp(buf + i, ":se=", 4)) {
+ tc_gets(buf + i, &SE);
+ } else if (!strncmp(buf + i, ":li#", 4)) {
+ tc_gnum(buf + i, &LINES);
+ } else if (!strncmp(buf + i, ":co#", 4)) {
+ tc_gnum(buf + i, &COLS);
+ }
+ i++;
+ }
+ }
+ } while (fgets(buf, BUFLEN, fp) != NULL);
+
+ if ((!CM) || (!CL)) {
+ clean_up("Terminal and termcap must have cm and cl");
+ }
+ tc_cmget();
+}
+
+tc_gets(ibuf, tcstr)
+char *ibuf;
+char **tcstr;
+{
+ short i, j, k, n;
+ char obuf[BUFLEN];
+
+ i = 4;
+ j = 0;
+
+ while (ibuf[i] && is_digit(ibuf[i])) {
+ i++;
+ }
+
+ while (ibuf[i] && (ibuf[i] != ':')) {
+ if (ibuf[i] == '\\') {
+ i++;
+ switch(ibuf[i]) {
+ case 'E':
+ obuf[j] = ESC;
+ i++;
+ break;
+ case 'n':
+ obuf[j] = LF;
+ i++;
+ break;
+ case 'r':
+ obuf[j] = CR;
+ i++;
+ break;
+ case 'b':
+ obuf[j] = BS;
+ i++;
+ break;
+ case 't':
+ obuf[j] = TAB;
+ i++;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ n = 0;
+ k = 0;
+ while (k < 3 && ibuf[i] && is_digit(ibuf[i])) {
+ n = (8 * n) + (ibuf[i] - '0');
+ i++;
+ k++;
+ }
+ obuf[j] = (char) n;
+ break;
+ default:
+ obuf[j] = ibuf[i];
+ i++;
+ }
+ } else if (ibuf[i] == '^') {
+ obuf[j] = ibuf[i+1] - 64;
+ i += 2;
+ } else {
+ obuf[j] = ibuf[i++];
+ }
+ j++;
+ }
+ obuf[j] = 0;
+ if (!(*tcstr = md_malloc(j + 1))) {
+ clean_up("cannot alloc() memory");
+ }
+ (void) strcpy(*tcstr, obuf);
+}
+
+tc_gnum(ibuf, n)
+char *ibuf;
+int *n;
+{
+ short i;
+ int r = 0;
+
+ i = 4;
+
+ while (is_digit(ibuf[i])) {
+ r = (r * 10) + (ibuf[i] - '0');
+ i++;
+ }
+ *n = r;
+}
+
+tstp()
+{
+ endwin();
+ md_tstp();
+
+ start_window();
+ printf("%s%s", TI, VS);
+ wrefresh(curscr);
+ md_slurp();
+}
+
+tc_cmget()
+{
+ short i = 0, j = 0, rc_spec = 0;
+
+ while (CM[i] && (CM[i] != '%') && (j < 15)) {
+ cm_esc[j++] = CM[i++];
+ }
+ cm_esc[j] = 0;
+
+ while (CM[i] && (rc_spec < 2)) {
+ if (CM[i] == '%') {
+ i++;
+ switch(CM[i]) {
+ case 'd':
+ rc_spec++;
+ break;
+ case 'i':
+ cm_inc = 1;
+ break;
+ case '2':
+ cm_two = 1;
+ rc_spec++;
+ break;
+ case '3':
+ cm_three = 1;
+ rc_spec++;
+ break;
+ case '.':
+ cm_char = 1;
+ rc_spec++;
+ break;
+ case 'r':
+ cm_reverse = 1;
+ break;
+ case '+':
+ i++;
+ cm_inc = CM[i];
+ cm_char = 1;
+ rc_spec++;
+ break;
+ }
+ i++;
+ } else {
+ j = 0;
+ while (CM[i] && (CM[i] != '%')) {
+ cm_sep[j++] = CM[i++];
+ }
+ cm_sep[j] = 0;
+ }
+ }
+
+ j = 0;
+ if (rc_spec == 2) {
+ while (CM[i] && (j < 15)) {
+ cm_end[j++] = CM[i++];
+ }
+ }
+ cm_end[j] = 0;
+}
+
+#endif
OpenPOWER on IntegriCloud