home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 125_01 / deflect.c < prev    next >
Text File  |  1985-03-10  |  8KB  |  448 lines

  1. /*   DISK CATALOG : HEADERS.DOC
  2.     
  3. C Users Group Volume Number 125 - VIDEO TERMINAL LIRARIES
  4. Cataloged By Ben Rockefeller 5/15/85    
  5.  
  6. */
  7.  
  8. /*           HEADER: CUG125.05; 
  9.  
  10.           TITLE: VIDEO TERMINAL LIBRARIES;
  11.             VERSION: 1.0;
  12.                   DATE: 5/15/85;
  13.         DESCRIPTION: "Rewrite of R.H. Halstead's Polish Pong
  14.               (PPONG.C) with conversion for vt52 terminal";
  15.         KEYWORDS: game;
  16.              SYSTEM: Osborne 1, DEC vt52;
  17.            FILENAME: DEFLECT.C;
  18.        WARNINGS: "Requires video routines linked";
  19.        SEE-ALSO: DEFLECT.NRO;
  20.             AUTHORS: Stephen L. Browning;
  21.           COMPILERS: BDC C;
  22. */
  23.  
  24.  
  25. /*
  26.  *    Rewrite of R. H. Halstead's Polish Pong (PPONG.C)
  27.  *    with conversions for VT52 terminal.
  28.  *
  29.  *    This version does not require the terminal to have
  30.  *    a special graphics mode, just cursor addressing
  31.  *    capabilities.
  32.  *
  33.  *    Stephen L. Browning
  34.  *    5723 North Parker
  35.  *    Indianapolis, IN 46220
  36.  */
  37.  
  38. #include "a:bdscio.h"
  39. #include "a:ascii.h"
  40.  
  41. #define MAXX    80        /* horizontal size of board */
  42. #define MAXY    23        /* vertical size */
  43. #define MAXTARG    20        /* no. of targets per game */
  44. #define ISPEED    400        /* initial ball speed */
  45. #define SPEDINC    100        /* increment/decrement in ball speed */
  46.  
  47. /*
  48.  *    location of status strings
  49.  */
  50.  
  51. #define TIMX    50        /* time */
  52. #define TIMY    0
  53. #define TARGX    30        /* targets */
  54. #define TARGY    0
  55. #define SPEEDX    10        /* current speed setting */
  56. #define SPEEDY    0
  57. #define BESTX    70        /* best score so far */
  58. #define BESTY    0
  59.  
  60. #define MSPS    960        /* "millisecs" per second */
  61.  
  62. #define QUITCH    ETX        /* ^C exits program */
  63. #define DELETE    0177        /* DELETE (rubout) restarts game */
  64.  
  65. #define XON    DC1        /* ^Q */
  66. #define XOFF    DC3        /* ^S */
  67.  
  68. #define VBAR    '|'
  69. #define HBAR    '-'
  70. #define SLASH    '/'
  71. #define BSLASH    '\\'
  72. #define BALL    'O'
  73. #define TARGET    '*'
  74.  
  75. char board[MAXX][MAXY];        /* board with current layout */
  76. int best;            /* best score so far */
  77. int inchar;            /* character input buffer */
  78. int ballx,bally,ballxv,ballyv;    /* ball positioning data */
  79. int speed,dist;            /* speed control */
  80. int targleft;            /* no. of targets remaining */
  81. int msecs,secs;            /* timers */
  82. int newtime;            /* time remaining */
  83. char bellflag;            /* turns off/on bell output */
  84.  
  85.  
  86. main()
  87. {
  88.     int i;
  89.  
  90.     clrscrn();
  91.     puts("Welcome to Deflection\n");
  92.     for (i=0; i<30000; ++i) ;
  93.     best = 0x7fff;
  94.     speed = ISPEED;
  95.     bellflag = TRUE;
  96.     while (playgame());
  97.     clrscrn();
  98. }
  99.  
  100.  
  101. playgame()
  102. {
  103.     int i,j;
  104.     char buff[100];
  105.  
  106.     inchar = -1;        /* initially no character input */
  107.     clrscrn();
  108.     getchx();
  109.     srand1("\nType any key to start game (h for help): ");
  110.     i = getchar();
  111.     if (i == QUITCH) {
  112.         return(0);
  113.     }
  114.     if (tolower(i) == 'h') {
  115.         help();
  116.     }
  117.     inchar = -1;        /* reset input buffer */
  118.     initboard();
  119.     targleft = MAXTARG;
  120.     clrscrn();
  121.     for (j=MAXY-1; j>=0; --j) {
  122.         for (i=0; i<MAXX; ++i) putchx(board[i][j]);
  123.         putchx('\n');
  124.     }
  125.     outs(SPEEDX-7,SPEEDY,"Speed: ");
  126.     outs(TARGX-14,TARGY,"Targets Left: ");
  127.     outs(TIMX-11,TIMY,"Time Used: ");
  128.     if (best < 0x7fff) {
  129.         sprintf(buff,"Best Time: %03d",best);
  130.         outs(BESTX-11,BESTY,buff);
  131.     }
  132.     putspeed();
  133.     puttarg();
  134.     msecs = secs = 0;
  135.     puttime();
  136.     ouch(ballx,bally+1,BALL);
  137.     while (moveball()) ;
  138.     if (targleft == 0 && secs < best) best = secs;
  139.     return(1);
  140. }
  141.  
  142.  
  143.  
  144. /*
  145.  *    initialize screen for new game
  146.  */
  147.  
  148. initboard()
  149. {
  150.     int i,j;
  151.  
  152.     ballx = rand() % (MAXX-2) + 1;
  153.     bally = rand() % (MAXY-2) + 1;
  154.     ballxv = ballyv = 0;
  155.     i = (rand() & 2) - 1;        /* i = -1 or +1 */
  156.     if (rand() & 1) ballxv = i;
  157.     else ballyv = i;
  158.     for (i=0; i<MAXX; ++i)
  159.         for (j=0; j<MAXY; ++j) board[i][j] = ' ';
  160.     for (i=0; i<MAXX; ++i) board[i][0] = board[i][MAXY-1] = HBAR;
  161.     for (i=0; i<MAXY; ++i) board[0][i] = board[MAXX-1][i] = VBAR;
  162.     board[0][0] = board[0][MAXY-1] = board[MAXX-1][0] = board[MAXX-1][MAXY-1] = '+';
  163.     board[rand()%(MAXX-2)+1][rand()%(MAXY-2)+1] = TARGET;
  164. }
  165.  
  166.  
  167.  
  168. /*
  169.  *    move the ball and record deflections
  170.  */
  171.  
  172. moveball()
  173. {
  174.     int i,nx,ny;
  175.  
  176.     dist = 0;
  177.     i = inchar;
  178.     if (i > 0) {
  179.         inchar = -1;
  180.         switch (i) {
  181.         case SLASH:
  182.         case BSLASH:
  183.             if (board[ballx][bally] == ' ')
  184.                 board[ballx][bally] = i;
  185.             else putchx(BEL);
  186.             break;
  187.         case 'd':
  188.         case 'D':        /* delete character */
  189.             i = board[ballx][bally];
  190.             if (i == SLASH || i == BSLASH) board[ballx][bally] = ' ';
  191.             else putchx(BEL);
  192.             break;
  193.         case 'f':
  194.         case 'F':        /* faster */
  195.             if (speed < 1000) {
  196.                 speed += SPEDINC;
  197.                 putspeed();
  198.             }
  199.             break;
  200.         case 's':
  201.         case 'S':        /* slower */
  202.             if (speed > (SPEDINC + 50)) {
  203.                 speed -= SPEDINC;
  204.                 putspeed();
  205.             }
  206.             break;
  207.         case DELETE:        /* new game */
  208.             clrscrn();
  209.             return(0);
  210.             break;
  211.         case 'h':
  212.         case 'H':        /* help */
  213.             help();
  214.             return(0);
  215.             break;
  216.         default:
  217.             putchx(BEL);
  218.             break;
  219.         }
  220.     }
  221.     switch (board[ballx][bally]) {
  222.     case VBAR:
  223.         ballxv = -ballxv;
  224.         break;
  225.     case HBAR:
  226.         ballyv = -ballyv;
  227.         break;
  228.     case BSLASH:
  229.         i = ballxv;
  230.         ballxv = -ballyv;
  231.         ballyv = -i;
  232.         break;
  233.     case SLASH:
  234.         i = ballxv;
  235.         ballxv = ballyv;
  236.         ballyv = i;
  237.         break;
  238.     case TARGET:
  239.         if (--targleft <= 0) {
  240.             clrscrn();
  241.             return(0);
  242.         }
  243.         puttarg();
  244.         board[ballx][bally] = ' ';
  245.         do {
  246.             nx = rand() % (MAXX-2) + 1;
  247.             ny = rand() % (MAXY-2) + 1;
  248.         } while (board[nx][ny] != ' ');
  249.         board[nx][ny] = TARGET;
  250.         ouch(nx,ny+1,TARGET);
  251.         break;
  252.     }
  253.     nx = ballx + ballxv;
  254.     ny = bally + ballyv;
  255.     ouch(nx,ny+1,BALL);
  256.     ouch(ballx,bally+1,board[ballx][bally]);
  257.     setcux(0,0);
  258.     if (newtime) puttime();
  259.     ballx = nx;
  260.     bally = ny;
  261.     /*
  262.      * now delay for awhile
  263.      */
  264.     while (dist < (ballyv ? 22000 : 10000)) putchx(NUL);
  265.     return(1);
  266. }
  267.  
  268.  
  269.  
  270. /*
  271.  *    explain the game
  272.  */
  273.  
  274. help()
  275. {
  276.     clrscrn();
  277.     printf("The object of the game is to deflect the ball\n");
  278.     printf("by using the '/' and '\\' characters so that it\n");
  279.     printf("hits the target.  The time it takes to eliminate\n");
  280.     printf("20 targets is your score.\n\n");
  281.     printf("Other characters recognized:\n\n");
  282.     printf("\tf - increases the speed of play\n");
  283.     printf("\ts - decreases the speed of play\n");
  284.     printf("\td - deletes the character at the current position\n");
  285.     printf("\th - prints this message\n");
  286.     printf("\t^S - suspends execution\n");
  287.     printf("\t^Q - resumes execution\n");
  288.     printf("\tDELETE(rubout) - restarts the game\n");
  289.     printf("\t^C - quit\n");
  290.     printf("\nAny other characters will typically cause the bell\n");
  291.     printf("to sound.  Typing ^G (bell) will toggle the flag\n");
  292.     printf("which enables/disables the output of bells.\n\n");
  293.     printf("Type a character to resume play: ");
  294.     getchar();
  295.     clrscrn();
  296. }
  297.  
  298.  
  299. /*
  300.  *    Output character at location x,y
  301.  */
  302.  
  303. ouch(x,y,c)
  304. int x,y;
  305. int c;
  306. {
  307.     setcux(x,y);
  308.     putchx(c);
  309. }
  310.  
  311.  
  312. /*
  313.  *    Position cursor to x,y - then output string
  314.  */
  315.  
  316. outs(x,y,s)
  317. int x,y;
  318. char *s;
  319. {
  320.     setcux(x,y);
  321.     puts(s);
  322. }
  323.  
  324.  
  325. /*
  326.  *    Special version of puts - needed by srand1
  327.  */
  328.  
  329. puts(s)
  330. char *s;
  331. {
  332.     while (*s) putchx(*s++);
  333. }
  334.  
  335.  
  336. /*
  337.  *    Special variation of putchar
  338.  */
  339.  
  340. putchx(c)
  341. int c;
  342. {
  343.     if (++msecs >= MSPS) {
  344.         msecs = 0;
  345.         ++secs;
  346.         newtime = TRUE;
  347.     }
  348.     dist += speed;
  349.     if (inchar == -1) {
  350.         inchar = getchx();
  351.         switch (inchar) {
  352.         case BEL:
  353.             bellflag = !bellflag;
  354.             break;
  355.         case XOFF:
  356.             while (inchar != XON) {
  357.                 inchar = getchx();
  358.             }
  359.             inchar = -1;
  360.             break;
  361.         }
  362.     }
  363.     if (c == '\0') return;
  364.     if (c != BEL || bellflag) bios(4,c);
  365.     if (c == '\n') bios(4,'\r');
  366. }
  367.  
  368.  
  369.  
  370. /*
  371.  *    special variation of getchar
  372.  */
  373.  
  374. getchx()
  375. {
  376.     int c;
  377.  
  378.     if (bios(2)) {
  379.         for (c=0; c<10; ++c) ;        /* debounce */
  380.         c = bios(3) & 0177;
  381.         if (c == QUITCH) {
  382.             clrscrn();
  383.             exit();
  384.         }
  385.         return(c);
  386.     }
  387.     return(-1);
  388. }
  389.  
  390.  
  391.  
  392. /*
  393.  *    print speed
  394.  */
  395.  
  396. putspeed()
  397. {
  398.     char buff[10];
  399.  
  400.     sprintf(buff,"%03d",speed/10);
  401.     buff[3] = '\0';
  402.     outs(SPEEDX,SPEEDY,buff);
  403. }
  404.  
  405.  
  406. /*
  407.  *    update target count
  408.  */
  409.  
  410. puttarg()
  411. {
  412.     char buff[10];
  413.  
  414.     sprintf(buff,"%02d",targleft);
  415.     buff[2] = '\0';
  416.     outs(TARGX,TARGY,buff);
  417. }
  418.  
  419.  
  420. /*
  421.  *    update time display
  422.  */
  423.  
  424. puttime()
  425. {
  426.     char buff[10];
  427.  
  428.     sprintf(buff,"%03d",secs);
  429.     buff[3] = '\0';
  430.     outs(TIMX,TIMY,buff);
  431.     newtime = FALSE;
  432. }
  433.  
  434.  
  435. /*
  436.  *    Special version of set cursor which utilizes putchx.
  437.  *    This version is for VT-52.
  438.  *    Well, so much for portability.
  439.  */
  440.  
  441. setcux(x,y)
  442. int x,y;
  443. {
  444.     putchx(ESC);
  445.     putchx('Y');
  446.     putchx(23-y+' ');
  447.     putchx(x+' ');
  448. }