home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / win / tty / topl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  8.0 KB  |  352 lines  |  [TEXT/R*ch]

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