[comp.sources.games] v11i018: blockbuster - clear the bricks games

billr@saab.CNA.TEK.COM (Bill Randle) (08/10/90)

Submitted-by: Eric Van Gestel <ericvg%BLEKUL60.BITNET@cunyvm.cuny.edu>
Posting-number: Volume 11, Issue 18
Archive-name: blockbuster/Part01

	[I've played this on my Sun 3/60 (OS 3.5) and it works,
	 although the ball speed could stand to be faster. It would
	 probably do well on a SS.  -br]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 3)."
# Contents:  README MANIFEST STAGES STAGES.try STAGES.try/save
#   STAGES.wacko STAGES.wacko/save STAGES/save balls_pallet.c
#   blockbuster.h blockbuster.man bricks.c icons stage.c stage.skel
# Wrapped by billr@saab on Thu Aug  9 16:34:56 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1036 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X/*
X * The blockbuster game for Sun running Sunview.
X * Appearance ONLY shamelessly stolen from the real video game,
X * wonderfully written by someone somewhere (I haven't got the foggiest).
X *
X * Move mouse to move pallet and keep the ball on the stage.
X *
X * Stages are built from various building blocks, some of which are based on
X * recollection from analogous blocks in the video game, others, in particular
X * the interesting ones, are new.
X *
X * The stages can be defined from the ascii map codes using any text editor.
X * They must be numbered consecutively from 0 with the total number
X * (i.e., one more than the highest number) available in the file nb_stages.
X *
X * -- Eric Van Gestel (ericvg@cs.kuleuven.ac.be)
X */
X
XListing and selecting alternate playgrounds as per the man page
Xadded by Bill Randle (billr@saab.CNA.TEK.COM) 9 August 1990.
X[The man page described the "play_ground" option, but it wasn't
Ximplemented in the code until now.]
X
XBe sure to edit blockbuster.h and/or Makefile if the directory
Xpathnames change.
END_OF_FILE
if test 1036 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(3214 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X MANIFEST                   1	This shipping list
X Makefile                   2	
X RATIONAL                   2	
X README                     1	
X STAGES                     1	
X STAGES.try                 1	
X STAGES.try/nb_stages       3	
X STAGES.try/save            1	
X STAGES.try/scores          3	
X STAGES.wacko               1	
X STAGES.wacko/nb_stages     3	
X STAGES.wacko/save          1	
X STAGES.wacko/scores        3	
X STAGES.wacko/stage0        2	
X STAGES.wacko/stage1        2	
X STAGES/nb_stages           3	
X STAGES/save                1	
X STAGES/scores              3	
X STAGES/stage0              2	
X STAGES/stage1              2	
X STAGES/stage10             2	
X STAGES/stage11             2	
X STAGES/stage12             2	
X STAGES/stage13             2	
X STAGES/stage14             2	
X STAGES/stage15             2	
X STAGES/stage16             2	
X STAGES/stage17             2	
X STAGES/stage18             2	
X STAGES/stage19             2	
X STAGES/stage2              2	
X STAGES/stage20             2	
X STAGES/stage21             2	
X STAGES/stage22             2	
X STAGES/stage23             2	
X STAGES/stage3              2	
X STAGES/stage4              2	
X STAGES/stage5              2	
X STAGES/stage6              2	
X STAGES/stage7              2	
X STAGES/stage8              2	
X STAGES/stage9              2	
X balls_pallet.c             1	
X blockbuster.SKEL           2	
X blockbuster.c              2	
X blockbuster.h              1	
X blockbuster.man            1	
X bricks.c                   1	
X bricks.h                   3	
X deflection.c               2	
X icons                      1	
X icons/ball.pr              3	
X icons/blockbuster.icon     2	
X icons/brick_0.pr           3	
X icons/brick_1.pr           3	
X icons/brick_2.pr           3	
X icons/brick_3.pr           3	
X icons/brick_4.pr           3	
X icons/brick_5.pr           3	
X icons/brick_6.pr           3	
X icons/brick_7.pr           3	
X icons/brick_8.pr           3	
X icons/brick_9.pr           3	
X icons/brick_A.pr           3	
X icons/brick_C.pr           3	
X icons/brick_D.pr           3	
X icons/brick_E.pr           3	
X icons/brick_G.pr           3	
X icons/brick_H.pr           3	
X icons/brick_L.pr           3	
X icons/brick_M.pr           3	
X icons/brick_P.pr           3	
X icons/brick_R.pr           3	
X icons/brick_S.pr           2	
X icons/brick_T.pr           3	
X icons/brick_U.pr           3	
X icons/brick_W.pr           3	
X icons/brick_X.pr           3	
X icons/brick_a.pr           3	
X icons/brick_b.pr           3	
X icons/brick_c.pr           3	
X icons/brick_d.pr           3	
X icons/brick_e.pr           3	
X icons/brick_j.pr           2	
X icons/clear.pr             3	
X icons/clear0.pr            3	
X icons/launchNE.pr          2	
X icons/launchNE0.pr         3	
X icons/launchNW.pr          2	
X icons/launchNW0.pr         3	
X icons/solid.pr             3	
X icons/solid0.pr            3	
X save.c                     2	
X score.c                    2	
X smm.SKEL                   3	
X stage.c                    1	
X stage.skel                 1	
X stagemm.c                  3	
X tes.SKEL                   3	
X try.SKEL                   3	
END_OF_FILE
if test 3214 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test ! -d 'STAGES' ; then
    echo shar: Creating directory \"'STAGES'\"
    mkdir 'STAGES'
fi
if test ! -d 'STAGES.try' ; then
    echo shar: Creating directory \"'STAGES.try'\"
    mkdir 'STAGES.try'
fi
if test ! -d 'STAGES.try/save' ; then
    echo shar: Creating directory \"'STAGES.try/save'\"
    mkdir 'STAGES.try/save'
fi
if test ! -d 'STAGES.wacko' ; then
    echo shar: Creating directory \"'STAGES.wacko'\"
    mkdir 'STAGES.wacko'
fi
if test ! -d 'STAGES.wacko/save' ; then
    echo shar: Creating directory \"'STAGES.wacko/save'\"
    mkdir 'STAGES.wacko/save'
fi
if test ! -d 'STAGES/save' ; then
    echo shar: Creating directory \"'STAGES/save'\"
    mkdir 'STAGES/save'
fi
if test -f 'balls_pallet.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'balls_pallet.c'\"
else
echo shar: Extracting \"'balls_pallet.c'\" \(15924 characters\)
sed "s/^X//" >'balls_pallet.c' <<'END_OF_FILE'
X/*
X * File:       balls_pallet.c
X * Author:     Eric Van Gestel
X *
X * For:                blockbuster
X *
X * Implementation:
X *     Drawing is to be done twice with the same coordinates such that
X *     the second removes the first while restoring the context.
X *     The procedures move_pallet and move_balls are to be called on
X *     mouse and timeout events respectively.
X *     The auxiliary functions return a boolean value indicating whether
X *     the hit might have increased the score.
X */
X/*** WORKAROUND for a Horizontal Crosshair ***/
X
X#include "blockbuster.h"
X#include "bricks.h"
X
Xshort           ball_image[] = {
X#include "icons/ball.pr"
X};
X
Xmpr_static( ball_pr, 16, 16, 1, ball_image );
X
X
X/* Macro to draw a ball */
X
X#define draw_ball( ball )      \
X	/* struct Ball *ball */    \
X	pw_rop( stage_win, (int)( (ball)->x ) - 8, (int)( (ball)->y ) - 8, 16, 16, \
X			PIX_XOR, &ball_pr, 0, 0 )
X
X
X/* Procedure to draw the pallet */
Xvoid
Xdraw_pallet(  )
X{
X	pw_vector( stage_win, pallet_xI - pallet_lengthI + 2, pallet_yI,
X		   pallet_xI + pallet_lengthI - 2, pallet_yI,
X		   PIX_XOR, 1 );
X	pw_vector( stage_win, pallet_xI - pallet_lengthI + 1, pallet_yI + 1,
X		   pallet_xI + pallet_lengthI - 1, pallet_yI + 1,
X		   PIX_XOR, 1 );
X	pw_vector( stage_win, pallet_xI - pallet_lengthI, pallet_yI + 2,
X		   pallet_xI + pallet_lengthI, pallet_yI + 2,
X		   PIX_XOR, 1 );
X	pw_vector( stage_win, pallet_xI - 1, pallet_yI + 3,
X		   pallet_xI - 1, pallet_yI + 6,
X		   PIX_XOR, 1 );
X	pw_vector( stage_win, pallet_xI - 1, pallet_yI + 6,
X		   pallet_xI + 1, pallet_yI + 6,
X		   PIX_XOR, 1 );
X	pw_vector( stage_win, pallet_xI + 1, pallet_yI + 6,
X		   pallet_xI + 1, pallet_yI + 3,
X		   PIX_XOR, 1 );
X	pw_vector( stage_win, 0, mouse_yI - 1,	/* <HC> */
X		   10, mouse_yI - 1,	/* <HC> */
X		   PIX_XOR, 1 );/* <HC> */
X	pw_vector( stage_win, 0, mouse_yI,
X		   10, mouse_yI,/* <HC> */
X		   PIX_XOR, 1 );/* <HC> */
X	pw_vector( stage_win, 0, mouse_yI + 1,	/* <HC> */
X		   10, mouse_yI + 1,	/* <HC> */
X		   PIX_XOR, 1 );/* <HC> */
X	pw_vector( stage_win, STAGE_WIDTH_IN_PIXELS - 1, mouse_yI - 1,	/* <HC> */
X		   STAGE_WIDTH_IN_PIXELS - 11, mouse_yI - 1,	/* <HC> */
X		   PIX_XOR, 1 );/* <HC> */
X	pw_vector( stage_win, STAGE_WIDTH_IN_PIXELS - 1, mouse_yI,
X		   STAGE_WIDTH_IN_PIXELS - 11, mouse_yI,	/* <HC> */
X		   PIX_XOR, 1 );/* <HC> */
X	pw_vector( stage_win, STAGE_WIDTH_IN_PIXELS - 1, mouse_yI + 1,	/* <HC> */
X		   STAGE_WIDTH_IN_PIXELS - 11, mouse_yI + 1,	/* <HC> */
X		   PIX_XOR, 1 );/* <HC> */
X}
X
X
X/* Procedure to show the speeds */
X#define SX     OFFSET_SPEED + 70
X#define SY     FONT_HEIGHT
Xvoid
Xshow_speeds(  )
X{
X	int             sp;
X
X	msg0( OFFSET_SPEED, "Speed:%10c", ' ' );
X
X	/* scale line */
X	pw_vector( msg_win, SX, SY - 1, SX + SPEED_RESOLUTION - 1, SY - 1, PIX_SRC, 1 );
X	pw_vector( msg_win, SX, SY, SX + SPEED_RESOLUTION, SY, PIX_SRC, 1 );
X	pw_vector( msg_win, SX, SY + 1, SX + SPEED_RESOLUTION - 1, SY + 1, PIX_SRC, 1 );
X
X	/* base bar */
X	pw_vector( msg_win, SX, SY - 12, SX, SY + 3, PIX_SRC, 1 );
X	pw_vector( msg_win, SX + 1, SY - 12, SX + 1, SY + 3, PIX_SRC, 1 );
X
X	/* launch speed bar */
X	sp = ( int ) ( launch_speed * SPEED_RESOLUTION_FACTOR );
X	if ( launch_speed < MAX_SPEED )
X		pw_vector( msg_win, SX + sp, SY - 2, SX + sp, SY + 2, PIX_XOR, 1 );
X	else
X		pw_vector( msg_win, SX + sp, SY - 2, SX + sp, SY + 2, PIX_SRC, 1 );
X
X	/* ball lines */
X	if ( ball1.quadrant ) {
X		sp = ( int ) ( ball1.speed * SPEED_RESOLUTION_FACTOR );
X		pw_vector( msg_win, SX, SY - 4, SX + sp, SY - 4, PIX_SRC, 1 );
X	}
X	if ( ball2.quadrant ) {
X		sp = ( int ) ( ball2.speed * SPEED_RESOLUTION_FACTOR );
X		pw_vector( msg_win, SX, SY - 7, SX + sp, SY - 7, PIX_SRC, 1 );
X	}
X	if ( ball3.quadrant ) {
X		sp = ( int ) ( ball3.speed * SPEED_RESOLUTION_FACTOR );
X		pw_vector( msg_win, SX, SY - 10, SX + sp, SY - 10, PIX_SRC, 1 );
X	}
X}
X
X
X
X/* auxiliary procedures */
Xvoid
Xnew_ball( ball )
X	register struct Ball *ball;
X{
X	if ( balls_left-- ) {
X		ball->quadrant = launch_quadrant;
X		ball->angle = 0.0;
X		ball->row = launch_row;
X		ball->col = launch_col;
X		ball->x = launch_x;
X		ball->y = launch_y;
X		ball->speed = launch_speed;
X		ball->x_speed = launch_speed * ( ( ball->quadrant == NE ) ? M_SQRT2_2
X						  /* NW */ : -M_SQRT2_2 );
X		ball->y_speed = launch_speed * -M_SQRT2_2;
X		/* initial ball image */
X		draw_ball( ball );
X		/* show balls left */
X		msg0( OFFSET_BALLS, "Balls left:  %d ", balls_left );
X		/* show speeds */
X		show_speeds(  );
X	} else {
X		balls_left = 0;	/* kludge */
X		msg( 0, "Game Over." );
X		sleep( 2 );
X		show_score_board(  );	/* BYE !! */
X	}
X}
X
X
Xvoid
Xblow_up( row, col )
X	register int    row, col;
X{
X	if ( stage[row][col].code == ' ' )
X		return;		/* nothing there */
X	if ( IS_HIT_BRICK( stage[row][col].code ) )
X		nbricks--;
X	stage[row][col].code = 'R';
X	draw_brick( row, col );
X}
X
X
Xint				/* boolean */
Xhit_brick( hit, ball )
X	register int    hit;	/* enumeration { HORIZONTAL, VERTICAL } */
X	register struct Ball *ball;
X{
X	register struct Brick *brick = &stage[ball->row][ball->col];
X	register int    busted = FALSE;
X	register int    redraw = FALSE;
X	register int    score_hit = FALSE;
X
X	/* has the ball left the stage vertically ? */
X	if ( ball->row < 0 || ball->row > MAX_ROW ) {
X		ball->quadrant = NO_BALL;	/* so much for this ball */
X		return ( score_hit );
X	}
X	/* check for looping */
X	switch ( brick->code ) {
X	case ' ':		/* no hit */
X		break;
X	case '#':
X	case '/':
X	case '\\':
X	case '^':
X	case '0':
X	case 'A':
X	case 'R':
X	case 'S':
X	case 'U':		/* because it may undo another one */
X	case 'W':
X	case '%':
X		if ( !( ++loop_nhits % LOOP_MAX ) )
X			ball->x -=
X				ball->x_speed * ( double ) ( loop_nhits / LOOP_MAX ) + 1;
X		/* horizontal shift, trying to get out of a bounce loop */
X		/* negative to try to avoid leaving the stage */
X		break;
X	default:		/* non-solid brick */
X		loop_nhits = 0;
X	}
X
X	/* advance score taking special action if needed */
X	switch ( brick->code ) {
X	case ' ':		/* clear space */
X		/* has the ball left the stage horizontally ? */
X		if ( ball->col <= 0 || ball->col >= MAX_COL ) {
X			ball->quadrant = NO_BALL;	/* so much for this ball */
X		}
X		return ( score_hit );	/* no hit */
X
X	case '#':		/* solid wall */
X	case '/':		/* launchpad NE */
X	case '\\':		/* launchpad NW */
X	case '^':		/* emitter */
X		break;
X
X	case '0':		/* solid brick */
X		score += score_incr;
X		score_hit = TRUE;
X		break;
X
X	case 'A':		/* absorber */
X		ball->x += ( double ) ( emit_col - ball->col ) * 64;
X		ball->y += ( double ) ( emit_row - ball->row ) * 16;
X		break;
X	case 'C':		/* clipper */
X		if ( ++( brick->nhits ) == 2 ) {
X			pallet_lengthI -= pallet_lengthI / 5;
X			if ( pallet_lengthI < MIN_PALLET_LENGTH )
X				pallet_lengthI = MIN_PALLET_LENGTH;
X			pallet_length = ( double ) pallet_lengthI;
X			busted = TRUE;
X		}
X		break;
X	case 'D':		/* double */
X		if ( ++( brick->nhits ) == 2 ) {
X			score_incr *= 2;
X			busted = TRUE;
X		}
X		break;
X	case 'E':		/* extra ball */
X		if ( ++( brick->nhits ) == 2 ) {
X			balls_left++;
X			msg0( OFFSET_BALLS, "Balls left:  %d ", balls_left );
X			busted = TRUE;
X		}
X		break;
X	case 'G':		/* gap */
X		if ( ++( brick->nhits ) == 2 ) {
X			ball->quadrant = NO_BALL;	/* so much for this ball */
X			busted = TRUE;
X		}
X		break;
X	case 'H':		/* halt */
X		if ( ++( brick->nhits ) == 3 )
X			busted = TRUE;
X		{
X			double          pause = 0.1 * ( double ) ( 10 - brick->nhits );
X
X			ball->speed *= pause;
X			ball->x_speed *= pause;
X			ball->y_speed *= pause;
X		}
X		/* approximative; will be corrected on next pallet deflection */
X		show_speeds(  );
X		break;
X	case 'I':		/* invisible brick */
X		score += score_incr;
X		brick->code = '1';
X		nbricks++;
X		score_hit = redraw = TRUE;
X		break;
X	case 'L':		/* launch ball */
X		if ( ++( brick->nhits ) == 2 ) {
X			balls_left++;	/* kludge to avoid consuming a ball */
X			if ( !ball1.quadrant )
X				new_ball( &ball1 );
X			else if ( !ball2.quadrant )
X				new_ball( &ball2 );
X			else if ( !ball3.quadrant )
X				new_ball( &ball3 );
X			else
X				msg0( OFFSET_BALLS, "Balls left:  %d ", balls_left );
X			show_speeds(  );
X			busted = TRUE;
X		}
X		break;
X	case 'M':		/* mine */
X		if ( ++( brick->nhits ) == 3 ) {
X			blow_up( ball->row - 1, ball->col - 1 );
X			blow_up( ball->row - 1, ball->col );
X			blow_up( ball->row - 1, ball->col + 1 );
X			blow_up( ball->row, ball->col - 1 );
X			blow_up( ball->row, ball->col + 1 );
X			blow_up( ball->row + 1, ball->col - 1 );
X			blow_up( ball->row + 1, ball->col );
X			blow_up( ball->row + 1, ball->col + 1 );
X			busted = TRUE;
X		}
X		break;
X	case 'P':		/* pause */
X		if ( ++( brick->nhits ) == 8 ) {
X			launch_speed -= ( launch_speed - INIT_SPEED ) * 0.3;
X			busted = TRUE;
X		}
X		show_speeds(  );
X		break;
X	case 'R':		/* refractor */
X		ball->angle = -( ball->angle );
X		{
X			register int    sign = ( ball->x_speed * ball->y_speed ) < 0;
X			register double tmp = ball->x_speed;
X
X			ball->x_speed = sign ? -( ball->y_speed ) : ball->y_speed;
X			ball->y_speed = sign ? -tmp : tmp;
X			/*
X			 * note no check for NEAR_HORIZONTAL and none needed
X			 * since,
X			 */
X			/*
X			 * if it gets too horizontal, it probably will hit it
X			 * again.
X			 */
X		}
X		return ( FALSE );	/* no deflection */
X	case 'S':		/* speeder */
X		if ( ball->speed < SPEED_LIMIT ) {
X			ball->speed += SPEED_INCR;
X			ball->x_speed += ( ball->x_speed < 0 ) ? -SPEED_INCR_2
X				: SPEED_INCR_2;
X			ball->y_speed += ( ball->y_speed < 0 ) ? -SPEED_INCR_2
X				: SPEED_INCR_2;
X			/*
X			 * approximative; will be corrected on next pallet
X			 * deflection
X			 */
X			show_speeds(  );
X		} else
X			pallet_modif++;
X		break;
X	case 'T':		/* triple */
X		if ( ++( brick->nhits ) == 3 ) {
X			score_incr *= 3;
X			busted = TRUE;
X		}
X		break;
X	case 'U': /* undo */ ;
X		/* effective only after something has been busted */
X		if ( last_busted_brick ) {
X			last_busted_brick->code = last_busted_code;
X			last_busted_brick->nhits = 0;
X			if ( IS_HIT_BRICK( last_busted_code ) )
X				nbricks++;
X			draw_brick( last_busted_row, last_busted_col );
X			busted = TRUE;
X		}
X		break;
X	case 'W': /* open window */ ;
X		brick->code = '%';
X		 /* redraw = TRUE */ draw_brick( ball->row, ball->col );
X		return ( score_hit );	/* no deflection */
X	case '%': /* closed window */ ;
X		brick->code = 'W';
X		redraw = TRUE;
X		break;
X	case 'X':		/* expander */
X		if ( ++( brick->nhits ) == 4 ) {
X			pallet_modif -= 2 * PALLET_INCR;
X			busted = TRUE;
X		}
X		break;
X
X	default:
X		if ( brick->code >= '1' && brick->code <= '9' ) {
X			/* hit bricks */
X			score += ++( brick->nhits ) * score_incr;
X			score_hit = TRUE;
X			if ( brick->nhits == brick->code - '0' )
X				busted = TRUE;
X			else
X				redraw = TRUE;
X		} else {	/* 'a' .. 'e' & 'j' */
X			/* bonus bricks */
X			if ( ++( brick->nhits ) > brick->code - 'a' + 1 ) {
X				score += ( brick->code - 'a' + 1 ) * 10 * score_incr;
X				score_hit = busted = TRUE;
X			}
X		}
X	}
X	if ( busted ) {
X		last_busted_brick = brick;
X		last_busted_code = brick->code;
X		last_busted_row = ball->row;
X		last_busted_col = ball->col;
X		if ( IS_HIT_BRICK( brick->code ) )
X			nbricks--;
X		brick->code = ' ';
X		redraw = TRUE;
X	}
X	/* redraw brick (never on the sides) */
X	if ( redraw ) {
X		if ( pallet_row == ball->row )
X			draw_pallet(  );	/* avoid shadow */
X		draw_brick( ball->row, ball->col );
X		if ( pallet_row == ball->row )
X			draw_pallet(  );	/* restore */
X	}
X	/* deflection */
X	if ( ball->col <= 0 || ball->col >= MAX_COL ) {
X		/*
X		 * kludge to avoid tunnelling out through the side (or
X		 * corner)
X		 */
X		if ( ( ball->col <= 0 &&
X		       ( ball->quadrant == NW || ball->quadrant == SW ) ) ||
X		     ( ball->col >= MAX_COL &&
X		       ( ball->quadrant == NE || ball->quadrant == SE ) ) )
X			brick_deflection( VERTICAL, ball );
X		if ( ( ball->row == 0 &&
X		       ( ball->quadrant == NE || ball->quadrant == NW ) ) ||
X		     ( ball->row == MAX_ROW &&
X		       ( ball->quadrant == SE || ball->quadrant == SW ) ) )
X			brick_deflection( HORIZONTAL, ball );
X	} else
X		brick_deflection( hit, ball );
X
X	return ( score_hit );
X}
X
Xint				/* boolean */
Xmove_ball( ball )
X	register struct Ball *ball;
X{
X	register int    tmp;	/* tmp row or col designation */
X	register int    hit = FALSE;	/* enumeration { FALSE, HORIZONTAL,
X					 * VERTICAL } */
X	register int    score_hit;	/* boolean */
X
X	/* erase ball image */
X	draw_ball( ball );
X
X	/* move ball */
X	ball->x += ball->x_speed;
X	ball->y += ball->y_speed;
X
X	/* might it have hit a brick ? */
X	if ( ( tmp = X_COL( ball->x ) ) != ball->col ) {
X		ball->col = tmp;
X		hit = VERTICAL;
X	}
X	if ( ( tmp = Y_ROW( ball->y ) ) != ball->row ) {
X		ball->row = tmp;
X		hit = HORIZONTAL;	/* HORIZONTAL takes precedence over
X					 * VERTICAL */
X	}
X	if ( hit )
X		score_hit = hit_brick( hit, ball );
X	if ( !ball->quadrant ) {
X		/* so much for this ball */
X		show_speeds(  );
X		return ( score_hit );
X	}
X	/* might it have hit the pallet ? */
X	if ( ball->y >= pallet_y - 0.1 &&	/* round of protection */
X	     ball->y <= pallet_y + ball->y_speed &&
X	     ball->x >= pallet_x - pallet_length &&
X	     ball->x <= pallet_x + pallet_length ) {
X		loop_nhits = 0;
X		pallet_deflection( ball );
X	}
X	/* redraw ball image */
X	draw_ball( ball );
X
X	return ( score_hit );
X}
X
X
X/*** on timeout event ***/
XNotify_value
Xmove_balls( frm, which_itimer )
X	Frame           frm;	/* ignored */
X	int             which_itimer;	/* enumeration { ITIMER_REAL } **
X					 * ignored */
X{
X	register int    score_hit1 = FALSE, score_hit2 = FALSE, score_hit3 = FALSE;
X
X	/* halt cycle */
X	stop_timer(  );
X
X	/* start new ball if none left */
X	if ( !ball1.quadrant && !ball2.quadrant && !ball3.quadrant )
X		new_ball( &ball1 );
X
X	/* move balls */
X	if ( ball1.quadrant )
X		score_hit1 = move_ball( &ball1 );
X	if ( ball2.quadrant )
X		score_hit2 = move_ball( &ball2 );
X	if ( ball3.quadrant )
X		score_hit3 = move_ball( &ball3 );
X
X	/* start new stage if no more bricks to bust */
X	if ( nbricks <= 0 ) {
X
X		/* add stage bonus */
X		score += 100;
X		msg( 0, "Stage bonus: 100" );
X
X		/* erase pallet image */
X		draw_pallet(  );
X
X		/* erase ball images */
X		if ( ball1.quadrant ) {
X			ball1.quadrant = NO_BALL;
X			balls_left++;	/* kludge to avoid consuming the ball */
X			draw_ball( &ball1 );
X		}
X		if ( ball2.quadrant ) {
X			ball2.quadrant = NO_BALL;
X			balls_left++;	/* kludge to avoid consuming the ball */
X			draw_ball( &ball2 );
X		}
X		if ( ball3.quadrant ) {
X			ball3.quadrant = NO_BALL;
X			balls_left++;	/* kludge to avoid consuming the ball */
X			draw_ball( &ball3 );
X		}
X		/* update score */
X		msg0( OFFSET_SCORE, "Score:  %d ", score );
X
X		/* off we go again */
X		new_stage(  );
X
X	} else {
X
X		/* update score */
X		if ( score_hit1 || score_hit2 || score_hit3 )
X			msg0( OFFSET_SCORE, "Score:  %d ", score );
X
X		/* next cycle */
X		start_timer(  );
X	}
X
X	return ( NOTIFY_DONE );
X}
X
X
X/*** on mouse events ***/
Xint
Xmove_pallet( cvs, event, arg )
X	Canvas          cvs;	/* ignored */
X	Event          *event;
X	caddr_t         arg;	/* ignored */
X{
X	register int    tmp;
X
X	/* erase pallet image */
X	draw_pallet(  );
X
X	switch ( event_id( event ) ) {
X	case MS_LEFT:
X		if ( pallet_yI > PALLET_MIN_Y ) {
X			pallet_y = ( double ) ( pallet_yI -= 16 );
X			pallet_row--;
X		}
X		break;
X	case MS_MIDDLE:
X		pallet_y = ( double ) ( pallet_yI = PALLET_MAX_Y + 4 );
X		pallet_row = MAX_ROW - 1;
X		break;
X	case MS_RIGHT:
X		/* clear msg */
X		for ( tmp = 0; tmp < MSG_HEIGHT; tmp++ )
X			pw_vector( msg_win, 0, tmp, STAGE_WIDTH_IN_PIXELS - 1, tmp,
X				   PIX_CLR, 1 );
X		/* redo all messages */
X		msg1( OFFSET_SPEED, stage_name );
X		msg0( OFFSET_BALLS, "Balls left:  %d ", balls_left );
X		msg0( OFFSET_SCORE, "Score:  %d ", score );
X		show_speeds(  );
X		/* lets go ! */
X		move_balls(  );	/* starts the timer */
X		break;
X	case KEY_RIGHT( 1 ):
X		if ( !ball1.quadrant && !ball2.quadrant && !ball3.quadrant ) {
X			msg0( OFFSET_BALLS, "Saving...%46c", ' ' );
X			save(  );	/* BYE !! */
X		} else
X			msg0( OFFSET_BALLS, "Not saved...%43c", ' ' );
X		break;
X	default:		/* LOC_MOVE, LOC_STILL */
X		/* move pallet */
X		pallet_x = ( double ) ( pallet_xI = event_x( event ) );
X		mouse_yI = event_y( event );	/* <HC> */
X	}
X
X	/* redraw pallet image */
X	draw_pallet(  );
X}
END_OF_FILE
if test 15924 -ne `wc -c <'balls_pallet.c'`; then
    echo shar: \"'balls_pallet.c'\" unpacked with wrong size!
fi
# end of 'balls_pallet.c'
fi
if test -f 'blockbuster.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'blockbuster.h'\"
else
echo shar: Extracting \"'blockbuster.h'\" \(6458 characters\)
sed "s/^X//" >'blockbuster.h' <<'END_OF_FILE'
X/*
X * File:       blockbuster.h
X * Author:     Eric Van Gestel
X *
X * For:                blockbuster
X *
X * Compilation:
X *     -lsuntool -lsunwindow -lpixrect
X */
X
X/* file paths are defined at the end of this file */
X
X#include <stdio.h>
X#include <pwd.h>
X#include <suntool/sunview.h>
X#include <suntool/canvas.h>
X#include <sys/time.h>
X#include <sys/file.h>
X#include <ctype.h>
X#include <math.h>
X/*
X * #define M_PI                3.14159265358979323846
X * #define M_PI_2      1.57079632679489661923
X * #define M_PI_4      0.78539816339744830962
X */
X#define M_PI_3_4       2.35619449019234492885
X#define M_SQRT2_2      0.70710678118654752440
X#define NEAR_HORIZONTAL        0.7	/* < M_PI_4 */
X
X
X/*** windowing objects ***/
X
X#define BORDER         50
X#define MSG_HEIGHT     FONT_HEIGHT + 10
X
X#define MAX_ROW                42
X#define MAX_COL                11
X
X/* upper left corner of brick in pixels */
X#define COL_X( col )   (col) ? (col) * 64 - 48 + BORDER : BORDER
X#define ROW_Y( row )   (row) * 16 + BORDER
X
X/* brick coordinates */
X#define X_COL( x )     ( (int)(x) - BORDER + 48 ) / 64
X#define Y_ROW( y )     ( (int)(y) - BORDER ) / 16
X
X#define STAGE_HEIGHT_IN_PIXELS ( ( MAX_ROW + 1 ) * 16 + 2 * BORDER )
X#define STAGE_WIDTH_IN_PIXELS  ( ( MAX_COL - 1 ) * 64 + 2 * ( BORDER + 16 ) )
X
X#define PIX_XOR        (PIX_SRC^PIX_DST)
X
XFrame           frame;
XCanvas          stage_cvs, msg_cvs;
XPixwin         *stage_win, *msg_win;
XPixfont        *font;
X
X
X/*** messages ***/
X
X#define FONT_R16       "/usr/lib/fonts/fixedwidthfonts/serif.r.16"
X#define FONT_WIDTH     font->pf_defaultsize.x
X#define FONT_HEIGHT    ( font->pf_defaultsize.y + 10 )
X
X#define OFFSET_BALLS   20
X#define OFFSET_SCORE   250
X#define OFFSET_SPEED   550
X
Xchar            msg0_buf[55];
X
X#define msg0( offset, format, value )  \
X	/* int offset;  char *format;  {arg} value; */ \
X	pw_text( msg_win, offset, FONT_HEIGHT, PIX_SRC, font, \
X		sprintf( msg0_buf, format, value ) )
X
X#define msg1( offset, value )  \
X	/* int offset;  char *value; */ \
X	pw_text( stage_win, offset, FONT_HEIGHT, PIX_SRC, font, value )
X
X#define msg( offset, message ) \
X	/* int offset;  char *message; */ \
X	pw_text( stage_win, \
X		( STAGE_WIDTH_IN_PIXELS - strlen( message ) * FONT_WIDTH ) / 2, \
X		BORDER + ( 4 + offset ) * FONT_HEIGHT, \
X		PIX_SRC, font, message )
X
X
X/*** active objects ***/
X
X#define NO_BALL        0
X#define NE     1
X#define NW     2
X#define SW     3
X#define SE     4
X
X#ifndef FALSE
X#define FALSE  0
X#endif
X#ifndef TRUE
X#define TRUE   1
X#endif
X
X#define HORIZONTAL     1
X#define VERTICAL       2
X
X#define INIT_BALLS     3
X#define LOOP_MAX       100
X
X#define INIT_SPEED     3.0
X#define MAX_SPEED      8.0
X#define SPEED_LIMIT    12.0
X#define SPEED_INCR     0.2
X#define SPEED_INCR_2   0.1	/* SPEED_INCR / 2 */
X#define SPEED_RESOLUTION       60	/* SPEED_LIMIT / SPEED_INCR */
X#define SPEED_RESOLUTION_FACTOR        5.0	/* SPEED_RESOLUTION /
X						 * SPEED_LIMI
X						 * 
X						/* the stage is a two
X						 * dimensional array of
X						 * bricks */
Xstruct Brick {
X	char            code;	/* Q.V. map_codes */
X	short           nhits;
X}               stage[MAX_ROW + 1][MAX_COL + 1];
X
X#define IS_HIT_BRICK( code )   code > '0' && code <= '9'
X
Xstruct Ball {
X	int             quadrant;	/* enumeration { NO_BALL, NE, NW, SW,
X					 * SE } */
X	double          angle;	/* range -M_PI_4..NEAR_HORIZONTAL */
X	/*
X	 * NW -P4|-P4 NE +NH | +NH >>>>>>+<<<<<<  (gap to avoid infinite
X	 * horizontal bounce loops) +NH | +NH SW -P4|-P4 SE
X	 */
X	int             row, col;	/* coordinates on the stage */
X	double          x, y;	/* coordinates in pixels */
X	double          speed, x_speed, y_speed;	/* motion per update in
X							 * pixels */
X	/*
X	 * INVARIANT: x_speed == speed * cos( true_angle ) y_speed == speed *
X	 * sin( true_angle )
X	 */
X}               ball1, ball2, ball3;
X
Xint             launch_quadrant;/* enumeration { NE, NW } */
Xint             launch_row, launch_col;
Xdouble          launch_x, launch_y;
Xint             emit_row, emit_col;
X
X#define MIN_PALLET_LENGTH      12
X#define SHORT_PALLET_LENGTH    16
X#define LONG_PALLET_LENGTH     99
X#define MAX_PALLET_LENGTH      99
X#define MAX_PALLET_HEIGHT      999
X#define PALLET_INCR    100
X#define PALLET_DENOMINATOR     20000
X#define PALLET_MIN_Y   ROW_Y( MAX_ROW - 9 )
X#define PALLET_MAX_Y   ROW_Y( MAX_ROW - 1 )
X
Xint             pallet_lengthI;	/* range MIN_PALLET_LENGTH..MAX_PALLET_LENGTH */
Xint             pallet_heightI;	/* range pallet_lengthI..MAX_PALLET_HEIGHT */
Xint             pallet_xI;	/* range 0..STAGE_WIDTH_IN_PIXELS */
Xint             pallet_yI;	/* range PALLET_MAX_Y+4..PALLET_MIN_Y-12 */
Xint             pallet_row;	/* range MAX_ROW-1..MAX_ROW-9 */
Xdouble          pallet_length, pallet_height, pallet_x, pallet_y;
X
X/*
X * INVARIANT:
X *     pallet_* == (double) pallet_*I;
X *     pallet_width == 2 * pallet_length
X *     pallet_height >= pallet_length >= ABS( excentricity )
X *       =>  atan2( excentricity, pallet_height ) range -M_PI_4..M_PI_4
X */
Xint             mouse_yI;	/* range 0..STAGE_HEIGHT_IN_PIXELS *//* <HC> */
X
Xint             nb_stages, stage_nb, balls_left, score, score_incr, nbricks, loop_nhits, pallet_modif;
Xdouble          launch_speed;
X
X#define NAME_LENGTH    20
Xchar            stage_name[NAME_LENGTH];
X
X#define MAX_NB_STAGES  100
Xint             stages[MAX_NB_STAGES];
X
Xstruct Brick   *last_busted_brick;	/* NULL == none so far */
Xchar            last_busted_code;
Xint             last_busted_row, last_busted_col;
X
X
X/*** notifier event handlers ***/
X
XNotify_value    move_balls(  );	/* => timeout events */
Xint             move_pallet(  );/* => LOC_MOVE events */
X
X
X/*** itimer ***/
X
Xstruct itimerval timeout;
X
X#define ITIMER_DELAY   5000
X#define ITIMER_NULL ((struct itimerval *) 0 )
X#define start_timer()  \
X	timeout.it_value.tv_usec = ITIMER_DELAY; \
X	(void) notify_set_itimer_func( frame, move_balls, \
X	ITIMER_REAL, &timeout, ITIMER_NULL )
X#define stop_timer()   \
X	(void) notify_set_itimer_func( frame, move_balls, \
X	ITIMER_REAL, ITIMER_NULL, ITIMER_NULL )
X
X
X/*** score and stages files ***/
X
X#define PATH_LENGTH	64
X
Xchar	*login;
Xchar	playground[PATH_LENGTH];
X
X#ifndef STAGEDIR
X#define STAGEDIR	"/usr/games/lib/blockbuster"
X#endif
X
X#define SCOREFILE      "%s/scores"
X#define NB_SCORES      12
X#define USER_SCORES    3
X
X#define NB_STAGESFILE  "%s/nb_stages"
X#define STAGEFILE      "%s/stage%d"
X#define STAGEFILE_LENGTH       PATH_LENGTH
X
X#define SAVEFILE       "%s/save/%s"
X#define SAVEFILE_LENGTH        PATH_LENGTH
END_OF_FILE
if test 6458 -ne `wc -c <'blockbuster.h'`; then
    echo shar: \"'blockbuster.h'\" unpacked with wrong size!
fi
# end of 'blockbuster.h'
fi
if test -f 'blockbuster.man' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'blockbuster.man'\"
else
echo shar: Extracting \"'blockbuster.man'\" \(8137 characters\)
sed "s/^X//" >'blockbuster.man' <<'END_OF_FILE'
X.TH BLOCKBUSTER 6L "26 January 1990"
X.br
X.SH NAME
Xblockbuster \- game
X.SH SYNOPSIS
X.B blockbuster
X.I [play_ground]
X.I [sunview_options]
X.SH DESCRIPTION
XThe play ground is either the anonymous public play ground (no argument),
Xa named public playground or a privately owned directory.
XThe list of available named public play grounds is obtained by giving "-"
Xas the play ground argument.
X.LP
XThe object of the game is to collect as many points as possible by
X.I busting
Xthrough
X.I blocks
Xof various types with a ball that reflects from the blocks and from a pallet
Xcontrolled by mouse movement.
X.LP
XThe ball must be seen as a high-energy particle that penetrates the block
Xbefore being repelled.
XIf it gets repelled into another block it will find its own way out again.
XThis process, which often leads to surprises, is known as
X.I tunnelling.
X.br
X(By design, tunnelling only occurs along a horizontal connection between blocks
Xor along the vertical sides, so never vertically between blocks.)
X.LP
XAs the game progresses, balls are launched faster and faster.
XWhen the speed has reached it maximum, the pallet is gradually,
Xthough cumulatively, shrunk.
XBe aware that the maximum launch speed (see below),
Xand hence the point from which the pallet is shrunk,
Xis only 2/3 of the speed limit, and the effect is much larger than that of
Xhitting a speeder (but of course you may hit them often).
X.LP
XThe pallet is convex.
XHence reflection is a function of both the incoming angle and the excentricity
Xof the point of impact.
XIf the pallet is sufficiently convex (differs from stage to stage), the ball
Xmay even rebound.
X.LP
XThe mouse buttons control the pallet:
XLEFT moves it up one row, MIDDLE moves it all the way down again.
XEach stage is started with the RIGHT mouse button.
X.LP
XA stage can be halted by closing the window.
XBe advised however, that the game will resume immediately upon opening the
Xwindow.
X.LP
XDuring a game, the score, number of balls left and speeds are shown.
XThe speeds are represented by up to 3 thin lines (one for each ball),
Xabove a thick line representing the speed limit.
XThe short vertical bar indicates the launch speed
X(black upon reaching the maximum launch speed, white below that).
X.LP
XA game can be saved in between stages with the R1 button.
XAt this point, as well as at the end of the game, your score is logged.
XThe score board shows scores, number of balls left between parentheses if any
Xand user name.
XFinally, an indication of your current pallet shrinkage is given.
X.SH NOTES
X.LP
XIn order to avoid infinite loops
X(i.e., the ball(s) never reflecting from the pallet),
Xa ball will, upon hitting too many solid bricks,
Xundergo a horizontal shift,
Xproportional to, but opposite to the current horizontal speed.
X.LP
XThe score board imposes a maximum on the number of entries for any given user
Xname.
XIf your current score didn't make it onto the score board,
Xit will be displayed at the bottom.
X.LP
XIf a score entry is detected which obviously must have originated from a saved
Xgame which for some reason "died", a `+' is appended and the entry will hence
Xforward be treated as any completed game.
X.LP
XA common problem players encounter is that of losing track of their mouse.
XBe advised that mouse movement only alters the horizontal pallet position,
Xbut the mouse of course may move vertically as well.
XIf your mouse is not neatly perpendicular to the reflection plate, you may
Xfind yourself outside the window in the middle of some hectic action, causing
Xloss of control (and usually loss of one or several balls).
XFor this reason the horizontal crosshair is shown at the window border,
Xhelping you to keep track of the mouse.
X.SH "CREATION OF PLAY GROUNDS"
XA private play ground can be created in any directory.
XThe stages can be defined from the ascii map codes using any text editor
X(q.v. 'tes').
XThey must be numbered consecutively from 0 with the total number
X(i.e., one more than the highest number) available in the file nb_stages.
XFurthermore a directory 'save' and an empty file 'scores' must be created.
X.LP
XIndividual stages can be tried in the public play ground "try" (q.v. 'try'),
Xprovided you have write access.
X.SH "TYPES OF BLOCKS"
X.sp
X.nf
X.na
XCODE\h'|7m'NAME\h'|24m'REPRESENTATION
X.sp
X\&' ' \h'|7m'clear space\h'|24m'white
X#\h'|7m'solid wall\h'|24m'black
X/,\\\h'|7m'launchpad\h'|24m'black with arrow (like solid wall)
X  The balls enters the stage diagonally at the tip of the arrow.
X.SS BRICKS
X.sp
X0\h'|7m'solid brick\h'|24m'75% gray
X  Scores 1 on each hit.
X.sp
X1-9\h'|7m'hit bricks\h'|24m'white with border (and slanted bars)
X  Requires as many hits as their are bars (plus 1),
X  each scoring equal to how often you have hit it.
X  The stage is over when no such bricks remain.
X.sp
Xa-e,j\h'|7m'bonus bricks\h'|24m'50% gray with value inscribed
X  Requires value/10+1 hits before scoring.
X.SS MAGIC
X.sp
XA\h'|7m'absorber\h'|24m'25% gray (no border)
X^\h'|7m'emitter\h'|24m'black (like solid wall)
X  The ball is absorbed and emitted (whilst being reflected).
X.sp
XC\h'|7m'clipper\h'|24m'pair of scissors between "> <"
X  (On 2nd hit) Clips 10% off the pallet.
X  By design, the remnants litter the screen!
X  [Until the end of the current stage only.]
X.sp
XD\h'|7m'double\h'|24m'"double"
X  (On 2nd hit) Doubles all subsequent hit values.
X  [Until the end of the current stage only.]
X.sp
XE\h'|7m'extra ball\h'|24m'"+O+"
X  (On 2nd hit) Adds an extra ball to the stock.
X.sp
XG\h'|7m'gap\h'|24m'the danger sign (! in a triangle)
X  (On 2nd hit) The ball is lost.
X  [As if it would have left the stage.]
X.sp
XH\h'|7m'halt\h'|24m'maze of small squares
X  Successively takes 10, 20 and 30% of the speed.
X.sp
XI\h'|7m'invisible brick\h'|24m'white (like open space)
X  Turns into a single hit brick when first hit, scoring 1.
X.sp
XL\h'|7m'launch ball\h'|24m'"=O="
X  (On 2nd hit) Launches an extra ball.
X  [Behaves like an 'extra ball' from 3 balls in game.]
X.sp
XM\h'|7m'mine\h'|24m'"kaboom" in dashed border
X  (On 3rd hit) Blows up all adjacent bricks (no score);
X  leaving debris 'refractor's.
X.sp
XP\h'|7m'pause\h'|24m'maze of small squares with launchpad images.
X  (On 8th hit) Takes 30% of the excessive launch speed.
X.sp
XR\h'|7m'refractor\h'|24m'dashed border with crosses
X  Interchanges motion along the axes.
X.sp
XS\h'|7m'speeder\h'|24m'concentric borders
X  Adds speed (up to the speed limit; then pallet shrinkage).
X.sp
XT\h'|7m'triple\h'|24m'"triple"
X  (On 3rd hit) Triples all subsequent hit values.
X  [Until the end of the current stage only.]
X.sp
XU\h'|7m'undo\h'|24m'"undo"
X  Restores the last block busted (with 0 hit count).
X.sp
XW\h'|7m'open window\h'|24m'bracketed set of vertical lines
X%\h'|7m'closed window\h'|24m'black (like solid wall)
X  Alternates between the two states upon each hit.
X.sp
XX\h'|7m'expander\h'|24m'a pallet image between "< >"
X  (On 4th hit) Expands the pallet.
X  [Equivalent to twice the full launch speed shrinkage.]
X  [Effective in the next stage only.]
X.SH DIRECTORIES
X{BBexe} & {BBstg} installation dependent (may be identical)
X.SH FILES
X{BBexe}/blockbuster.*.exe\h'|30m'executables (per architecture)
X{BBexe}/stagemm.exe\h'|30m'[optional] bookkeeping program (q.v. 'smm')
X{BBstg}/stage.skel\h'|30m'skeleton stage (q.v. 'tes')
X{BBstg}/STAGES.\h'|30m'anonymous public play ground
X{BBstg}/STAGES.*\h'|30m'named public play grounds
X\h'|30m'(including a try out environment) (q.v. 'try')
X.SH "USEFUL AUXILIARY SHELLSCRIPTS"
X\&'blockbuster'
X\&'smm'\h'|6m'stage mini-max (small bookkeeping program)
X\&'tes'\h'|6m'tuned textedit
X\&'try'\h'|6m'try out any individual stage in any play ground
X\h'|6m'(using {BBstg}/STAGES.try)
X.fi
X.ad
X.SH BUGS
XSometimes the balls stall.
XIt generally suffices to click or move the mouse to get going again.
X.LP
XWhen two balls hit the same brick simultaneously,
Xone may leave a shadow on the stage.
X.LP
XThe game (re)starts immediately after opening the window.
XIf it had not yet been started officially (using the right mouse button),
Xthe message on top will be garbled.
XPressing the right mouse button will tidy up at any time.
X.LP
XThrough lack of proper real time primitives,
Xit is difficult to tune the speed range over various architectures.
END_OF_FILE
if test 8137 -ne `wc -c <'blockbuster.man'`; then
    echo shar: \"'blockbuster.man'\" unpacked with wrong size!
fi
# end of 'blockbuster.man'
fi
if test -f 'bricks.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bricks.c'\"
else
echo shar: Extracting \"'bricks.c'\" \(7129 characters\)
sed "s/^X//" >'bricks.c' <<'END_OF_FILE'
X/*
X * File:       bricks.c
X * Author:     Eric Van Gestel
X *
X * For:                blockbuster
X */
X
X#include "blockbuster.h"
X
X/*** normal images (rectangular) ***/
X
Xshort           clear_image[] = {
X#include "icons/clear.pr"
X};
X
Xmpr_static( clear_pr, 64, 16, 1, clear_image );
X
Xshort           solid_image[] = {
X#include "icons/solid.pr"
X};
X
Xmpr_static( solid_pr, 64, 16, 1, solid_image );
X
Xshort           launchNE_image[] = {
X#include "icons/launchNE.pr"
X};
X
Xmpr_static( launchNE_pr, 64, 16, 1, launchNE_image );
X
Xshort           launchNW_image[] = {
X#include "icons/launchNW.pr"
X};
X
Xmpr_static( launchNW_pr, 64, 16, 1, launchNW_image );
X
X
Xshort           brick_0_image[] = {
X#include "icons/brick_0.pr"
X};
X
Xmpr_static( brick_0_pr, 64, 16, 1, brick_0_image );
X
Xshort           brick_1_image[] = {
X#include "icons/brick_1.pr"
X};
X
Xmpr_static( brick_1_pr, 64, 16, 1, brick_1_image );
X
Xshort           brick_2_image[] = {
X#include "icons/brick_2.pr"
X};
X
Xmpr_static( brick_2_pr, 64, 16, 1, brick_2_image );
X
Xshort           brick_3_image[] = {
X#include "icons/brick_3.pr"
X};
X
Xmpr_static( brick_3_pr, 64, 16, 1, brick_3_image );
X
Xshort           brick_4_image[] = {
X#include "icons/brick_4.pr"
X};
X
Xmpr_static( brick_4_pr, 64, 16, 1, brick_4_image );
X
Xshort           brick_5_image[] = {
X#include "icons/brick_5.pr"
X};
X
Xmpr_static( brick_5_pr, 64, 16, 1, brick_5_image );
X
Xshort           brick_6_image[] = {
X#include "icons/brick_6.pr"
X};
X
Xmpr_static( brick_6_pr, 64, 16, 1, brick_6_image );
X
Xshort           brick_7_image[] = {
X#include "icons/brick_7.pr"
X};
X
Xmpr_static( brick_7_pr, 64, 16, 1, brick_7_image );
X
Xshort           brick_8_image[] = {
X#include "icons/brick_8.pr"
X};
X
Xmpr_static( brick_8_pr, 64, 16, 1, brick_8_image );
X
Xshort           brick_9_image[] = {
X#include "icons/brick_9.pr"
X};
X
Xmpr_static( brick_9_pr, 64, 16, 1, brick_9_image );
X
X
Xshort           brick_a_image[] = {
X#include "icons/brick_a.pr"
X};
X
Xmpr_static( brick_a_pr, 64, 16, 1, brick_a_image );
X
Xshort           brick_b_image[] = {
X#include "icons/brick_b.pr"
X};
X
Xmpr_static( brick_b_pr, 64, 16, 1, brick_b_image );
X
Xshort           brick_c_image[] = {
X#include "icons/brick_c.pr"
X};
X
Xmpr_static( brick_c_pr, 64, 16, 1, brick_c_image );
X
Xshort           brick_d_image[] = {
X#include "icons/brick_d.pr"
X};
X
Xmpr_static( brick_d_pr, 64, 16, 1, brick_d_image );
X
Xshort           brick_e_image[] = {
X#include "icons/brick_e.pr"
X};
X
Xmpr_static( brick_e_pr, 64, 16, 1, brick_e_image );
X
Xshort           brick_j_image[] = {
X#include "icons/brick_j.pr"
X};
X
Xmpr_static( brick_j_pr, 64, 16, 1, brick_j_image );
X
X
Xshort           brick_A_image[] = {
X#include "icons/brick_A.pr"
X};
X
Xmpr_static( brick_A_pr, 64, 16, 1, brick_A_image );
X
Xshort           brick_C_image[] = {
X#include "icons/brick_C.pr"
X};
X
Xmpr_static( brick_C_pr, 64, 16, 1, brick_C_image );
X
Xshort           brick_D_image[] = {
X#include "icons/brick_D.pr"
X};
X
Xmpr_static( brick_D_pr, 64, 16, 1, brick_D_image );
X
Xshort           brick_E_image[] = {
X#include "icons/brick_E.pr"
X};
X
Xmpr_static( brick_E_pr, 64, 16, 1, brick_E_image );
X
Xshort           brick_G_image[] = {
X#include "icons/brick_G.pr"
X};
X
Xmpr_static( brick_G_pr, 64, 16, 1, brick_G_image );
X
Xshort           brick_H_image[] = {
X#include "icons/brick_H.pr"
X};
X
Xmpr_static( brick_H_pr, 64, 16, 1, brick_H_image );
X
X/* short brick_I_image[] == clear_image */
X
Xshort           brick_L_image[] = {
X#include "icons/brick_L.pr"
X};
X
Xmpr_static( brick_L_pr, 64, 16, 1, brick_L_image );
X
Xshort           brick_M_image[] = {
X#include "icons/brick_M.pr"
X};
X
Xmpr_static( brick_M_pr, 64, 16, 1, brick_M_image );
X
Xshort           brick_P_image[] = {
X#include "icons/brick_P.pr"
X};
X
Xmpr_static( brick_P_pr, 64, 16, 1, brick_P_image );
X
Xshort           brick_R_image[] = {
X#include "icons/brick_R.pr"
X};
X
Xmpr_static( brick_R_pr, 64, 16, 1, brick_R_image );
X
Xshort           brick_S_image[] = {
X#include "icons/brick_S.pr"
X};
X
Xmpr_static( brick_S_pr, 64, 16, 1, brick_S_image );
X
Xshort           brick_T_image[] = {
X#include "icons/brick_T.pr"
X};
X
Xmpr_static( brick_T_pr, 64, 16, 1, brick_T_image );
X
Xshort           brick_U_image[] = {
X#include "icons/brick_U.pr"
X};
X
Xmpr_static( brick_U_pr, 64, 16, 1, brick_U_image );
X
Xshort           brick_W_image[] = {
X#include "icons/brick_W.pr"
X};
X
Xmpr_static( brick_W_pr, 64, 16, 1, brick_W_image );
X
Xshort           brick_X_image[] = {
X#include "icons/brick_X.pr"
X};
X
Xmpr_static( brick_X_pr, 64, 16, 1, brick_X_image );
X
X
X/*** side images (square) ***/
X
Xshort           clear0_image[] = {
X#include "icons/clear0.pr"
X};
X
Xmpr_static( clear0_pr, 16, 16, 1, clear0_image );
X
Xshort           solid0_image[] = {
X#include "icons/solid0.pr"
X};
X
Xmpr_static( solid0_pr, 16, 16, 1, solid0_image );
X
Xshort           launchNE0_image[] = {
X#include "icons/launchNE0.pr"
X};
X
Xmpr_static( launchNE0_pr, 16, 16, 1, launchNE0_image );
X
Xshort           launchNW0_image[] = {
X#include "icons/launchNW0.pr"
X};
X
Xmpr_static( launchNW0_pr, 16, 16, 1, launchNW0_image );
X
X
X/*** address functions ***/
X
XPixrect        *
Xbrick_addr( row, col )
X	int             row, col;	/* col > 0 && col < MAX_COL */
X{
X	int             tmp = stage[row][col].nhits;
X
X	switch ( stage[row][col].code ) {
X	case ' ':
X		return ( &clear_pr );
X	case '#':
X		return ( &solid_pr );
X	case '/':
X		return ( &launchNE_pr );
X	case '\\':
X		return ( &launchNW_pr );
X
X	case '9':
X		if ( !tmp-- )
X			return ( &brick_9_pr );
X	case '8':
X		if ( !tmp-- )
X			return ( &brick_8_pr );
X	case '7':
X		if ( !tmp-- )
X			return ( &brick_7_pr );
X	case '6':
X		if ( !tmp-- )
X			return ( &brick_6_pr );
X	case '5':
X		if ( !tmp-- )
X			return ( &brick_5_pr );
X	case '4':
X		if ( !tmp-- )
X			return ( &brick_4_pr );
X	case '3':
X		if ( !tmp-- )
X			return ( &brick_3_pr );
X	case '2':
X		if ( !tmp-- )
X			return ( &brick_2_pr );
X	case '1':
X		return ( &brick_1_pr );
X
X	case '0':
X		return ( &brick_0_pr );
X
X	case 'a':
X		return ( &brick_a_pr );
X	case 'b':
X		return ( &brick_b_pr );
X	case 'c':
X		return ( &brick_c_pr );
X	case 'd':
X		return ( &brick_d_pr );
X	case 'e':
X		return ( &brick_e_pr );
X	case 'j':
X		return ( &brick_j_pr );
X
X	case 'A':
X		return ( &brick_A_pr );
X	case '^':
X		return ( &solid_pr );
X	case 'C':
X		return ( &brick_C_pr );
X	case 'D':
X		return ( &brick_D_pr );
X	case 'E':
X		return ( &brick_E_pr );
X	case 'G':
X		return ( &brick_G_pr );
X	case 'H':
X		return ( &brick_H_pr );
X	case 'I':
X		return ( &clear_pr );
X	case 'L':
X		return ( &brick_L_pr );
X	case 'M':
X		return ( &brick_M_pr );
X	case 'P':
X		return ( &brick_P_pr );
X	case 'R':
X		return ( &brick_R_pr );
X	case 'S':
X		return ( &brick_S_pr );
X	case 'T':
X		return ( &brick_T_pr );
X	case 'U':
X		return ( &brick_U_pr );
X	case 'W':
X		return ( &brick_W_pr );
X	case '%':
X		return ( &solid_pr );
X	case 'X':
X		return ( &brick_X_pr );
X
X	default:
X		perror( "Illegal map code" );
X		exit( 1 );
X	}
X}
X
XPixrect        *
Xbrick_addr0( row, col )
X	int             row, col;	/* col == 0 || col == MAX_COL */
X{
X	switch ( stage[row][col].code ) {
X	case ' ':
X		return ( &clear0_pr );
X	case '#':
X		return ( &solid0_pr );
X	case '/':
X		return ( &launchNE0_pr );
X	case '\\':
X		return ( &launchNW0_pr );
X
X	default:
X		perror( "Illegal map code" );
X		exit( 1 );
X	};
X}
END_OF_FILE
if test 7129 -ne `wc -c <'bricks.c'`; then
    echo shar: \"'bricks.c'\" unpacked with wrong size!
fi
# end of 'bricks.c'
fi
if test ! -d 'icons' ; then
    echo shar: Creating directory \"'icons'\"
    mkdir 'icons'
fi
if test -f 'stage.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stage.c'\"
else
echo shar: Extracting \"'stage.c'\" \(4054 characters\)
sed "s/^X//" >'stage.c' <<'END_OF_FILE'
X/*
X * File:       stage.c
X * Author:     Eric Van Gestel
X *
X * For:                blockbuster
X */
X
X#include "blockbuster.h"
X#include "bricks.h"
X
Xvoid
Xget_stage(  )
X{
X	FILE           *fd;
X	char            buf[MAX_COL + 3], stg[STAGEFILE_LENGTH];
X	register int    row, col, tmp;
X	register char   code;
X
X	nbricks = 0;
X	score_incr = 1;
X	loop_nhits = 0;
X	last_busted_brick = NULL;
X
X	/* open next stage file */
X	if ( !( fd = fopen( sprintf( stg, STAGEFILE, playground, stage_nb ),
X			    "r" ) ) ) {
X		perror( "Can't open stage" );
X		exit( 1 );
X	}
X	/* clear msg */
X	for ( tmp = 0; tmp < MSG_HEIGHT; tmp++ )
X		pw_vector( msg_win, 0, tmp, STAGE_WIDTH_IN_PIXELS - 1, tmp,
X			   PIX_CLR, 1 );
X
X	/* read stage name */
X	fscanf( fd, "%s\n", stage_name );
X	for ( tmp = 0; stage_name[tmp]; tmp++ )
X		if ( stage_name[tmp] == '_' )
X			stage_name[tmp] = ' ';
X	for (  /* tmp = tmp */ ; tmp < NAME_LENGTH - 1; tmp++ )
X		stage_name[tmp] = ' ';
X	stage_name[NAME_LENGTH - 1] = '\0';
X	msg1( OFFSET_SPEED, stage_name );
X
X	/* read pallet dimensions */
X	fscanf( fd, "%d%d\n", &pallet_lengthI, &pallet_heightI );
X	if ( pallet_lengthI < SHORT_PALLET_LENGTH ||
X	     pallet_lengthI > LONG_PALLET_LENGTH ||
X	     pallet_heightI < pallet_lengthI ||
X	     pallet_heightI > MAX_PALLET_HEIGHT ) {
X		perror( "Inconsistent pallet dimensions" );
X		exit( 1 );
X	}
X	/* modify for difficulty level */
X	pallet_lengthI -= ( pallet_modif * pallet_lengthI ) / PALLET_DENOMINATOR;
X	if ( pallet_lengthI < MIN_PALLET_LENGTH )
X		pallet_lengthI = MIN_PALLET_LENGTH;
X	if ( pallet_lengthI > MAX_PALLET_LENGTH )
X		pallet_lengthI = MAX_PALLET_LENGTH;
X	if ( pallet_heightI < pallet_lengthI )
X		pallet_heightI = pallet_lengthI;
X	pallet_length = ( double ) pallet_lengthI;
X	pallet_height = ( double ) pallet_heightI;
X
X	/* read stage map */
X	for ( row = 0; row <= MAX_ROW; row++ ) {
X		if ( !fgets( buf, MAX_COL + 3, fd ) ) {
X			perror( "Can't read stage" );
X			exit( 1 );
X		}
X		for ( col = 0; col <= MAX_COL; col++ ) {
X			code = buf[col];
X			if ( IS_HIT_BRICK( code ) )
X				nbricks++;
X			switch ( code ) {
X			case '/':
X				launch_quadrant = NE;
X				launch_row = row;
X				launch_col = col;
X				launch_x = ( double ) ( COL_X( col + 1 ) );
X				launch_y = ( double ) ( ROW_Y( row ) );
X				break;
X			case '\\':
X				launch_quadrant = NW;
X				launch_row = row;
X				launch_col = col;
X				launch_x = ( double ) ( COL_X( col ) );
X				launch_y = ( double ) ( ROW_Y( row ) );
X				break;
X			case '^':
X				emit_row = row;
X				emit_col = col;
X			}
X			stage[row][col].code = code;
X			stage[row][col].nhits = 0;
X		}
X	}
X	fclose( fd );
X
X	/* draw new stage */
X	for ( row = 0; row <= MAX_ROW; row++ ) {
X		draw_brick0( row, 0 );
X		for ( col = 1; col < MAX_COL; col++ )
X			draw_brick( row, col );
X		draw_brick0( row, MAX_COL );
X	}
X
X	/* reset pallet location */
X	pallet_y = ( double ) ( pallet_yI = PALLET_MAX_Y + 4 );
X	pallet_row = MAX_ROW - 1;
X	draw_pallet(  );
X
X	/* ready ? */
X	msg0( OFFSET_BALLS,
X	      "Press right mouse button when ready; R1 to save.%7c", ' ' );
X}
X
Xvoid
Xnew_stage(  )
X{
X	FILE           *fd;
X	register int    stage_index, stage_nb_tmp;
X	char		buf[STAGEFILE_LENGTH], buf2[2*STAGEFILE_LENGTH];
X
X	/* go faster or make the pallet smaller */
X	if ( launch_speed < MAX_SPEED )
X		launch_speed += SPEED_INCR;
X	else
X		pallet_modif += PALLET_INCR;
X
X	/* determine stage number */
X	if ( !nb_stages ) {
X		/* read number of available stages */
X		if ( !( fd = fopen( sprintf( buf, NB_STAGESFILE, playground ),
X				    "r" ) ) ) {
X			perror( sprintf( buf2, "Can't open number of stages file <%s>",
X					 buf ) );
X			exit( 1 );
X		}
X		fscanf( fd, "%d", &nb_stages );
X		fclose( fd );
X		/* clear stages memory */
X		for ( stage_nb_tmp = 0; stage_nb_tmp < MAX_NB_STAGES; )
X			stages[stage_nb_tmp++] = FALSE;
X	}
X	/* search for stage index'th available stage number */
X	stage_index = ( int ) ( random(  ) ) % nb_stages--;
X	if ( stage_index < 0 )
X		stage_index = -stage_index;
X	for ( stage_nb = 0; stages[stage_nb]; )
X		stage_nb++;
X	while ( stage_index-- ) {
X		while ( stages[++stage_nb] );
X	}
X	stages[stage_nb] = TRUE;
X
X	get_stage(  );
X}
END_OF_FILE
if test 4054 -ne `wc -c <'stage.c'`; then
    echo shar: \"'stage.c'\" unpacked with wrong size!
fi
# end of 'stage.c'
fi
if test -f 'stage.skel' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stage.skel'\"
else
echo shar: Extracting \"'stage.skel'\" \(623 characters\)
sed "s/^X//" >'stage.skel' <<'END_OF_FILE'
XNAME_blancs_replaced_by_underscores
XPALLET_LENGTH PALLET_HEIGHT
X############
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
X#          #
END_OF_FILE
if test 623 -ne `wc -c <'stage.skel'`; then
    echo shar: \"'stage.skel'\" unpacked with wrong size!
fi
# end of 'stage.skel'
fi
echo shar: End of archive 1 \(of 3\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0