home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume19 / xblockbuster / part05 / balls_pallet.c
C/C++ Source or Header  |  1993-04-28  |  16KB  |  606 lines

  1. /*
  2.  * File:       balls_pallet.c
  3.  * Author:     Eric Van Gestel
  4.  * Updated for X11 by Mark S. Wedel
  5.  *
  6.  * For:                xblockbuster
  7.  *
  8.  * Implementation:
  9.  *     Drawing is to be done twice with the same coordinates such that
  10.  *     the second removes the first while restoring the context.
  11.  *     The procedure move_balls is called on timeout (xblockbuster.c)
  12.  *     The procedure draw_pallet is called whenever the pallet changes (mouse
  13.  *     movement event, button 1 or 2, or hitting a clipper.)
  14.  *     Auxilary print functions added by MSW to help clean up the code a
  15.  *     little.
  16.  *     The auxiliary functions return a boolean value indicating whether
  17.  *     the hit might have increased the score.
  18.  */
  19.  
  20.  
  21. #include "xblockbuster.h"
  22.  
  23. #include "icons/ball.pr"
  24.  
  25. static char    str[256];
  26.  
  27.  
  28. void print_score()
  29. {
  30.     sprintf(str, "Score:  %d ", score );
  31.     XDrawImageString(display, win, gc, OFFSET_SCORE, font_height, str, 
  32.             strlen(str));
  33. }
  34.  
  35. void print_balls()
  36. {
  37.     sprintf(str, "Balls left:  %d ", balls_left);
  38.     XDrawImageString(display, win, gc, OFFSET_BALLS, font_height, str, 
  39.             strlen(str));
  40. }
  41.  
  42. Pixmap ball_pr;
  43. extern int    in_event, do_balls, timer_active;
  44.  
  45. void ball_init()
  46. {
  47.     ball_pr = XCreateBitmapFromData(display, win, ball_bits, ball_width, ball_height);
  48. }
  49.  
  50. /* Macro to draw a ball */
  51.  
  52. #define draw_ball( ball )      \
  53.     XCopyPlane(display, ball_pr, win, gc_xor, 0, 0, 16, 16, \
  54.         (int)( (ball)->x ) - 8, (int)( (ball)->y ) - 8, 1)
  55.  
  56.  
  57. /* Procedure to draw the pallet */
  58. void
  59. draw_pallet(  )
  60. {
  61.     XDrawLine( display, win, gc_xor, pallet_xI - pallet_lengthI + 2, pallet_yI,
  62.            pallet_xI + pallet_lengthI - 2, pallet_yI);
  63.     XDrawLine( display, win, gc_xor, pallet_xI - pallet_lengthI + 1, pallet_yI + 1,
  64.            pallet_xI + pallet_lengthI - 1, pallet_yI + 1);
  65.     XDrawLine( display, win, gc_xor, pallet_xI - pallet_lengthI, pallet_yI + 2,
  66.            pallet_xI + pallet_lengthI, pallet_yI + 2);
  67.     XDrawLine( display, win, gc_xor, pallet_xI - 1, pallet_yI + 3,
  68.            pallet_xI - 1, pallet_yI + 6);
  69.     XDrawLine( display, win, gc_xor, pallet_xI - 1, pallet_yI + 6,
  70.            pallet_xI + 1, pallet_yI + 6);
  71.     XDrawLine( display, win, gc_xor, pallet_xI + 1, pallet_yI + 6,
  72.            pallet_xI + 1, pallet_yI + 3);
  73.     XDrawLine( display, win, gc_xor, 0, mouse_yI - 1,    /* <HC> */
  74.            10, mouse_yI - 1);
  75.     XDrawLine( display, win, gc_xor, 0, mouse_yI,
  76.            10, mouse_yI);
  77.     XDrawLine( display, win, gc_xor, 0, mouse_yI + 1,    /* <HC> */
  78.            10, mouse_yI + 1);
  79.     XDrawLine( display, win, gc_xor, STAGE_WIDTH_IN_PIXELS - 1, mouse_yI - 1,    /* <HC> */
  80.            STAGE_WIDTH_IN_PIXELS - 11, mouse_yI - 1);
  81.     XDrawLine( display, win, gc_xor, STAGE_WIDTH_IN_PIXELS - 1, mouse_yI,
  82.            STAGE_WIDTH_IN_PIXELS - 11, mouse_yI);
  83.     XDrawLine( display, win, gc_xor, STAGE_WIDTH_IN_PIXELS - 1, mouse_yI + 1,    /* <HC> */
  84.            STAGE_WIDTH_IN_PIXELS - 11, mouse_yI + 1);
  85. }
  86.  
  87.  
  88. /* Procedure to show the speeds */
  89. #define SX     OFFSET_SPEED + 70
  90. void
  91. show_speeds(  )
  92. {
  93.     int             sp;
  94.  
  95.     XDrawImageString(display, win, gc, OFFSET_SPEED, font_height,
  96.         "Speed:          ",16);
  97.  
  98.     /* scale line */
  99.     XDrawLine( display, win, gc, SX, font_height - 1, SX + SPEED_RESOLUTION - 1, font_height - 1);
  100.     XDrawLine( display, win, gc, SX, font_height, SX + SPEED_RESOLUTION, font_height);
  101.     XDrawLine( display, win, gc, SX, font_height + 1, SX + SPEED_RESOLUTION - 1, font_height + 1);
  102.  
  103.     /* base bar */
  104.     XDrawLine( display, win, gc, SX, font_height - 12, SX, font_height + 3);
  105.     XDrawLine( display, win, gc, SX + 1, font_height - 12, SX + 1, font_height + 3);
  106.  
  107.     /* launch speed bar */
  108.     sp = ( int ) ( launch_speed * SPEED_RESOLUTION_FACTOR );
  109.     if ( launch_speed < MAX_SPEED )
  110.         XDrawLine( display, win, gc, SX + sp, font_height - 2, SX + sp, font_height + 2);
  111.     else
  112.         XDrawLine( display, win, gc, SX + sp, font_height - 2, SX + sp, font_height + 2);
  113.  
  114.     /* ball lines */
  115.     if ( ball1.quadrant ) {
  116.         sp = ( int ) ( ball1.speed * SPEED_RESOLUTION_FACTOR );
  117.         XDrawLine( display, win, gc, SX, font_height - 4, SX + sp, font_height - 4);
  118.     }
  119.     if ( ball2.quadrant ) {
  120.         sp = ( int ) ( ball2.speed * SPEED_RESOLUTION_FACTOR );
  121.         XDrawLine( display, win, gc, SX, font_height - 7, SX + sp, font_height - 7);
  122.     }
  123.     if ( ball3.quadrant ) {
  124.         sp = ( int ) ( ball3.speed * SPEED_RESOLUTION_FACTOR );
  125.         XDrawLine( display, win, gc, SX, font_height - 10, SX + sp, font_height - 10);
  126.     }
  127. }
  128.  
  129.  
  130.  
  131. /* auxiliary procedures */
  132. void
  133. new_ball( ball )
  134.     register struct Ball *ball;
  135. {
  136.     if ( balls_left-- ) {
  137.         ball->quadrant = launch_quadrant;
  138.         ball->angle = 0.0;
  139.         ball->row = launch_row;
  140.         ball->col = launch_col;
  141.         ball->x = launch_x;
  142.         ball->y = launch_y;
  143.         ball->speed = launch_speed;
  144.         ball->x_speed = launch_speed * ( ( ball->quadrant == NE ) ? M_SQRT2_2
  145.                           /* NW */ : -M_SQRT2_2 );
  146.         ball->y_speed = launch_speed * -M_SQRT2_2;
  147.         /* initial ball image */
  148.         draw_ball( ball );
  149.         /* show balls left */
  150.         print_balls();
  151.         /* show speeds */
  152.         show_speeds(  );
  153.     } else {
  154.         balls_left = 0;    /* kludge */
  155.         XDrawImageString(display, win, gc, 0, font_height,
  156.             "Game Over.",10 );
  157.         sleep( 2 );
  158.         show_score_board(  );    /* BYE !! */
  159.     }
  160. }
  161.  
  162.  
  163. void
  164. blow_up( row, col )
  165.     register int    row, col;
  166. {
  167.     if ( stage[row][col].code == ' ' )
  168.         return;        /* nothing there */
  169.     if ( IS_HIT_BRICK( stage[row][col].code ) )
  170.         nbricks--;
  171.     stage[row][col].code = 'R';
  172.     draw_brick( row, col );
  173. }
  174.  
  175.  
  176. int                /* boolean */
  177. hit_brick( hit, ball )
  178.     register int    hit;    /* enumeration { HORIZONTAL, VERTICAL } */
  179.     register struct Ball *ball;
  180. {
  181.     register struct Brick *brick = &stage[ball->row][ball->col];
  182.     register int    busted = FALSE;
  183.     register int    redraw = FALSE;
  184.     register int    score_hit = FALSE;
  185.     char        str[80];
  186.  
  187.     /* has the ball left the stage vertically ? */
  188.     if ( ball->row < 0 || ball->row > MAX_ROW ) {
  189.         ball->quadrant = NO_BALL;    /* so much for this ball */
  190.         return ( score_hit );
  191.     }
  192.     /* check for looping */
  193.     switch ( brick->code ) {
  194.     case ' ':        /* no hit */
  195.         break;
  196.     case '#':
  197.     case '/':
  198.     case '\\':
  199.     case '^':
  200.     case '0':
  201.     case 'A':
  202.     case 'R':
  203.     case 'S':
  204.     case 'U':        /* because it may undo another one */
  205.     case 'W':
  206.     case '%':
  207.         if ( !( ++loop_nhits % LOOP_MAX ) )
  208.             ball->x -=
  209.                 ball->x_speed * ( double ) ( loop_nhits / LOOP_MAX ) + 1;
  210.         /* horizontal shift, trying to get out of a bounce loop */
  211.         /* negative to try to avoid leaving the stage */
  212.         break;
  213.     default:        /* non-solid brick */
  214.         loop_nhits = 0;
  215.     }
  216.  
  217.     /* advance score taking special action if needed */
  218.     switch ( brick->code ) {
  219.     case ' ':        /* clear space */
  220.         /* has the ball left the stage horizontally ? */
  221.         if ( ball->col <= 0 || ball->col >= MAX_COL ) {
  222.             ball->quadrant = NO_BALL;    /* so much for this ball */
  223.         }
  224.         return ( score_hit );    /* no hit */
  225.  
  226.     case '#':        /* solid wall */
  227.     case '/':        /* launchpad NE */
  228.     case '\\':        /* launchpad NW */
  229.     case '^':        /* emitter */
  230.         break;
  231.  
  232.     case '0':        /* solid brick */
  233.         score += score_incr;
  234.         score_hit = TRUE;
  235.         break;
  236.  
  237.     case 'A':        /* absorber */
  238.         ball->x += ( double ) ( emit_col - ball->col ) * 64;
  239.         ball->y += ( double ) ( emit_row - ball->row ) * 16;
  240.         break;
  241.     case 'C':        /* clipper */
  242.         if ( ++( brick->nhits ) == 2 ) {
  243.             draw_pallet();
  244.             pallet_lengthI -= pallet_lengthI / 5;
  245.             if ( pallet_lengthI < MIN_PALLET_LENGTH )
  246.                 pallet_lengthI = MIN_PALLET_LENGTH;
  247.             pallet_length = ( double ) pallet_lengthI;
  248.             busted = TRUE;
  249.             draw_pallet();
  250.         }
  251.         break;
  252.     case 'D':        /* double */
  253.         if ( ++( brick->nhits ) == 2 ) {
  254.             score_incr *= 2;
  255.             busted = TRUE;
  256.             sprintf(str,"Bonus x%d",score_incr);
  257.             XDrawImageString(display, win, gc,
  258.              OFFSET_SCORE, font_height*2, str, 
  259.                 strlen(str));
  260.         }
  261.         break;
  262.     case 'E':        /* extra ball */
  263.         if ( ++( brick->nhits ) == 2 ) {
  264.             balls_left++;
  265.             print_balls();
  266.             busted = TRUE;
  267.         }
  268.         break;
  269.     case 'G':        /* gap */
  270.         if ( ++( brick->nhits ) == 2 ) {
  271.             ball->quadrant = NO_BALL;    /* so much for this ball */
  272.             busted = TRUE;
  273.         }
  274.         break;
  275.     case 'H':        /* halt */
  276.         if ( ++( brick->nhits ) == 3 )
  277.             busted = TRUE;
  278.         {
  279.             double          pause = 0.1 * ( double ) ( 10 - brick->nhits );
  280.  
  281.             ball->speed *= pause;
  282.             ball->x_speed *= pause;
  283.             ball->y_speed *= pause;
  284.         }
  285.         /* approximative; will be corrected on next pallet deflection */
  286.         show_speeds(  );
  287.         break;
  288.     case 'I':        /* invisible brick */
  289.         score += score_incr;
  290.         brick->code = '1';
  291.         nbricks++;
  292.         score_hit = redraw = TRUE;
  293.         break;
  294.     case 'L':        /* launch ball */
  295.         if ( ++( brick->nhits ) == 2 ) {
  296.             balls_left++;    /* kludge to avoid consuming a ball */
  297.             if ( !ball1.quadrant )
  298.                 new_ball( &ball1 );
  299.             else if ( !ball2.quadrant )
  300.                 new_ball( &ball2 );
  301.             else if ( !ball3.quadrant )
  302.                 new_ball( &ball3 );
  303.             else
  304.                 print_balls();
  305.             show_speeds(  );
  306.             busted = TRUE;
  307.         }
  308.         break;
  309.     case 'M':        /* mine */
  310.         if ( ++( brick->nhits ) == 3 ) {
  311.             blow_up( ball->row - 1, ball->col - 1 );
  312.             blow_up( ball->row - 1, ball->col );
  313.             blow_up( ball->row - 1, ball->col + 1 );
  314.             blow_up( ball->row, ball->col - 1 );
  315.             blow_up( ball->row, ball->col + 1 );
  316.             blow_up( ball->row + 1, ball->col - 1 );
  317.             blow_up( ball->row + 1, ball->col );
  318.             blow_up( ball->row + 1, ball->col + 1 );
  319.             busted = TRUE;
  320.         }
  321.         break;
  322.     case 'P':        /* pause */
  323.         if ( ++( brick->nhits ) == 8 ) {
  324.             launch_speed -= ( launch_speed - INIT_SPEED ) * 0.3;
  325.             busted = TRUE;
  326.         }
  327.         show_speeds(  );
  328.         break;
  329.     case 'R':        /* refractor */
  330.         ball->angle = -( ball->angle );
  331.         {
  332.             register int    sign = ( ball->x_speed * ball->y_speed ) < 0;
  333.             register double tmp = ball->x_speed;
  334.  
  335.             ball->x_speed = sign ? -( ball->y_speed ) : ball->y_speed;
  336.             ball->y_speed = sign ? -tmp : tmp;
  337.             /*
  338.              * note no check for NEAR_HORIZONTAL and none needed
  339.              * since,
  340.              */
  341.             /*
  342.              * if it gets too horizontal, it probably will hit it
  343.              * again.
  344.              */
  345.         }
  346.         return ( FALSE );    /* no deflection */
  347.     case 'S':        /* speeder */
  348.         if ( ball->speed < SPEED_LIMIT ) {
  349.             ball->speed += SPEED_INCR;
  350.             ball->x_speed += ( ball->x_speed < 0 ) ? -SPEED_INCR_2
  351.                 : SPEED_INCR_2;
  352.             ball->y_speed += ( ball->y_speed < 0 ) ? -SPEED_INCR_2
  353.                 : SPEED_INCR_2;
  354.             /*
  355.              * approximative; will be corrected on next pallet
  356.              * deflection
  357.              */
  358.             show_speeds(  );
  359.         } else
  360.             pallet_modif++;
  361.         break;
  362.     case 'T':        /* triple */
  363.         if ( ++( brick->nhits ) == 3 ) {
  364.             score_incr *= 3;
  365.             busted = TRUE;
  366.             sprintf(str,"Bonus x%d",score_incr);
  367.             XDrawImageString(display, win, gc,
  368.              OFFSET_SCORE, font_height*2, str, 
  369.                 strlen(str));
  370.         }
  371.         break;
  372.     case 'U': /* undo */ ;
  373.         /* effective only after something has been busted */
  374.         if ( last_busted_brick ) {
  375.             last_busted_brick->code = last_busted_code;
  376.             last_busted_brick->nhits = 0;
  377.             if ( IS_HIT_BRICK( last_busted_code ) )
  378.                 nbricks++;
  379.             draw_brick( last_busted_row, last_busted_col );
  380.             busted = TRUE;
  381.         }
  382.         break;
  383.     case 'W': /* open window */ ;
  384.         brick->code = '%';
  385.          /* redraw = TRUE */ draw_brick( ball->row, ball->col );
  386.         return ( score_hit );    /* no deflection */
  387.     case '%': /* closed window */ ;
  388.         brick->code = 'W';
  389.         redraw = TRUE;
  390.         break;
  391.     case 'X':        /* expander */
  392.         if ( ++( brick->nhits ) == 4 ) {
  393.             pallet_modif -= 2 * PALLET_INCR;
  394.             busted = TRUE;
  395.         }
  396.         break;
  397.  
  398.     default:
  399.         if ( brick->code >= '1' && brick->code <= '9' ) {
  400.             /* hit bricks */
  401.             score += ++( brick->nhits ) * score_incr;
  402.             score_hit = TRUE;
  403.             if ( brick->nhits == brick->code - '0' )
  404.                 busted = TRUE;
  405.             else
  406.                 redraw = TRUE;
  407.         } else {    /* 'a' .. 'e' & 'j' */
  408.             /* bonus= bricks */
  409.             if ( ++( brick->nhits ) > brick->code - 'a' + 1 ) {
  410.                 score += ( brick->code - 'a' + 1 ) * 10 * score_incr;
  411.                 score_hit = busted = TRUE;
  412.             }
  413.         }
  414.     }
  415.     if ( busted ) {
  416.         last_busted_brick = brick;
  417.         last_busted_code = brick->code;
  418.         last_busted_row = ball->row;
  419.         last_busted_col = ball->col;
  420.         if ( IS_HIT_BRICK( brick->code ) )
  421.             nbricks--;
  422.         brick->code = ' ';
  423.         redraw = TRUE;
  424.     }
  425.     /* redraw brick (never on the sides) */
  426.     if ( redraw ) {
  427.         if ( pallet_row == ball->row )
  428.             draw_pallet(  );    /* avoid shadow */
  429.         draw_brick( ball->row, ball->col );
  430.         if ( pallet_row == ball->row )
  431.             draw_pallet(  );    /* restore */
  432.     }
  433.     /* deflection */
  434.     if ( ball->col <= 0 || ball->col >= MAX_COL ) {
  435.         /*
  436.          * kludge to avoid tunnelling out through the side (or
  437.          * corner)
  438.          */
  439.         if ( ( ball->col <= 0 &&
  440.                ( ball->quadrant == NW || ball->quadrant == SW ) ) ||
  441.              ( ball->col >= MAX_COL &&
  442.                ( ball->quadrant == NE || ball->quadrant == SE ) ) )
  443.             brick_deflection( VERTICAL, ball );
  444.         if ( ( ball->row == 0 &&
  445.                ( ball->quadrant == NE || ball->quadrant == NW ) ) ||
  446.              ( ball->row == MAX_ROW &&
  447.                ( ball->quadrant == SE || ball->quadrant == SW ) ) )
  448.             brick_deflection( HORIZONTAL, ball );
  449.     } else
  450.         brick_deflection( hit, ball );
  451.  
  452.     return ( score_hit );
  453. }
  454.  
  455. int                /* boolean */
  456. move_ball( ball )
  457.     register struct Ball *ball;
  458. {
  459.     register int    tmp;    /* tmp row or col designation */
  460.     register int    hit = FALSE;    /* enumeration { FALSE, HORIZONTAL,
  461.                      * VERTICAL } */
  462.     register int    score_hit = FALSE;    /* boolean */
  463.  
  464.     /* erase ball image */
  465.     draw_ball( ball );
  466.  
  467.     /* move ball */
  468.     ball->x += ball->x_speed;
  469.     ball->y += ball->y_speed;
  470.  
  471.     /* might it have hit a brick ? */
  472.     if ( ( tmp = X_COL( ball->x ) ) != ball->col ) {
  473.         ball->col = tmp;
  474.         hit = VERTICAL;
  475.     }
  476.     if ( ( tmp = Y_ROW( ball->y ) ) != ball->row ) {
  477.         ball->row = tmp;
  478.         hit = HORIZONTAL;    /* HORIZONTAL takes precedence over
  479.                      * VERTICAL */
  480.     }
  481.     if ( hit )
  482.         score_hit = hit_brick( hit, ball );
  483.     if ( !ball->quadrant ) {
  484.         /* so much for this ball */
  485.         show_speeds(  );
  486.         return ( score_hit );
  487.     }
  488.     /* might it have hit the pallet ? */
  489.     if ( ball->y >= pallet_y - 0.1 &&    /* round of protection */
  490.          ball->y <= pallet_y + ball->y_speed &&
  491.          ball->x >= pallet_x - pallet_length &&
  492.          ball->x <= pallet_x + pallet_length ) {
  493.         loop_nhits = 0;
  494.         pallet_deflection( ball );
  495.     }
  496.     /* redraw ball image */
  497.     draw_ball( ball );
  498.  
  499.     return ( score_hit );
  500. }
  501.  
  502. void check_ball(ball, old_pallet_y)
  503. register struct Ball *ball;
  504. double old_pallet_y;
  505. {
  506.     if ( ball->y >= pallet_y - 0.1 &&    /* round of protection */
  507.          ball->y <= old_pallet_y + ball->y_speed &&
  508.          ball->x >= pallet_x - pallet_length &&
  509.          ball->x <= pallet_x + pallet_length ) {
  510.         loop_nhits = 0;
  511.         pallet_deflection( ball );
  512.     }
  513. }
  514.  
  515. void
  516. check_deflections(old_pallet_y )
  517. double old_pallet_y;
  518. {
  519.     if (ball1.quadrant) check_ball(&ball1,old_pallet_y);
  520.     if (ball2.quadrant) check_ball(&ball3,old_pallet_y);
  521.     if (ball3.quadrant) check_ball(&ball3,old_pallet_y);
  522. }
  523.  
  524.  
  525. void draw_balls()
  526. {
  527.     if ( ball1.quadrant ) draw_ball(&ball1);
  528.     if ( ball2.quadrant ) draw_ball(&ball2);
  529.     if ( ball3.quadrant ) draw_ball(&ball3);
  530. }
  531.  
  532.  
  533. /*** on timeout event ***/
  534. void move_balls( )
  535. {
  536.     register int    score_hit1 = FALSE, score_hit2 = FALSE, score_hit3 = FALSE;
  537.  
  538.     /* start new ball if none left */
  539.     if ( !ball1.quadrant && !ball2.quadrant && !ball3.quadrant ) {
  540.         new_ball( &ball1 );
  541.     }
  542.  
  543.     /* move balls */
  544.     if ( ball1.quadrant )
  545.         score_hit1 = move_ball( &ball1 );
  546.     if ( ball2.quadrant )
  547.         score_hit2 = move_ball( &ball2 );
  548.     if ( ball3.quadrant )
  549.         score_hit3 = move_ball( &ball3 );
  550.  
  551.     /* start new stage if no more bricks to bust */
  552.     if ( nbricks <= 0 ) {
  553.  
  554.         /* add stage bonus */
  555.         score += 100;
  556.  
  557.         XFillRectangle( display,win, gc_erase,
  558.             0, 0, STAGE_WIDTH_IN_PIXELS - 1, MSG_HEIGHT);
  559.         XDrawImageString(display, win, gc,
  560.              0,font_height, " Stage bonus: 100",17);
  561.  
  562.  
  563.         /* erase ball images */
  564.         if ( ball1.quadrant ) {
  565.             ball1.quadrant = NO_BALL;
  566.             balls_left++;    /* kludge to avoid consuming the ball */
  567.             draw_ball( &ball1 );
  568.         }
  569.         if ( ball2.quadrant ) {
  570.             ball2.quadrant = NO_BALL;
  571.             balls_left++;    /* kludge to avoid consuming the ball */
  572.             draw_ball( &ball2 );
  573.         }
  574.         if ( ball3.quadrant ) {
  575.             ball3.quadrant = NO_BALL;
  576.             balls_left++;    /* kludge to avoid consuming the ball */
  577.             draw_ball( &ball3 );
  578.         }
  579.         /* update score */
  580.         print_score();
  581.         timer_active=0;
  582.         /* off we go again */
  583.         new_stage(  );
  584.  
  585.     } else {
  586.  
  587.         /* update score */
  588.         if ( score_hit1 || score_hit2 || score_hit3 )
  589.             print_score();
  590.  
  591.  
  592.         if (!ball1.quadrant && !ball2.quadrant && !ball3.quadrant) {
  593.             timer_active=0;
  594.             XFlush(display);
  595.             if (balls_left==0) {
  596.                 print_balls();
  597.                 show_score_board(  );    /* BYE !! */
  598.             }
  599.         }
  600.     }
  601.  
  602. }
  603.  
  604.  
  605.  
  606.