home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / nethack-3.1 / win / tty / topl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-18  |  7.8 KB  |  343 lines

  1. /*    SCCS Id: @(#)topl.c    3.1    90/09/21
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "termcap.h"
  7. #include "wintty.h"
  8. #include <ctype.h>
  9.  
  10. STATIC_DCL void FDECL(redotoplin, (const char*));
  11. STATIC_DCL void FDECL(topl_putsym, (CHAR_P));
  12. STATIC_DCL void NDECL(remember_topl);
  13. static void FDECL(removetopl, (int));
  14.  
  15. #ifdef OVLB
  16.  
  17. int
  18. tty_doprev_message()
  19. {
  20.     register struct WinDesc *cw = wins[WIN_MESSAGE];
  21.  
  22.     if(cw->data[cw->maxcol])
  23.     redotoplin(cw->data[cw->maxcol]);
  24.     else if(cw->maxcol == cw->maxrow)
  25.     redotoplin(toplines);
  26.     cw->maxcol--;
  27.     if(cw->maxcol < 0) cw->maxcol = cw->rows-1;
  28.     if(!cw->data[cw->maxcol])
  29.     cw->maxcol = cw->maxrow;
  30.     return 0;
  31. }
  32.  
  33. #endif /* OVLB */
  34. #ifdef OVL1
  35.  
  36. STATIC_OVL void
  37. redotoplin(str)
  38.     const char *str;
  39. {
  40.     int otoplin = ttyDisplay->toplin;
  41.     home();
  42.     if(*str & 0x80) {
  43.         /* kludge for the / command, the only time we ever want a */
  44.         /* graphics character on the top line */
  45.         g_putch(*str++);
  46.         ttyDisplay->curx++;
  47.     }
  48.     end_glyphout();    /* in case message printed during graphics output */
  49.     putsyms(str);
  50.     cl_end();
  51.     ttyDisplay->toplin = 1;
  52.     if(ttyDisplay->cury && otoplin != 3)
  53.         more();
  54. }
  55.  
  56. STATIC_OVL void
  57. remember_topl()
  58. {
  59.     register struct WinDesc *cw = wins[WIN_MESSAGE];
  60.  
  61.     cw->data[cw->maxrow] = (char*) alloc(strlen(toplines)+1);
  62.     Strcpy(cw->data[cw->maxrow], toplines);
  63.     cw->maxcol = cw->maxrow = (cw->maxrow+1) % cw->rows;
  64.     if(cw->data[cw->maxrow]) {
  65.     free((genericptr_t)cw->data[cw->maxrow]);
  66.     cw->data[cw->maxrow] = 0;
  67.     }
  68. }
  69.  
  70. void
  71. addtopl(s)
  72. const char *s;
  73. {
  74.     register struct WinDesc *cw = wins[WIN_MESSAGE];
  75.  
  76.     tty_curs(BASE_WINDOW,cw->curx+1,cw->cury);
  77.     if(cw->curx + (int)strlen(s) >= CO) topl_putsym('\n');
  78.     putsyms(s);
  79.     cl_end();
  80.     ttyDisplay->toplin = 1;
  81. }
  82.  
  83. #endif /* OVL1 */
  84. #ifdef OVL2
  85.  
  86. void
  87. more()
  88. {
  89.     struct WinDesc *cw = wins[WIN_MESSAGE];
  90.  
  91.     /* avoid recursion -- only happens from interrupts */
  92.     if(ttyDisplay->inmore++)
  93.     return;
  94.  
  95.     if(ttyDisplay->toplin) {
  96.     tty_curs(BASE_WINDOW, cw->curx+1, cw->cury);
  97.     if(cw->curx >= CO - 8) topl_putsym('\n');
  98.     }
  99.  
  100.     if(flags.standout)
  101.     standoutbeg();
  102.     putsyms(defmorestr);
  103.     if(flags.standout)
  104.     standoutend();
  105.  
  106.     xwaitforspace("\033");
  107.  
  108.     if(morc == '\033')
  109.     cw->flags |= WIN_STOP;
  110.  
  111.     if(ttyDisplay->toplin && cw->cury) {
  112.     docorner(1, cw->cury+1);
  113.     cw->curx = cw->cury = 0;
  114.     home();
  115.     } else if(morc == '\033') {
  116.     cw->curx = cw->cury = 0;
  117.     home();
  118.     cl_end();
  119.     }
  120.     ttyDisplay->toplin = 0;
  121.     ttyDisplay->inmore = 0;
  122. }
  123.  
  124. void
  125. update_topl(bp)
  126.     register const char *bp;
  127. {
  128.     register char *tl, *otl;
  129.     register int n0;
  130.     int notdied = 1;
  131.     struct WinDesc *cw = wins[WIN_MESSAGE];
  132.  
  133.     /* If there is room on the line, print message on same line */
  134.     /* But messages like "You die..." deserve their own line */
  135.     n0 = strlen(bp);
  136.     if(ttyDisplay->toplin == 1 && cw->cury == 0 &&
  137.         n0 + (int)strlen(toplines) + 3 < CO-8 &&  /* room for --More-- */
  138.         (notdied = strncmp(bp, "You die", 7))) {
  139.         Strcat(toplines, "  ");
  140.         Strcat(toplines, bp);
  141.         cw->curx += 2;
  142.         if(!(cw->flags & WIN_STOP))
  143.             addtopl(bp);
  144.         return;
  145.     } else if(!(cw->flags & WIN_STOP)) {
  146.         if(ttyDisplay->toplin == 1) more();
  147.         else if(cw->cury) {    /* for when flags.toplin == 2 && cury > 1 */
  148.         docorner(1, cw->cury+1); /* reset cury = 0 if redraw screen */
  149.         cw->curx = cw->cury = 0;/* from home--cls() & docorner(1,n) */
  150.         }
  151.     }
  152.     remember_topl();
  153.     Strcpy(toplines, bp);
  154.     for(tl = toplines; n0 >= CO; ){
  155.         otl = tl;
  156.         for(tl+=CO-1; tl != otl && !isspace(*tl); --tl) ;
  157.         if(tl == otl) {
  158.         /* Eek!  A huge token.  Try splitting after it. */
  159.         tl = index(otl, ' ');
  160.         if (!tl) break;    /* No choice but to spit it out whole. */
  161.         }
  162.         *tl++ = '\n';
  163.         n0 = strlen(tl);
  164.     }
  165.     if(!notdied) cw->flags &= ~WIN_STOP;
  166.     if(!(cw->flags & WIN_STOP)) redotoplin(toplines);
  167. }
  168.  
  169. STATIC_OVL
  170. void
  171. topl_putsym(c)
  172.     char c;
  173. {
  174.     register struct WinDesc *cw = wins[WIN_MESSAGE];
  175.  
  176.     if(cw == (struct WinDesc *) 0) panic("Putsym window MESSAGE nonexistant");
  177.     
  178.     switch(c) {
  179.     case '\b':
  180.     if(ttyDisplay->curx == 0 && ttyDisplay->cury > 0)
  181.         tty_curs(BASE_WINDOW, CO, (int)ttyDisplay->cury-1);
  182.     backsp();
  183.     ttyDisplay->curx--;
  184.     cw->curx = ttyDisplay->curx;
  185.     return;
  186.     case '\n':
  187.     cl_end();
  188.     ttyDisplay->curx = 0;
  189.     ttyDisplay->cury++;
  190.     cw->cury = ttyDisplay->cury;
  191.     break;
  192.     default:
  193.     if(ttyDisplay->curx == CO-1)
  194.         topl_putsym('\n'); /* 1 <= curx <= CO; avoid CO */
  195.     ttyDisplay->curx++;
  196.     }
  197.     cw->curx = ttyDisplay->curx;
  198.     if(cw->curx == 0) cl_end();
  199.     (void) putchar(c);
  200. }
  201.  
  202. void
  203. putsyms(str)
  204.     const char *str;
  205. {
  206.     while(*str)
  207.     topl_putsym(*str++);
  208. }
  209.  
  210. static void
  211. removetopl(n)
  212. register int n;
  213. {
  214.     /* assume addtopl() has been done, so ttyDisplay->toplin is already set */
  215.     while (n-- > 0) putsyms("\b \b");
  216. }
  217.  
  218. extern char erase_char;        /* from xxxtty.c; don't need kill_char */
  219.  
  220. char
  221. tty_yn_function(query,resp, def)
  222. const char *query,*resp;
  223. char def;
  224. /*
  225.  *   Generic yes/no function. 'def' is the default (returned by space or
  226.  *   return; 'esc' returns 'q', or 'n', or the default, depending on
  227.  *   what's in the string. The 'query' string is printed before the user
  228.  *   is asked about the string.
  229.  *   If resp is NULL, any single character is accepted and returned.
  230.  */
  231. {
  232.     register char q;
  233.     char rtmp[40];
  234.     boolean digit_ok, allow_num;
  235.     struct WinDesc *cw = wins[WIN_MESSAGE];
  236.     boolean doprev = 0;
  237.     char prompt[QBUFSZ];
  238.  
  239.     if(ttyDisplay->toplin == 1 && !(cw->flags & WIN_STOP)) more();
  240.     cw->flags &= ~WIN_STOP;
  241.     ttyDisplay->toplin = 3; /* special prompt state */
  242.     ttyDisplay->inread++;
  243.     if(resp) {
  244.         allow_num = (index(resp, '#') != 0);
  245.         if(def)
  246.         Sprintf(prompt, "%s [%s] (%c) ", query, resp, def);
  247.         else
  248.         Sprintf(prompt, "%s [%s] ", query, resp);
  249.         pline("%s", prompt);
  250.     } else {
  251.         pline("%s ", query);
  252.         q = readchar();
  253.         goto clean_up;
  254.     }
  255.  
  256.     do {    /* loop until we get valid input */
  257.         q = lowc(readchar());
  258.         if (q == '\020') { /* ctrl-P */
  259.         if(!doprev) (void) tty_doprev_message(); /* need two initially */
  260.         (void) tty_doprev_message();
  261.         q = (char)0;
  262.         doprev = 1;
  263.         continue;
  264.         } else if(doprev) {
  265.         tty_clear_nhwindow(WIN_MESSAGE);
  266.         cw->maxcol = cw->maxrow;
  267.         doprev = 0;
  268.         addtopl(prompt);
  269.         continue;
  270.         }
  271.         digit_ok = allow_num && digit(q);
  272.         if (q == '\033') {
  273.         if (index(resp, 'q'))
  274.             q = 'q';
  275.         else if (index(resp, 'n'))
  276.             q = 'n';
  277.         else
  278.             q = def;
  279.         break;
  280.         } else if (index(quitchars, q)) {
  281.         q = def;
  282.         break;
  283.         }
  284.         if (!index(resp, q) && !digit_ok) {
  285.         tty_nhbell();
  286.         q = (char)0;
  287.         } else if (q == '#' || digit_ok) {
  288.         char z, digit_string[2];
  289.         int n_len = 0;
  290.         long value = 0;
  291.         addtopl("#"),  n_len++;
  292.         digit_string[1] = '\0';
  293.         if (q != '#') {
  294.             digit_string[0] = q;
  295.             addtopl(digit_string),  n_len++;
  296.             value = q - '0';
  297.             q = '#';
  298.         }
  299.         do {    /* loop until we get a non-digit */
  300.             z = lowc(readchar());
  301.             if (digit(z)) {
  302.             value = (10 * value) + (z - '0');
  303.             if (value < 0) break;    /* overflow: try again */
  304.             digit_string[0] = z;
  305.             addtopl(digit_string),  n_len++;
  306.             } else if (z == 'y' || index(quitchars, z)) {
  307.             if (z == '\033')  value = -1;    /* abort */
  308.             z = '\n';    /* break */
  309.             } else if (z == erase_char || z == '\b') {
  310.             if (n_len <= 1) { value = -1;  break; }
  311.             else { value /= 10;  removetopl(1),  n_len--; }
  312.             } else {
  313.             value = -1;    /* abort */
  314.             tty_nhbell();
  315.             break;
  316.             }
  317.         } while (z != '\n');
  318.         if (value > 0) yn_number = value;
  319.         else if (value == 0) q = 'n';        /* 0 => "no" */
  320.         else {    /* remove number from top line, then try again */
  321.             removetopl(n_len),  n_len = 0;
  322.             q = '\0';
  323.         }
  324.         }
  325.     } while(!q);
  326.  
  327.     if (q != '#') {
  328.         Sprintf(rtmp, "%c", q);
  329.         addtopl(rtmp);
  330.     }
  331.     clean_up:
  332.     ttyDisplay->inread--;
  333.     ttyDisplay->toplin = 2;
  334.     if(wins[WIN_MESSAGE]->cury)
  335.         tty_clear_nhwindow(WIN_MESSAGE);
  336.  
  337.     return q;
  338. }
  339.  
  340. #endif /* OVL2 */
  341.  
  342. /*topl.c*/
  343.