home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume3 / nethack2.2 / part16 / termcap.c < prev    next >
C/C++ Source or Header  |  1987-12-04  |  8KB  |  409 lines

  1. /*    SCCS Id: @(#)termcap.c    2.1    87/10/19
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  
  4. #include <stdio.h>
  5. #include <ctype.h>    /* for isdigit() */
  6. #include "hack.h"    /* for ROWNO, COLNO, *HI, *HE */
  7. #ifdef GENIX
  8. #define    void    int    /* jhn - mod to prevent compiler from bombing */
  9. #endif
  10.  
  11. extern char *tgetstr(), *tgoto(), *getenv();
  12. extern long *alloc();
  13.  
  14. #ifndef TERMINFO
  15. # ifndef LINT
  16. extern            /* it is defined in libtermlib (libtermcap) */
  17. # endif
  18.     short ospeed;        /* terminal baudrate; used by tputs */
  19. #endif
  20. static char tbuf[512];
  21. static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
  22. static char *VS, *VE, *US, *UE;
  23. static int SG;
  24. static char PC = '\0';
  25. char *CD;        /* tested in pri.c: docorner() */
  26. int CO, LI;        /* used in pri.c and whatis.c */
  27.  
  28. #ifdef MSDOS
  29. static char tgotobuf[20];
  30. #define tgoto(fmt, x, y)    (sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf)
  31. #endif /* MSDOS /**/
  32.  
  33. startup()
  34. {
  35. #ifdef MSDOS
  36.     HO = "\033[H";
  37.     CL = "\033[2J";
  38.     CE = "\033[K";
  39.     UP = "\033[1A";
  40.     CM = "\033[%d;%dH";    /* used with function tgoto() */
  41.     ND = "\033[1C";
  42.     XD = "\033[1B";
  43.     BC = "\033[1D";
  44. # ifdef MSDOSCOLOR    /* creps@silver.bacs.indiana.edu */
  45.     TI = "\033[44;37m";
  46.     TE = "\033[0m";
  47.     VS = VE = "";
  48.     SO = "\033[31m";
  49.     SE = "\033[44;37m";
  50. # else
  51.     TI = TE = VS = VE = "";
  52.       SO = "\033[7m";
  53.       SE = "\033[0m";
  54. # endif
  55.     CD = "\033";
  56.     CO = COLNO;
  57.     LI = ROWNO;
  58. # if defined(DGK) || defined(SORTING)
  59. #  ifdef MSDOSCOLOR
  60.     HI = "\033[32m";
  61.     HE = "\033[44;37m";
  62. #  else
  63.     HI = "\033[4m";
  64.     HE = "\033[0m";
  65. #  endif
  66. # endif
  67. #else /* MSDOS /**/
  68.     register char *term;
  69.     register char *tptr;
  70.     char *tbufptr, *pc;
  71.     register int i;
  72.  
  73.     tptr = (char *) alloc(1024);
  74.  
  75.     tbufptr = tbuf;
  76.     if(!(term = getenv("TERM")))
  77.         error("Can't get TERM.");
  78.     if(!strncmp(term, "5620", 4))
  79.         flags.nonull = 1;    /* this should be a termcap flag */
  80.     if(tgetent(tptr, term) < 1)
  81.         error("Unknown terminal type: %s.", term);
  82.     if(pc = tgetstr("pc", &tbufptr))
  83.         PC = *pc;
  84.     if(!(BC = tgetstr("bc", &tbufptr))) {    
  85.         if(!tgetflag("bs"))
  86.             error("Terminal must backspace.");
  87.         BC = tbufptr;
  88.         tbufptr += 2;
  89.         *BC = '\b';
  90.     }
  91.     HO = tgetstr("ho", &tbufptr);
  92.     CO = tgetnum("co");
  93.     LI = tgetnum("li");
  94.     if(CO < COLNO || LI < ROWNO+2)
  95.         setclipped();
  96.     if(!(CL = tgetstr("cl", &tbufptr)))
  97.         error("Hack needs CL.");
  98.     ND = tgetstr("nd", &tbufptr);
  99.     if(tgetflag("os"))
  100.         error("Hack can't have OS.");
  101.     CE = tgetstr("ce", &tbufptr);
  102.     UP = tgetstr("up", &tbufptr);
  103.     /* It seems that xd is no longer supported, and we should use
  104.        a linefeed instead; unfortunately this requires resetting
  105.        CRMOD, and many output routines will have to be modified
  106.        slightly. Let's leave that till the next release. */
  107.     XD = tgetstr("xd", &tbufptr);
  108. /* not:         XD = tgetstr("do", &tbufptr); */
  109.     if(!(CM = tgetstr("cm", &tbufptr))) {
  110.         if(!UP && !HO)
  111.             error("Hack needs CM or UP or HO.");
  112.         printf("Playing hack on terminals without cm is suspect...\n");
  113.         getret();
  114.     }
  115.     SO = tgetstr("so", &tbufptr);
  116.     SE = tgetstr("se", &tbufptr);
  117.     US = tgetstr("us", &tbufptr);
  118.     UE = tgetstr("ue", &tbufptr);
  119.     SG = tgetnum("sg");    /* -1: not fnd; else # of spaces left by so */
  120.     if(!SO || !SE || (SG > 0)) SO = SE = US = UE = 0;
  121.     TI = tgetstr("ti", &tbufptr);
  122.     TE = tgetstr("te", &tbufptr);
  123.     VS = VE = "";
  124. # ifdef SORTING
  125.     /* Get rid of padding numbers for HI and HE.  Hope they
  126.      * aren't really needed!!!  HI and HE are ouputted to the
  127.      * pager as a string - so how can you send it NULLS???
  128.      *  -jsb
  129.      */
  130.         HI = (char *) alloc(strlen(SO) + 1);
  131.         HE = (char *) alloc(strlen(SE) + 1);
  132.         i = 0;
  133.         while(isdigit(SO[i])) i++;
  134.         strcpy(HI, &SO[i]);
  135.         i = 0;
  136.         while(isdigit(SE[i])) i++;
  137.         strcpy(HE, &SE[i]);
  138. # endif
  139.     CD = tgetstr("cd", &tbufptr);
  140.     set_whole_screen();        /* uses LI and CD */
  141.     if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
  142.     free(tptr);
  143. #endif /* MSDOS /**/
  144. #ifdef MSDOSCOLOR
  145.     init_hilite();
  146. #endif
  147. }
  148.  
  149. start_screen()
  150. {
  151.     xputs(TI);
  152.     xputs(VS);
  153. #ifdef DGK
  154.     /* Select normal ASCII and line drawing character sets.
  155.      */
  156.     if (flags.DECRainbow)
  157.         xputs("\033(B\033)0");
  158. #endif
  159. }
  160.  
  161. end_screen()
  162. {
  163.     clear_screen();
  164.     xputs(VE);
  165.     xputs(TE);
  166. }
  167.  
  168. /* Cursor movements */
  169. extern xchar curx, cury;
  170.  
  171. curs(x, y)
  172. register int x, y;    /* not xchar: perhaps xchar is unsigned and
  173.                curx-x would be unsigned as well */
  174. {
  175.  
  176.     if (y == cury && x == curx)
  177.         return;
  178.     if(!ND && (curx != x || x <= 3)) {    /* Extremely primitive */
  179.         cmov(x, y);            /* bunker!wtm */
  180.         return;
  181.     }
  182.     if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
  183.         nocmov(x, y);
  184.     else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
  185.         (void) putchar('\r');
  186.         curx = 1;
  187.         nocmov(x, y);
  188.     } else if(!CM) {
  189.         nocmov(x, y);
  190.     } else
  191.         cmov(x, y);
  192. }
  193.  
  194. nocmov(x, y)
  195. {
  196.     if (cury > y) {
  197.         if(UP) {
  198.             while (cury > y) {    /* Go up. */
  199.                 xputs(UP);
  200.                 cury--;
  201.             }
  202.         } else if(CM) {
  203.             cmov(x, y);
  204.         } else if(HO) {
  205.             home();
  206.             curs(x, y);
  207.         } /* else impossible("..."); */
  208.     } else if (cury < y) {
  209.         if(XD) {
  210.             while(cury < y) {
  211.                 xputs(XD);
  212.                 cury++;
  213.             }
  214.         } else if(CM) {
  215.             cmov(x, y);
  216.         } else {
  217.             while(cury < y) {
  218.                 xputc('\n');
  219.                 curx = 1;
  220.                 cury++;
  221.             }
  222.         }
  223.     }
  224.     if (curx < x) {        /* Go to the right. */
  225.         if(!ND) cmov(x, y); else    /* bah */
  226.             /* should instead print what is there already */
  227.         while (curx < x) {
  228.             xputs(ND);
  229.             curx++;
  230.         }
  231.     } else if (curx > x) {
  232.         while (curx > x) {    /* Go to the left. */
  233.             xputs(BC);
  234.             curx--;
  235.         }
  236.     }
  237. }
  238.  
  239. cmov(x, y)
  240. register x, y;
  241. {
  242.     xputs(tgoto(CM, x-1, y-1));
  243.     cury = y;
  244.     curx = x;
  245. }
  246.  
  247. xputc(c) char c; {
  248.     (void) fputc(c, stdout);
  249. }
  250.  
  251. xputs(s) char *s; {
  252. #ifdef MSDOS
  253.     fputs(s, stdout);
  254. #else
  255.     tputs(s, 1, xputc);
  256. #endif
  257. }
  258.  
  259. cl_end() {
  260.     if(CE)
  261.         xputs(CE);
  262. /*#ifdef MSDOSCOLOR
  263. /*        xputs(TI);
  264. /*#endif
  265. */
  266.     else {    /* no-CE fix - free after Harold Rynes */
  267.         /* this looks terrible, especially on a slow terminal
  268.            but is better than nothing */
  269.         register cx = curx, cy = cury;
  270.  
  271.         while(curx < COLNO) {
  272.             xputc(' ');
  273.             curx++;
  274.         }
  275.         curs(cx, cy);
  276.     }
  277. }
  278.  
  279. clear_screen() {
  280.     xputs(CL);
  281. #ifdef MSDOSCOLOR
  282.     xputs(TI);
  283. #endif
  284.     home();
  285. }
  286.  
  287. home()
  288. {
  289.     if(HO)
  290.         xputs(HO);
  291.     else if(CM)
  292.         xputs(tgoto(CM, 0, 0));
  293.     else
  294.         curs(1, 1);    /* using UP ... */
  295.     curx = cury = 1;
  296. }
  297.  
  298. standoutbeg()
  299. {
  300.     if(SO) xputs(SO);
  301. }
  302.  
  303. standoutend()
  304. {
  305.     if(SE) xputs(SE);
  306. }
  307.  
  308. backsp()
  309. {
  310.     xputs(BC);
  311.     curx--;
  312. }
  313.  
  314. bell()
  315. {
  316. #ifdef DGKMOD
  317.     if (flags.silent) return;
  318. #endif /* DGKMOD /**/
  319.     (void) putchar('\007');        /* curx does not change */
  320.     (void) fflush(stdout);
  321. }
  322.  
  323. static short tmspc10[] = {        /* from termcap */
  324.     0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
  325. };
  326.  
  327. delay_output() {
  328.     /* delay 50 ms - could also use a 'nap'-system call */
  329.     /* BUG: if the padding character is visible, as it is on the 5620
  330.        then this looks terrible. */
  331. #ifdef MSDOS
  332.     /* simulate the delay with "cursor here" */
  333.     register i;
  334.     for (i = 0; i < 3; i++) {
  335.         cmov(curx, cury);
  336.         (void) fflush(stdout);
  337.     }
  338. #else
  339.     if(!flags.nonull)
  340. #ifdef TERMINFO
  341.         tputs("$<50>", 1, xputs);
  342. #else
  343.         tputs("50", 1, xputs);
  344. #endif
  345.         /* cbosgd!cbcephus!pds for SYS V R2 */
  346.         /* is this terminfo, or what? */
  347.         /* tputs("$<50>", 1, xputc); */
  348.  
  349.     else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) {
  350.         /* delay by sending cm(here) an appropriate number of times */
  351.         register int cmlen = strlen(tgoto(CM, curx-1, cury-1));
  352.         register int i = 500 + tmspc10[ospeed]/2;
  353.  
  354.         while(i > 0) {
  355.             cmov(curx, cury);
  356.             i -= cmlen*tmspc10[ospeed];
  357.         }
  358.     }
  359. #endif /* MSDOS /**/
  360. }
  361.  
  362. cl_eos()            /* free after Robert Viduya */
  363. {                /* must only be called with curx = 1 */
  364.  
  365.     if(CD)
  366.         xputs(CD);
  367.     else {
  368.         register int cx = curx, cy = cury;
  369.         while(cury <= LI-2) {
  370.             cl_end();
  371.             xputc('\n');
  372.             curx = 1;
  373.             cury++;
  374.         }
  375.         cl_end();
  376.         curs(cx, cy);
  377.     }
  378. }
  379.  
  380. #ifdef MSDOSCOLOR
  381.  
  382. #define ESCCHR        '\033'
  383. #define HILITE_ATTRIB    1    /* highlight */
  384.  
  385. #define HILITE_MONSTER    1    /* red */
  386. #define HILITE_OBJECT    2    /* green */
  387.  
  388. init_hilite()
  389. {
  390.     register int hilen, def_background;
  391.  
  392.     /* find default background color */
  393.     hilen = strlen(HI) - 1;
  394.     if (hilen < 5) def_background = 0;    /* black */
  395.     else {
  396.         if (!isdigit(HI[hilen-1])) def_background = 0;
  397.         else def_background = HI[hilen-1];
  398.     }
  399.  
  400.     HI_MON = (char *) alloc(sizeof("E[0;33;44m"));
  401.     sprintf(HI_MON, "%c[%d;3%d;4%dm", ESCCHR, HILITE_ATTRIB, 
  402.             HILITE_MONSTER, def_background);
  403.     HI_OBJ = (char *) alloc(sizeof("E[0;33;44m"));
  404.     sprintf(HI_OBJ, "%c[%d;3%d;4%dm", ESCCHR, HILITE_ATTRIB, 
  405.             HILITE_OBJECT, def_background);
  406. }
  407.  
  408. #endif /* MSDOSCOLOR */
  409.