home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / games / volume13 / okbridge / part05 / display.c next >
C/C++ Source or Header  |  1992-01-12  |  17KB  |  653 lines

  1. /* display.c -- Display functions for netbridge program.
  2.  ! 
  3.  ! Copyright (C) 1990,1991 by Matthew Clegg
  4.  ! 
  5.  ! This program may be copied and distributed freely.  Please do not
  6.  ! charge money for this program or for any program derived from it.
  7.  ! If you modify this program, then include a notice stating plainly
  8.  ! that your program is derived from the okbridge program and is not
  9.  ! the same as the official okbridge program.
  10.  !
  11.  ! I welcome any suggestions for improvement to okbridge, and 
  12.  ! I would be especially happy to receive improved source code.
  13.  ! If you have comments or suggestions, or if you would like to
  14.  ! join the okbridge mailing list, then write to
  15.  !
  16.  !   mclegg@cs.ucsd.edu
  17.  !
  18. */
  19.  
  20. #include <stdio.h>
  21. #include <string.h>
  22.  
  23. #include "globals.h"
  24. #include "terminal.h"
  25.  
  26. typedef int window[4];
  27.  
  28. /* Conceptually, we think of the screen as being divided into a number
  29.    of windows, where each window describes one particular type of activity
  30.    or aspect of the game.  Therefore, we make the following definitions,
  31.    although these are only guidelines for operation of the display.
  32.  
  33. Name of
  34. Window               Ymin    Xmin    Height    Width
  35. -------             ----    ----    ----    ----            */
  36. window title          = { 1,    1,    6,    25};
  37. window top_hand      = { 2,    30,    4,    26};
  38. window scores         = { 1,    59,    6,    26};
  39. window left_hand     = { 8,    6,    6,    18};
  40. window playing_board = { 5,    27,    9,    26};
  41. window bidding_board = { 5,    1,    9,    58};
  42. window right_hand    = { 8,    56,    6,    23};
  43. window input         = { 13,    1,    6,    26};
  44. window status         = { 18,    1,    1,    78};
  45. window bottom_hand   = { 13,    30,    4,    26};
  46. window help         = { 13,    53,    6,    26};
  47. window converse         = { 19,    1,    6,    78};
  48.  
  49. #define XMIN(w)        w[1]
  50. #define YMIN(w)         w[0]
  51. #define XMAX(w)        (w[1] + w[3] - 1)
  52. #define YMAX(w)        (w[0] + w[2] - 1)
  53. #define HEIGHT(w)    w[2]
  54. #define WIDTH(w)    w[3]
  55.  
  56. static int PLAYERHAND_X [4];
  57. static int PLAYERHAND_Y [4]; 
  58. static int CARDPOS_X    [4];
  59. static int CARDPOS_Y    [4];
  60. static char *position_names [4];
  61. static int comments_suspended = 0;
  62.  
  63. static char line_buf [81];
  64. static char status_message_buf[81];
  65.  
  66. static underline (ymin, xmin, length)
  67.        int ymin, xmin, length;
  68. /* Prints a line of hyphens BELOW the field beginning at (ymin,xmin),
  69.  *  of given length.
  70.  */
  71. {
  72.     int i;
  73.  
  74.     for (i = 0; i < length; i++)
  75.         line_buf[i] = '-';
  76.     line_buf[length] = '\0';
  77.     print (ymin+1, xmin, line_buf);
  78. };
  79.  
  80. static clear_screen_area (ymin, xmin, height, width)
  81.        int ymin, xmin, height, width;
  82. {
  83.     int i;
  84.  
  85.     for (i = 0; i < width; i++) line_buf[i] = ' ';
  86.     line_buf[width] = '\0';
  87.     for (i = 0; i < height; i++) print (ymin+i, xmin, line_buf);
  88. };
  89.  
  90. Reset_Display ()
  91. /* Redraws the main features of the screen.  Used in the process
  92.  * of doing a 'refresh'.
  93.  */
  94. {
  95.     int i;
  96.     char program_name[20];
  97.  
  98.     sprintf (program_name, "OKBRIDGE %s%s", major_revision_level,
  99.          minor_revision_level);
  100.     clear_screen ();
  101.  
  102.     /* Display the title of the program: */
  103.     print (YMIN(title), XMIN(title),  program_name);
  104. /*    print (YMIN(title)+1, XMIN(title), "MTC    JUNE 90"); */
  105.  
  106.     /* Setup the scoreboard: */
  107.     if (side_of(local_player) == SIDE_NS) {
  108.       print (YMIN(scores), XMIN(scores) + 8,   "   WE");
  109.       print (YMIN(scores), XMIN(scores) + 16,  " THEY");
  110.     } else {
  111.       print (YMIN(scores), XMIN(scores) + 16,  "   WE");
  112.       print (YMIN(scores), XMIN(scores) + 8,   " THEY");
  113.     };
  114.     underline (YMIN(scores), XMIN(scores) + 8, 5);
  115.     underline (YMIN(scores), XMIN(scores) + 16, 5);
  116.     print (YMIN(scores)+2, XMIN(scores), "TRICKS");
  117.     print (YMIN(scores)+3, XMIN(scores), "VUL");
  118.  
  119.     switch (scoring_mode) {
  120.       case RUBBER_SCORING:
  121.           print (YMIN(scores)+4, XMIN(scores), "ABOVE");
  122.           print (YMIN(scores)+5, XMIN(scores), "BELOW");
  123.           print (YMIN(title)+1,  XMIN(title),  "HAND");
  124.         break;
  125.       case CHICAGO_SCORING:
  126.           print (YMIN(scores)+4, XMIN(scores), "TOTAL");
  127.           print (YMIN(scores)+5, XMIN(scores), "PART");
  128.           print (YMIN(title)+1,  XMIN(title),  "HAND");
  129.         break;
  130.       case DUPLICATE_SCORING:
  131.       case EMAIL_SCORING:
  132.           print (YMIN(scores)+4, XMIN(scores), "TOTAL");
  133.           print (YMIN(scores)+5, XMIN(scores), "PREV");
  134.           print (YMIN(title)+1,  XMIN(title),  "BOARD");
  135.         break;
  136.       case IMP_SCORING:
  137.           print (YMIN(scores)+4, XMIN(scores), "TOTAL");
  138.           print (YMIN(scores)+5, XMIN(scores), "IMP");
  139.           print (YMIN(title)+1,  XMIN(title),  "BOARD");
  140.         break;
  141.     };
  142.     sprintf (program_name, "%d", current_deal_no);
  143.     print (YMIN(title)+1, XMIN(title)+6, program_name);
  144.  
  145.     /* Setup the input area: */
  146.     print (TALK_ROW, TALK_COL, "TALK");
  147.  
  148.  
  149.     /* Setup the conversational area: */
  150.     for (i = 0; i <= XMAX(converse); i++) line_buf[i] = '-';
  151.     line_buf[XMAX(converse)+1] = '\0';
  152.     print (YMIN(converse), XMIN(converse), line_buf);
  153.     for (i = YMIN(converse)+1; i <= YMAX(converse); i++) {
  154.         print (i, XMIN(converse), "|");
  155.         print (i, XMAX(converse)+1, "|");
  156.     };
  157. };
  158.  
  159. Initialize_Display ()
  160. /* Should be called once when the program starts up. */
  161. /*    Initialize_Terminal (); */ 
  162.     Reset_Display ();
  163.  
  164.     PLAYERHAND_X [local_player] = XMIN(bottom_hand);
  165.     PLAYERHAND_Y [local_player] = YMIN(bottom_hand);
  166.     PLAYERHAND_X [player_next[local_player]] = XMIN(left_hand);
  167.     PLAYERHAND_Y [player_next[local_player]] = YMIN(left_hand);
  168.     PLAYERHAND_X [player_partner[local_player]] = XMIN(top_hand);
  169.     PLAYERHAND_Y [player_partner[local_player]] = YMIN(top_hand);
  170.     PLAYERHAND_X [player_prev[local_player]] = XMIN(right_hand);
  171.     PLAYERHAND_Y [player_prev[local_player]] = YMIN(right_hand);
  172.  
  173.     CARDPOS_Y[local_player] = YMAX(playing_board) - 2;
  174.     CARDPOS_X[local_player] = (XMAX(playing_board) + 
  175.                    XMIN(playing_board))/2;
  176.     CARDPOS_Y[player_next[local_player]] = (YMAX(playing_board) + 
  177.                         YMIN(playing_board))/2;
  178.     CARDPOS_X[player_next[local_player]] = XMIN(playing_board) + 3;
  179.     CARDPOS_Y[player_partner[local_player]] = YMIN(playing_board) + 2;
  180.     CARDPOS_X[player_partner[local_player]] = (XMAX(playing_board) + 
  181.                            XMIN(playing_board))/2;
  182.     CARDPOS_Y[player_prev[local_player]] = (YMAX(playing_board) + 
  183.                         YMIN(playing_board))/2;
  184.     CARDPOS_X[player_prev[local_player]] = XMAX(playing_board) - 4;
  185.  
  186.     position_names[0] = player_names [local_player];
  187.     position_names[1] = player_names [player_next[local_player]];
  188.     position_names[2] = player_names [player_partner[local_player]];
  189.     position_names[3] = player_names [player_prev[local_player]];
  190.  
  191.     status_message_buf[0] = '\0';
  192.  
  193. };
  194.  
  195. Refresh_Display ()
  196. /* Resets the terminal display and redraws everything. */
  197. {
  198.     int i, j, p;
  199.  
  200.     Reset_Display ();
  201.     Display_Tricks_Taken ();
  202.     Display_Above_Line_Points ();
  203.     Display_Below_Line_Points ();
  204.     Display_Vulnerabilities ();
  205.     Refresh_Player_Comments ();
  206.     if (game_mode == STARTUP_MODE) {
  207.         ;
  208.     } else if (game_mode == BIDDING_MODE) {
  209.         Display_Bidding_Board ();
  210.         Display_Hand_for_Bidding (local_player);
  211.         p = dealer;
  212.         for (i = 0; i < no_bids; i++) {
  213.             Display_Bid (i/4 + 1, p);
  214.             p = player_next [p];
  215.         };
  216.                 Display_Bidder (p);
  217.         print (PLAY_ROW, PLAY_COL, "BID ");
  218.     } else if (game_mode == PLAYING_MODE) {
  219.         Display_Contract (); 
  220.         Display_Playing_Board ();
  221.         Display_Hand (local_player);
  222.         if ((trick > 1) || (no_plays > 0))
  223.           Display_Hand (dummy);
  224.         if (local_player == dummy)
  225.           Display_Hand (declarer);
  226. #ifdef LOOPBACK_MODE
  227.         Display_Hand (player_next[local_player]);    /* DBG */
  228.         Display_Hand (player_partner[local_player]);    /* DBG */
  229.         Display_Hand (player_prev[local_player]);    /* DBG */
  230. #endif
  231. #ifdef TWOPLAYER_MODE
  232.         Display_Hand (player_partner[local_player]);
  233. #endif
  234.  
  235.         p = leader;
  236.         for (i = 0; i < no_plays; i++) {
  237.             Display_Play (p, plays[p]);
  238.             p = player_next[p];
  239.         };
  240.                 Display_Player (p);
  241.         print (PLAY_ROW, PLAY_COL, "PLAY");
  242.           } else if (game_mode == REVIEW_MODE) {
  243.         Display_Contract (); 
  244.         Display_Playing_Board ();
  245.         Display_Player (-1);
  246.         Display_Below_Line_Points ();
  247.         Display_Above_Line_Points ();
  248.         for (i = 0; i < 4; i++)
  249.           Display_Hand (i);
  250. /*
  251.         Display_Status 
  252.           ("REVIEW OF THE HAND -- PRESS RETURN ON A BLANK LINE TO PROCEED");
  253. */
  254.           };
  255.     Refresh_Status_Display ();
  256.  
  257. };
  258.  
  259.  
  260.  
  261. Display_Tricks_Taken ()
  262. {
  263.     sprintf (line_buf,"%5d   %5d",tricks[SIDE_NS], tricks[SIDE_EW]);
  264.     print (YMIN(scores)+2,XMIN(scores)+8, line_buf);
  265. };
  266.  
  267. Display_Above_Line_Points ()
  268. {
  269.     sprintf (line_buf,"%5d   %5d",above_line[SIDE_NS],
  270.         above_line[SIDE_EW]);
  271.     print (YMIN(scores)+4,XMIN(scores)+8, line_buf);
  272. };
  273.  
  274. Display_Below_Line_Points ()
  275. {
  276.   sprintf (line_buf,"%5d   %5d",below_line[SIDE_NS],
  277.        below_line[SIDE_EW]);
  278.   print (YMIN(scores)+5,XMIN(scores)+8, line_buf);
  279. };
  280.  
  281. Display_Vulnerabilities   ()
  282. {
  283.     char *nsv, *ewv;
  284.  
  285.     if (vulnerable[SIDE_NS]) nsv = "  YES";
  286.     else              nsv = "   NO";
  287.     if (vulnerable[SIDE_EW]) ewv = "  YES";
  288.     else              ewv = "   NO";
  289.     sprintf (line_buf, "%s   %s",nsv,ewv);
  290.     print (YMIN(scores)+3, XMIN(scores)+8, line_buf);
  291. };
  292.  
  293. Clear_Bidding_Board ()
  294. {
  295.     int x, y, h, w;
  296.  
  297.     x = XMIN(bidding_board);
  298.     y = YMIN(bidding_board);
  299.     h = HEIGHT(bidding_board);
  300.     w = WIDTH(bidding_board);
  301.     clear_screen_area (y, x, h, w);
  302.     clear_screen_area (PLAY_ROW, 1, 1, 10);
  303.  
  304. };
  305.  
  306. Display_Bidding_Board ()
  307. /* The bidding display is given as four columns, similar to that found
  308.    in many bridge books.  At the top of each column is printed the
  309.    corresponding input parameter string to identify the bidder. */
  310. {
  311.     int i;
  312.     char *first, *second, *third, *fourth, board_no_buf[10];
  313.  
  314.     Clear_Bidding_Board ();
  315.  
  316.     first  = player_names [PLAYER_NORTH];
  317.     second = player_names [player_next[PLAYER_NORTH]];
  318.     third  = player_names [player_partner[PLAYER_NORTH]];
  319.     fourth = player_names [player_prev[PLAYER_NORTH]];
  320.  
  321.     print(YMIN(bidding_board), XMIN(bidding_board)+05, first);
  322.     print(YMIN(bidding_board), XMIN(bidding_board)+15, second);
  323.     print(YMIN(bidding_board), XMIN(bidding_board)+25, third);
  324.     print(YMIN(bidding_board), XMIN(bidding_board)+35, fourth);
  325.  
  326.     underline(YMIN(bidding_board),XMIN(bidding_board)+05,strlen(first));
  327.     underline(YMIN(bidding_board),XMIN(bidding_board)+15,strlen(second));
  328.     underline(YMIN(bidding_board),XMIN(bidding_board)+25,strlen(third));
  329.     underline(YMIN(bidding_board),XMIN(bidding_board)+35,strlen(fourth));
  330.  
  331.     sprintf (board_no_buf, "%d", current_deal_no);
  332.     print (YMIN(title)+1, XMIN(title)+6, board_no_buf);
  333.  
  334. };
  335.  
  336. static Display_suit (y, x, cards)
  337.      int y, x; suit_type cards;
  338. /* Displays the cards in a given suit held by a player.  As input,
  339.  * cards[] is an array of 13 elements, where cards[i] is TRUE if the
  340.  * player holds the given card.  Displays the cards as a string on
  341.  * the terminal, beginning at coordinates <y,x>.
  342.  */
  343. {
  344.     int i;
  345.  
  346.     for (i = 12; i >= 0; i--)
  347.         if (cards[i])
  348.             print (y, x++, rank_names[i]);
  349. };
  350.  
  351. Display_Hand_for_Bidding (pos)
  352. int pos;
  353. {
  354.     int i, x, y;
  355.     suit_type h;
  356.  
  357.     y = YMIN(bidding_board);
  358.     x = XMIN(bidding_board) + 45;
  359.     clear_screen_area (y, x, HEIGHT(bidding_board),
  360.         XMAX(bidding_board)-x+1);
  361.     for (i = 0; i < 6; i++)
  362.         print (y+i, x, "|");
  363.  
  364.     x+=1;
  365.     print (y, x, player_names[pos]);
  366.     underline (y, x, strlen(player_names[pos]));
  367.     h = current_hand[pos];
  368.     print (y+2, x, "S "); Display_suit (y+2, x+2, h+39);
  369.     print (y+3, x, "H "); Display_suit (y+3, x+2, h+26);
  370.     print (y+4, x, "D "); Display_suit (y+4, x+2, h+13);
  371.     print (y+5, x, "C "); Display_suit (y+5, x+2, h);
  372. };
  373.  
  374. Display_Bidder (player)
  375.     int player;
  376. {
  377.     char bid_buf[80];
  378.  
  379.     sprintf (bid_buf, "%s's BID        ", player_names[player]);
  380.     print (YMIN(title)+2, XMIN(title), bid_buf);
  381. };
  382.  
  383. Display_Bid (round, player)
  384.      int round, player;
  385. {
  386.     int x, y, bid, position;
  387.     char *bid_string;
  388.  
  389.     y = YMIN(bidding_board) + round + 1;
  390.     sprintf (line_buf, " %2d", round);
  391.     print (y, XMIN(bidding_board), line_buf);
  392.  
  393. /* 
  394.     if (player == dealer) position = 0;
  395.     else if (player == player_next[dealer]) position = 1;
  396.     else if (player == player_partner[dealer]) position = 2;
  397.     else position = 3;
  398. */
  399.     y++; 
  400.     for (x = dealer; x < 4; x++)
  401.         if (x == player) y--;
  402.  
  403.     position = player;
  404.     x = XMIN(bidding_board) + 10 * position + 5;
  405.     bid = bids[player][round-1];
  406.     if (bid == BID_PASS)
  407.         bid_string = "--";
  408.     else
  409.         bid_string = bid_names[bid];
  410.     print (y, x, bid_string);
  411. };
  412.  
  413. Display_Contract ()
  414. {
  415.     char double_buf[40], contract_buf[60];
  416.  
  417.     clear_screen_area (YMIN(title)+2, XMIN(title), HEIGHT(title),
  418.                WIDTH(title));
  419.     if (redoubled)
  420.         sprintf (double_buf,"  REDOUBLED");
  421.     else if (doubled)
  422.         sprintf (double_buf, "  DOUBLED");
  423.     else
  424.         double_buf[0] = '\0';
  425.     sprintf (contract_buf, "%1d%s (%s)%s",contract,suit_names[trump_suit],
  426.         player_names[declarer], double_buf);
  427.  
  428.     print (YMIN(title)+3, XMIN(title), contract_buf);
  429. }
  430.  
  431. Clear_Playing_Board ()
  432. {
  433.     clear_screen_area (YMIN(playing_board), XMIN(playing_board),
  434.         HEIGHT(playing_board), WIDTH(playing_board));
  435.     clear_screen_area (YMIN(left_hand), XMIN(left_hand),
  436.         HEIGHT(left_hand), WIDTH(left_hand));
  437.     clear_screen_area (YMIN(right_hand), XMIN(right_hand),
  438.         HEIGHT(right_hand), WIDTH(right_hand));
  439.       clear_screen_area (YMIN(top_hand), XMIN(top_hand),
  440.         HEIGHT(top_hand), WIDTH(top_hand));
  441.     clear_screen_area (YMIN(bottom_hand), XMIN(bottom_hand),
  442.         HEIGHT(bottom_hand), WIDTH(bottom_hand));
  443.     clear_screen_area (YMIN(title)+3, XMIN(title), 1, WIDTH(title));
  444. };
  445.  
  446. Display_Playing_Board ()
  447. {
  448.     int i;
  449.  
  450. /*    Clear_Playing_Board (); */
  451.  
  452.     for (i = 0; i < 4; i++)
  453.         print (PLAYERHAND_Y[i]+1, PLAYERHAND_X[i]+12 -
  454.                strlen(player_names[i]), player_names[i]);
  455.  
  456.     for (i = 0; i < WIDTH(playing_board)-1; i++) line_buf[i] = '-';
  457.     line_buf[WIDTH(playing_board)-2] = '\0';
  458.     print (YMIN(playing_board)+1,XMIN(playing_board)+1,line_buf);
  459.     print (YMAX(playing_board)-1,XMIN(playing_board)+1,line_buf);
  460.  
  461.     for (i = YMIN(playing_board)+2; i < YMAX(playing_board)-1; i++) {
  462.         print (i, XMIN(playing_board)+1, "|");
  463.         print (i, XMAX(playing_board)-1, "|");
  464.     };
  465. };
  466.  
  467. Display_Player (player)
  468.     int player;
  469. {
  470.     char play_buf[80];
  471.  
  472.     if (player < 0)
  473.         sprintf (play_buf, "                    ");
  474.     else if (player == dummy)
  475.         sprintf (play_buf, "DUMMY'S PLAY        ");
  476.     else
  477.         sprintf (play_buf, "%s's PLAY        ",
  478.              player_names[player]);
  479.     print (YMIN(title)+4, XMIN(title), play_buf);
  480. };
  481.  
  482. Display_Play (p, card)
  483.      int p, card;
  484. {
  485.     int x, y, position;
  486.  
  487.     y = CARDPOS_Y [p];
  488.     x = CARDPOS_X [p];
  489.     if ((0 <= card) && (card < 52))
  490.         print (y, x, card_names[card]);
  491.     else
  492.         print (y, x, "   ");
  493. };
  494.  
  495. Clear_Plays  ()
  496. {
  497.     Display_Play (PLAYER_NORTH, -1);
  498.     Display_Play (PLAYER_EAST,  -1);
  499.     Display_Play (PLAYER_SOUTH, -1);
  500.     Display_Play (PLAYER_WEST,  -1);
  501. };
  502.  
  503. Display_Hand (p)
  504.      int p;
  505. {
  506.     int y, x, i;
  507.     suit_type h;
  508.  
  509.     y = PLAYERHAND_Y [p];
  510.     x = PLAYERHAND_X [p];
  511.     for (i = 0; i < 4; i++)
  512.         print (y+i, x, "                   ");
  513.  
  514.     h = current_hand[p];
  515.     print (y,   x+5-strlen(player_names[p]), player_names[p]);
  516.     if (p == dummy)
  517.         print (y+1, x+5-7, "(DUMMY)");
  518.     print (y,   x+7, "S "); Display_suit (y,   x+10, h+39);
  519.     print (y+1, x+7, "H "); Display_suit (y+1, x+10, h+26);
  520.     print (y+2, x+7, "D "); Display_suit (y+2, x+10, h+13);
  521.     print (y+3, x+7, "C "); Display_suit (y+3, x+10, h);
  522. };
  523.  
  524. Clear_Hand (p)
  525.      int p;
  526. {
  527.     int y, x, i;
  528.  
  529.     y = PLAYERHAND_Y [p];
  530.     x = PLAYERHAND_X [p];
  531.     for (i = 0; i < 4; i++)
  532.         print (y+i, x, "                   ");
  533.  
  534.     print (y,   x+5-strlen(player_names[p]), player_names[p]);
  535.     if (p == dummy)
  536.         print (y+1, x+5-7, "(DUMMY)");
  537. };
  538.  
  539. Display_Status (message)
  540.      char *message;
  541. {
  542.         Clear_Status_Display ();
  543.     print (YMIN(status), XMIN(status), message);
  544.     sprintf (status_message_buf, "%s", message);
  545.     set_cursor (YMIN(status), XMIN(status) + strlen(message) + 1);
  546. };
  547.  
  548. Clear_Status_Display ()
  549. {
  550.     clear_screen_area (YMIN(status), XMIN(status), 1, WIDTH(status));
  551.     status_message_buf [0] = '\0';
  552. };
  553.  
  554. Refresh_Status_Display ()
  555. {
  556.     clear_screen_area (YMIN(status), XMIN(status), 1, WIDTH(status));
  557.     print (YMIN(status), XMIN(status), status_message_buf);
  558.     set_cursor (YMIN(status), 
  559.             XMIN(status) + strlen(status_message_buf) + 1);
  560. };
  561.  
  562. /* The bottom part of the screen is used for the exchange of comments
  563.    between the players.  The following procedures are used for managing
  564.    this part of the display. */
  565.  
  566. #define COMMENT_LENGTH 78
  567. #define COMMENT_BUF_SIZE 5
  568.  
  569. typedef char comment_line [COMMENT_LENGTH];
  570. typedef comment_line comment_buf [COMMENT_BUF_SIZE];
  571. static  comment_buf  player_comments;
  572.  
  573. static blank_out_comment (c)
  574.      comment_line c;
  575. {
  576.     int i;
  577.  
  578.     for (i = 0; i < COMMENT_LENGTH-1; i++) c[i] = ' ';
  579.     c[COMMENT_LENGTH-1] = '\0';
  580. };
  581.  
  582. static copy_string_to_comment (c, s)
  583.      comment_line c; char *s;
  584. {
  585.     int i;
  586.  
  587.     blank_out_comment(c);
  588.     i = 0;
  589.     while ((s[i] != '\0') && (i < COMMENT_LENGTH-1)) {
  590.         c[i] = s[i]; i++; }
  591.  
  592. };
  593.  
  594. static scroll_player_comments ()
  595. {
  596.     int i, j;
  597.  
  598.     for (i = 0; i < COMMENT_BUF_SIZE - 1; i++)
  599.         for (j = 0; j < COMMENT_LENGTH; j++) {
  600.             player_comments[i][j] =
  601.                 player_comments[i+1][j];
  602.         };
  603. };
  604.  
  605. Refresh_Player_Comments ()
  606. {
  607.     int i, x, y;
  608.  
  609.     if (comments_suspended)
  610.         return;
  611.  
  612.     x = XMIN(converse) + 1;
  613.     y = YMIN(converse) + 1;
  614.  
  615.     for (i = 0; i < COMMENT_BUF_SIZE; i++)
  616.         print (y+i, x, player_comments[i]);
  617. };
  618.  
  619. Initialize_Player_Comments ()
  620. {
  621.     int i;
  622.  
  623.     for (i = 0; i < COMMENT_BUF_SIZE; i++)
  624.         blank_out_comment (player_comments[i]);
  625.     Refresh_Player_Comments ();
  626. };
  627.  
  628. Display_Player_Comment (player_name, comment)
  629.      char *player_name, *comment;
  630. {
  631.     char message_buf [80];
  632.  
  633.     sprintf (message_buf, "%s: %s", player_name, comment);
  634.     scroll_player_comments ();
  635.     copy_string_to_comment (player_comments[COMMENT_BUF_SIZE-1],
  636.                 message_buf);
  637.     Refresh_Player_Comments ();
  638. };
  639.  
  640.  
  641. void Suspend_Comment_Display ()
  642. {
  643.     comments_suspended = 1;
  644. };
  645.  
  646. void Continue_Comment_Display ()
  647. {
  648.     comments_suspended = 0;
  649. };
  650.  
  651.  
  652.