Annotation of 43BSDTahoe/games/rogue/curses.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.