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