home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Gry / Breakout / MAIN1.C < prev    next >
C/C++ Source or Header  |  1998-01-24  |  56KB  |  1,698 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include <conio.h>
  6. #include "allegro.h"
  7. #include "breakout.h"
  8.  
  9. BITMAP *page1;         // drawing screen
  10. BITMAP *bg1;           // display this between levels
  11. BITMAP *startup;       // main screen to show at start & between games
  12. BITMAP *bl_block;      // blue block
  13. BITMAP *grn_block;     // green block
  14. BITMAP *prp_block;     // purple block
  15. BITMAP *red_block;     // red block
  16. BITMAP *laser_block;   // laser block
  17. BITMAP *explode_block; // explosion block
  18. BITMAP *catch_block;   // catch block
  19. BITMAP *hit2_block;    // hit this block twice to destroy
  20. BITMAP *hit3_block;    // hit this block three times to destroy
  21. BITMAP *slow_block;    // make ball go slow block
  22. BITMAP *fast_block;    // make ball go fast block
  23. BITMAP *pwr_block;     // power block (enables ball to explode blocks)
  24. BITMAP *lrg_block;     // enlarge bat block
  25. BITMAP *sml_block;     // shrink bat block
  26. BITMAP *invinc_block;  // invincible block
  27. BITMAP *plus_block;    // extra life block
  28. BITMAP *next_block;    // next level block
  29. BITMAP *thru_block;    // ball through blocks (doesn't bounce if this block collected)
  30. BITMAP *explosion_frames; //explosion frames (10)
  31. BITMAP *ball;          // ball bitmap
  32. BITMAP *pwr_ball;      // power ball bitmap (explodes blocks on impact)
  33. BITMAP *bat1;          // bat 1 bitmap (normal size)
  34. BITMAP *bat2;          // bat 2 bitmap (large size)
  35. BITMAP *bat3;          // bat 3 bitmap (small size)
  36. BITMAP *laser_bat;     // laser bat
  37. BITMAP *catch_bat;     // catch bat
  38. BITMAP *finish_screen;  // exit screen
  39. BITMAP *gameover_screen; // gameover screen
  40. BITMAP *hiscore_screen;  // hi score screen
  41. BITMAP *help_screen;    // help screen
  42.  
  43.  
  44. PALLETE pallete1;       // main game pallete
  45. PALLETE pallete2;       // pallete used for between level screen
  46. PALLETE pal_startup;    // main screen pallete (used at start of game ie main.bmp)
  47. PALLETE pal_finish;     // exit screen pallete
  48. PALLETE pal_tmp;
  49. PALLETE pal_gamover;    // gameover screen pallete
  50. PALLETE pal_hiscore;    // hi score screen pallete
  51.  
  52. FILE *data;             // set up file pointer for block data to load from disk
  53. DATAFILE *fontfile;     // file to hold fonts
  54.  
  55. SAMPLE *hit_block;      // sound of ball hitting block
  56. SAMPLE *explode;        // explosion sound
  57. SAMPLE *laser;          // laser sound
  58. SAMPLE *powerup;        // power up sound
  59. SAMPLE *bounce;         // ball bounce off wall sound
  60. SAMPLE *loose1;         // loose a life sound
  61. SAMPLE *newlevel;       // new level music
  62. SAMPLE *newlev2;        // new level music
  63. SAMPLE *catch;          // catch ball sample (every time ball is catched)
  64. SAMPLE *new_life;       // play when a new life is obtained
  65. SAMPLE *bat_sml;        // small bat sound effect
  66. SAMPLE *bat_lrg;        // large bat sound effect
  67. SAMPLE *half_amin;      // half a minute music sample
  68. SAMPLE *finish;         // exit screen tune
  69. SAMPLE *hiscore;        // hiscore music
  70. SAMPLE *ball_fast;      // ball sppedup sound
  71. SAMPLE *ball_slow;      // ball slowdown sound
  72.  
  73. RGB col1={63,0,0};      // color for invincible box
  74. RGB col2={63,63,0};     // used for pallete shifting
  75.  
  76.  
  77. // global variable used for holding temporary characters
  78. char ch_tmp[80];          // temp character string
  79. int level;                // game level
  80. int ptr;                  // general pointer
  81. int lives;                // number of lives left
  82. int score;                // players score
  83. int new_level;            // set to 1 when all bricks have been destroyed.
  84. int ball_out;             // ball out of play flag (0= in play, 1= out of play)
  85. int bat_type;             // 1=normal bat, 2=large bat, 3=small bat
  86.              //
  87. int laser_down;           //|if set to '1' shifts laser block down screen
  88. int laser_enable;         //|if set to '1' turns bat into laser and enables firing
  89. int las_x1,las_y1;        //|laser beam x,y position
  90. int las_x2,las_y2;        //|laser beam x,y position
  91. int las_firing1;          //|set to '1' if laser beam is in process of firing
  92. int laser_ptr;           //|points to the laser block number just hit
  93. int las_firing2;          //|set to '1' if laser beam is in process of firing
  94.  
  95.                           //
  96. int catch_down;           //|if set to '1' shifts catch block down screen
  97. int catch_enable;         //|if set to '1' turns bat into catch bat
  98. int catch_ptr;            //|points to the catch block number just hit
  99.                           //
  100. int power_down;           //|if set to '1 shifts power block down screen
  101. int power_enable;         //|if set to '1' turns ball into power ball
  102. int power_ptr;            //|points to the power block number just hit
  103.  
  104. int plus_down;            //|if set to '1 shifts plus block down screen
  105. int plus_enable;          //|if set to '1' adds a life
  106. int plus_ptr;             //|points to the plus block number just hit
  107.  
  108. int next_down;            //|if set to '1 shifts next block down screen
  109. int next_enable;          //|if set to '1' skips the level
  110. int next_ptr;             //|points to the next block number just hit
  111.  
  112. int thru_down;            //|if set to '1 shifts thru block down screen
  113. int thru_enable;          //|if set to '1' ball will go through blocks (ie doesnt bounce)
  114. int thru_ptr;             //|points to the thru block number just hit
  115.  
  116.  
  117. int bounces;              // no of bounces ball has made (used to determine velocity)
  118. int vel_x;                // ball velocity
  119. int vel_y;
  120. int bounce_angle;         // angle of bounce off ball (0=normal, 1=high)
  121.  
  122. int frame_tstart;         // stores time for frames per second routine
  123. int frame_ctr;            // counts number of frames
  124. int frame_fps;
  125. int frame_delay;          // used by fps routine to limit fps
  126.  
  127. int explde[10];           // array to hold tiles that are to be exploded
  128. int explode_frame[10];    // up to 10 explosions at same time.
  129.                           // holds the current frame to be displayed
  130.  
  131. int frame_skip;           // used to skip frames
  132. int pal_cycles;           // used as counter for pallete cycling (see drawing_screen()
  133.  
  134. int bounce_time;          //monitors time between ball hitting bat
  135.  
  136. int input_device;         //The mouse is used for all menus, however
  137.                           //the game game be played using the
  138.                           //mouse, keyboard or joystick.
  139.                           // 1=mouse, 2=keyboard, 3=joystick
  140.                           // default is mouse
  141.  
  142. // define structure for holding block positions for each level
  143. // bx,by  : x,y position of block
  144. // bw,bh  : width & height of block
  145. // b_show : 0 = not displayed, 1=displayed
  146. // b_type : 1= blue block, 2= green, 3=purple, 4=red, 5=laser
  147. //          6= explode 7=catch, 8=hit2 , 9=hit3 , A=slow
  148. //          B=fast, C=power ball, D=small bat, E=large bat
  149. //          F=extra life, G=next level, H=ball thru blocks
  150. // hits   : no of hits required to destroy block
  151. struct {
  152.         int bx,by,bw,bh,b_show,b_type,hits;
  153. }blocks[450];
  154.  
  155. // define structure for holding ball position
  156. // bx,by  : x,y position of ball
  157. // dx,dy  : direction of ball.  eg. dx=-1 (left) dx=+1 (right)
  158. struct {
  159.         int bx,by,dx,dy;
  160. }balls[3];
  161.  
  162. // define structure for holding bat position data
  163. // mx.my,mw : x,y,width of bat
  164. // bb       : last button pressed (1= left, 2=right)
  165. struct {
  166.        int bx,by,bb,bw;
  167. }bat[4];
  168.  
  169.  
  170. // define structure for holding the hi-score table
  171. struct {
  172.        char names[22];
  173.        int scores;
  174. } hiscores[10];
  175.  
  176.  
  177.  
  178.  
  179. void load_bitmaps()
  180. {
  181.  // LOAD BITMAPS INTO MEMORY
  182.  // load background screen and set pallete
  183.  
  184.  sprintf(ch_tmp,"backgnd.bmp");         // place string into ch_tmp array
  185.  page1=load_bitmap(ch_tmp,pallete1);    // load background into drawing bitmap
  186.  set_pallete(pallete1);                 // set pallete
  187.  bg1=load_bitmap("newlevel.bmp",pallete2);  // new level background
  188.  startup=load_bitmap("main.bmp",pal_startup); // load stratup screen
  189.  //load blocks
  190.  bl_block=load_bitmap("bk_blue.bmp",pal_tmp);
  191.  grn_block=load_bitmap("bk_grn.bmp",pal_tmp);
  192.  prp_block=load_bitmap("bk_prpl.bmp",pal_tmp);
  193.  red_block=load_bitmap("bk_red.bmp",pal_tmp);
  194.  laser_block=load_bitmap("bk_lsr.bmp",pal_tmp);
  195.  explode_block=load_bitmap("bk_exp.bmp",pal_tmp);
  196.  catch_block=load_bitmap("bk_cth.bmp",pal_tmp);
  197.  hit2_block=load_bitmap("bk_2ht.bmp",pal_tmp);
  198.  hit3_block=load_bitmap("bk_3ht.bmp",pal_tmp);
  199.  slow_block=load_bitmap("bk_slw.bmp",pal_tmp);
  200.  fast_block=load_bitmap("bk_fst.bmp",pal_tmp);
  201.  pwr_block=load_bitmap("bk_pwr.bmp",pal_tmp);
  202.  sml_block=load_bitmap("bk_sml.bmp",pal_tmp);
  203.  lrg_block=load_bitmap("bk_lrg.bmp",pal_tmp);
  204.  invinc_block=load_bitmap("bk_inv.bmp",pal_tmp);
  205.  plus_block=load_bitmap("bk_plus.bmp",pal_tmp);
  206.  next_block=load_bitmap("bk_next.bmp",pal_tmp);
  207.  thru_block=load_bitmap("bk_thru.bmp",pal_tmp);
  208.  finish_screen=load_bitmap("finish.bmp",pal_finish);
  209.  gameover_screen=load_bitmap("gameover.bmp",pal_gamover);
  210.  hiscore_screen=load_bitmap("hiscores.bmp",pal_hiscore);
  211.  help_screen=load_bitmap("help.bmp",pal_tmp);
  212.  
  213.  
  214.  // load balls
  215.  ball=load_bitmap("ball.bmp",pal_tmp);
  216.  pwr_ball=load_bitmap("ball1.bmp",pal_tmp);
  217.  // load bats
  218.  bat1=load_bitmap("bat1.bmp",pal_tmp);
  219.  bat2=load_bitmap("bat2.bmp",pal_tmp);
  220.  bat3=load_bitmap("bat3.bmp",pal_tmp);
  221.  laser_bat=load_bitmap("bat_lsr.bmp",pal_tmp);
  222.  catch_bat=load_bitmap("bat_cth.bmp",pal_tmp);
  223.  // load explosion frames
  224.  explosion_frames=load_bitmap("explode.bmp",pal_tmp);
  225.  // load font file
  226.  fontfile=load_datafile("breakout.dat");
  227.  
  228. }
  229.  
  230.  
  231. void load_samples()
  232. {
  233.  // Load sound samples
  234.  hit_block=load_sample("block.wav");
  235.  explode=load_sample("explode.wav");
  236.  laser=load_sample("laser.wav");
  237.  powerup=load_sample("powerup.wav");
  238.  bounce=load_sample("bounce.wav");
  239.  loose1=load_sample("loose1.wav");
  240.  newlevel=load_sample("newlev1.wav");
  241.  newlev2=load_sample("newlev2.wav");
  242.  catch=load_sample("catch.wav");
  243.  new_life=load_sample("newlife.wav");
  244.  bat_lrg=load_sample("bat_lrg.wav");
  245.  bat_sml=load_sample("bat_sml.wav");
  246.  half_amin=load_sample("half.wav");
  247.  finish=load_sample("finish.wav");
  248.  hiscore=load_sample("hiscore.wav");
  249.  ball_fast=load_sample("fast.wav");
  250.  ball_slow=load_sample("slow.wav");
  251. }
  252.  
  253.  
  254.  
  255.  
  256. // load blocks of data according to level
  257. // data is loaded as ascii values into ch
  258. // ch=48  block 0  dont display        (0)
  259. // ch=49  block 1  blue                (1)
  260. // ch=50  block 2  green               (2)
  261. // ch=51  block 3  purple              (3)
  262. // ch=52  block 4  red                 (4)
  263. // ch=53  block 5  laser               (5)
  264. // ch=54  block 6  explosion           (6)
  265. // ch=55  block 7  catch               (7)
  266. // ch=56  block 8  hit 2               (8)
  267. // ch=57  block 9  hit 3               (9)
  268. // ch=65  block 10 slow ball           (A)
  269. // ch=66  block 11 fast ball           (B)
  270. // ch=67  block 12 power block         (C)
  271. // ch=68  block 13 shrink bat block    (D)
  272. // ch=69  block 14 enlarge bat block   (E)
  273. // ch=70  block 15 invincible block    (F)
  274. // ch=71  block 16 Extra life          (G)
  275. // ch=72  block 17 Skip to next level  (H)
  276. // ch=73  block 18 ball through blocks (I)
  277. void load_data(level)
  278. {
  279.  int ch,ptr,x,y;
  280.  x=80;
  281.  y=60;
  282.    // open block position data file (different for each level)
  283.    sprintf(ch_tmp,"level%d",level);
  284.    data=fopen(ch_tmp,"r");
  285.    for (ptr=0;ptr<303;ptr++){
  286.        ch=getc(data);
  287.        if (ch!=10){
  288.          blocks[ptr].bx=x;
  289.          blocks[ptr].by=y;
  290.          blocks[ptr].bw=31;
  291.          blocks[ptr].bh=12;
  292.        }
  293.        if (ch==48){
  294.          blocks[ptr].b_show=0;
  295.          blocks[ptr].b_type=0;
  296.          blocks[ptr].hits=0;
  297.        }
  298.        if (ch==49){
  299.          blocks[ptr].b_show=1;
  300.          blocks[ptr].b_type=1;
  301.          blocks[ptr].hits=1;
  302.        }
  303.        if (ch==50){
  304.          blocks[ptr].b_show=1;
  305.          blocks[ptr].b_type=2;
  306.          blocks[ptr].hits=1;
  307.        }
  308.        if (ch==51){
  309.          blocks[ptr].b_show=1;
  310.          blocks[ptr].b_type=3;
  311.          blocks[ptr].hits=1;
  312.        }
  313.        if (ch==52){
  314.          blocks[ptr].b_show=1;
  315.          blocks[ptr].b_type=4;
  316.          blocks[ptr].hits=1;
  317.        }
  318.        if (ch==53){
  319.          blocks[ptr].b_show=1;
  320.          blocks[ptr].b_type=5;
  321.          blocks[ptr].hits=1;
  322.        }
  323.        if (ch==54){
  324.          blocks[ptr].b_show=1;
  325.          blocks[ptr].b_type=6;
  326.          blocks[ptr].hits=1;
  327.        }
  328.        if (ch==55){
  329.          blocks[ptr].b_show=1;
  330.          blocks[ptr].b_type=7;
  331.          blocks[ptr].hits=1;
  332.        }
  333.        if (ch==56){
  334.          blocks[ptr].b_show=1;
  335.          blocks[ptr].b_type=8;
  336.          blocks[ptr].hits=2;
  337.        }
  338.        if (ch==57){
  339.          blocks[ptr].b_show=1;
  340.          blocks[ptr].b_type=9;
  341.          blocks[ptr].hits=3;
  342.        }
  343.        if (ch==65){
  344.          blocks[ptr].b_show=1;
  345.          blocks[ptr].b_type=10;
  346.          blocks[ptr].hits=1;
  347.        }
  348.        if (ch==66){
  349.          blocks[ptr].b_show=1;
  350.          blocks[ptr].b_type=11;
  351.          blocks[ptr].hits=1;
  352.        }
  353.        if (ch==67){
  354.          blocks[ptr].b_show=1;
  355.          blocks[ptr].b_type=12;
  356.          blocks[ptr].hits=1;
  357.        }
  358.        if (ch==68){
  359.          blocks[ptr].b_show=1;
  360.          blocks[ptr].b_type=13;
  361.          blocks[ptr].hits=1;
  362.        }
  363.        if (ch==69){
  364.          blocks[ptr].b_show=1;
  365.          blocks[ptr].b_type=14;
  366.          blocks[ptr].hits=1;
  367.        }
  368.        if (ch==70){
  369.          // b_show=2 means this block type is invincible
  370.          blocks[ptr].b_show=2;
  371.          blocks[ptr].b_type=15;
  372.          blocks[ptr].hits=1;
  373.        }
  374.        if (ch==71){
  375.          blocks[ptr].b_show=1;
  376.          blocks[ptr].b_type=16;
  377.          blocks[ptr].hits=1;
  378.        }
  379.        if (ch==72){
  380.          blocks[ptr].b_show=1;
  381.          blocks[ptr].b_type=17;
  382.          blocks[ptr].hits=1;
  383.        }
  384.        if (ch==73){
  385.          blocks[ptr].b_show=1;
  386.          blocks[ptr].b_type=18;
  387.          blocks[ptr].hits=1;
  388.        }
  389.        if (ch!=10){
  390.          x+=32;
  391.          if (x==560){
  392.            x=80;
  393.            y+=14;
  394.          }
  395.        }
  396.    }
  397.   fclose (data);
  398. }
  399.  
  400.  
  401.  
  402. // draw to drawing screen
  403. void drawing_screen()
  404. {
  405. int x,y,show,type,ptr;
  406.   // update drawing screen with blocks
  407.     for (ptr=0; ptr<303; ptr++) {
  408.        x=blocks[ptr].bx;
  409.        y=blocks[ptr].by;
  410.        show=blocks[ptr].b_show;
  411.        type=blocks[ptr].b_type;
  412.        if (show!=0){
  413.          if (type==1) blit(bl_block,page1,0,0,x,y,31,13); // blue
  414.          if (type==2) blit(grn_block,page1,0,0,x,y,31,13); // green
  415.          if (type==3) blit(prp_block,page1,0,0,x,y,31,13); // purple
  416.          if (type==4) blit(red_block,page1,0,0,x,y,31,13); // red
  417.          if (type==5) blit(laser_block,page1,0,0,x,y,31,13); // laser
  418.          if (type==6) blit(explode_block,page1,0,0,x,y,31,13); // explosion
  419.          if (type==7) blit(catch_block,page1,0,0,x,y,31,13); // catch
  420.          if (type==8) blit(hit2_block,page1,0,0,x,y,31,13); // 2 hit block
  421.          if (type==9) blit(hit3_block,page1,0,0,x,y,31,13); // 3 hit block
  422.          if (type==10) blit(slow_block,page1,0,0,x,y,31,13); // ball slow block
  423.          if (type==11) blit(fast_block,page1,0,0,x,y,31,13); // ball fast block
  424.          if (type==12) blit(pwr_block,page1,0,0,x,y,31,13); // power block
  425.          if (type==13) blit(sml_block,page1,0,0,x,y,31,13); // shrink bat block
  426.          if (type==14) blit(lrg_block,page1,0,0,x,y,31,13); // enlarge bat block
  427.          if (type==15) blit(invinc_block,page1,0,0,x,y,31,13); // invincible block
  428.          if (type==16) blit(plus_block,page1,0,0,x,y,31,13); // extra life block
  429.          if (type==17) blit(next_block,page1,0,0,x,y,31,13); // skip to next level block
  430.          if (type==18) blit(thru_block,page1,0,0,x,y,31,13); // ball thru blocks
  431.        }
  432.     }
  433.   // Shift the pallete for the invincible blocks
  434.   // swap colors 14 & 15
  435.   if (pal_cycles==20) {vsync();set_color(14,&col1);set_color(15,&col2);}
  436.   if (pal_cycles==40) {vsync();set_color(14,&col2);set_color(15,&col1);pal_cycles=0;}
  437.   pal_cycles++;
  438. }
  439.  
  440.  
  441. // copy drawing screen to output screen
  442. void copy_drawing()
  443. {
  444.   blit(page1,screen,0,0,0,0,640,480);
  445. }
  446.  
  447.  
  448. // copy background screen to drawing screen
  449. void copy_backgrnd()
  450. {
  451.   // replaced blit command with this
  452.   rectfill(page1,78,52,562,479,0);
  453.   rectfill(page1,78,5,562,30,1);
  454. }
  455.  
  456.  
  457.  
  458.  
  459. void show_score()
  460. {
  461. text_mode(-1);
  462. sprintf(ch_tmp,"%d",score);
  463. textout(page1,fontfile[SMALL].dat,ch_tmp,80,11,86);
  464. textout(page1,fontfile[SMALL].dat,ch_tmp,81,12,129);
  465. sprintf(ch_tmp,"LEVEL %d",level);
  466. textout(page1,fontfile[SMALL].dat,ch_tmp,382,12,86);
  467. textout(page1,fontfile[SMALL].dat,ch_tmp,383,13,129);
  468. sprintf(ch_tmp,"LIVES %d",lives);
  469. textout(page1,fontfile[SMALL].dat,ch_tmp,485,12,86);
  470. textout(page1,fontfile[SMALL].dat,ch_tmp,486,13,129);
  471. }
  472.  
  473.  
  474.  
  475.  
  476. void initialise_variables()
  477. {
  478.   int n;
  479.   frame_delay=1;
  480.   frame_fps=0;
  481.   score=0;
  482.   level=0;
  483.   lives=4;
  484.   bat_type=1; // 1= normal ball, 2=large ball, 3=small ball
  485.   ball_out=0; // 0=ball in play, 1= ball out of play
  486.   bounces=0;  // set ball bounces counter to zero
  487.   vel_x=2;    //  ball velocity (used as a multiplier for dx & dy)
  488.   vel_y=2;
  489.   laser_down=0; //
  490.   laser_enable=0;// disable laser
  491.   laser_ptr=-1;
  492.   catch_down=0;
  493.   catch_enable=0;
  494.   catch_ptr=-1;
  495.   power_down=0;
  496.   power_enable=0;
  497.   power_ptr=-1;
  498.   if (input_device==0) input_device=1;
  499.   // ensure that nothing is exploded at start of game
  500.   for (n=1 ;n<11 ;n++) {
  501.    explde[n]=0;
  502.    explode_frame[n]=0;
  503.   }
  504. }
  505.  
  506.  
  507.  
  508. void update_bat_position()
  509. {
  510. int x,b;
  511. // get input
  512.  
  513. // get mouse input
  514. if (input_device==1) {
  515.   {x=mouse_x; b=mouse_b;}
  516.   bat[bat_type].bx=x;
  517.   bat[bat_type].bb=b;
  518. }
  519.  
  520. // get keyboard input if required
  521. if (input_device==2) {
  522.   if (key[KEY_CONTROL]) bat[bat_type].bb=1;
  523.   if (key[KEY_CONTROL] ==FALSE) bat[bat_type].bb=0;
  524.   if (key[KEY_ALT]) bat[bat_type].bb=2;
  525.   if (key[KEY_LEFT]) bat[bat_type].bx-=8;
  526.   if (key[KEY_RIGHT]) bat[bat_type].bx+=8;
  527. }
  528.  
  529. // get joystick input if required
  530. if (input_device==3) {
  531.   poll_joystick();
  532.   if (joy_b1!=0) bat[bat_type].bb=1;
  533.   if (joy_b1==0) bat[bat_type].bb=0;
  534.   if (joy_b2!=0) bat[bat_type].bb=2;
  535.   if (joy_left) bat[bat_type].bx-=8;
  536.   if (joy_right) bat[bat_type].bx+=8;
  537. }
  538.  
  539. // ensure bat is not off side of screen
  540. if (bat[bat_type].bx+bat[bat_type].bw>563) {bat[bat_type].bx=563-bat[bat_type].bw; mouse_x=563;}
  541. if (bat[bat_type].bx<78) bat[bat_type].bx=78;
  542. // update drawing screen with new bat position
  543. // if the laser enable flag is set draw a laser bat
  544. if (laser_enable==1) draw_sprite(page1,laser_bat,bat[1].bx,bat[1].by);
  545. // if the catch enable flag is set draw a catch bat
  546. if (catch_enable==1) draw_sprite(page1,catch_bat,bat[1].bx,bat[1].by);
  547. // If one of the above bats is not displayed, draw a normal bat
  548. if ((laser_enable!=1) && (catch_enable!=1)){
  549.     if (bat_type==1) draw_sprite(page1,bat1,bat[bat_type].bx,bat[bat_type].by);
  550.     if (bat_type==2) draw_sprite(page1,bat2,bat[bat_type].bx,bat[bat_type].by);
  551.     if (bat_type==3) draw_sprite(page1,bat3,bat[bat_type].bx,bat[bat_type].by);
  552.   }
  553. }
  554.  
  555.  
  556.  
  557.  
  558.  
  559. // if a special block has been hit, make it move down the screen
  560. void move_blocks()
  561. {
  562.   // only update the block position evey 8 frames out of 10
  563.   if (frame_skip>1) {
  564.     // has the move laser block down flag been set ?
  565.     if (laser_down==1) {
  566.       // as we want to see the laser block falling, re-enable block show
  567.       blocks[laser_ptr].b_show=1;
  568.       // move laser block down one pixel
  569.       blocks[laser_ptr].by+=2;
  570.       // has the laser block missed the bat and reached the bottom of the screen ?
  571.       if (blocks[laser_ptr].by>455) {
  572.         laser_down=0;
  573.         blocks[laser_ptr].b_show=0;
  574.       }
  575.       // Has the laser block hit the bat, if so set the enable laser flag
  576.       if (((blocks[laser_ptr].bx>bat[bat_type].bx)
  577.         &&(blocks[laser_ptr].bx<bat[bat_type].bx+bat[bat_type].bw))
  578.         ||((blocks[laser_ptr].bx+blocks[laser_ptr].bw >bat[bat_type].bx)
  579.         &&(blocks[laser_ptr].bx+blocks[laser_ptr].bw <bat[bat_type].bx+bat[bat_type].bw))){
  580.           if (blocks[laser_ptr].by>450) {
  581.             bat[1].bx=bat[bat_type].bx;
  582.             bat_type=1;
  583.             laser_enable=1;
  584.             catch_enable=0;
  585.             play_sample(powerup,255,128,6000,FALSE);
  586.             score+=100;
  587.             blocks[laser_ptr].b_show=0;
  588.  
  589.           }
  590.         }
  591.     }
  592.     // *******************************************************************************************
  593.     // has the move catch block down flag been set ?
  594.     if (catch_down==1) {
  595.       // as we want to see the catch block falling, re-enable block show
  596.       blocks[catch_ptr].b_show=1;
  597.       // move catch block down one pixel
  598.       blocks[catch_ptr].by+=2;
  599.       // has the catch block missed the bat and reached the bottom of the screen ?
  600.       if (blocks[catch_ptr].by>455) {
  601.         catch_down=0;
  602.         blocks[catch_ptr].b_show=0;
  603.       }
  604.       // Has the catch block hit the bat, if so set the enable catch flag
  605.       if (((blocks[catch_ptr].bx>bat[bat_type].bx)
  606.         &&(blocks[catch_ptr].bx<bat[bat_type].bx+bat[bat_type].bw))
  607.         ||((blocks[catch_ptr].bx+blocks[catch_ptr].bw >bat[bat_type].bx)
  608.         &&(blocks[catch_ptr].bx+blocks[catch_ptr].bw <bat[bat_type].bx+bat[bat_type].bw))) {
  609.           if (blocks[catch_ptr].by>450) {
  610.             bat[1].bx=bat[bat_type].bx;
  611.             bat_type=1;
  612.             catch_enable=1;
  613.             laser_enable=0;
  614.             play_sample(powerup,255,128,6000,FALSE);
  615.             score+=100;
  616.             blocks[catch_ptr].b_show=0;
  617.           }
  618.       }
  619.     }
  620.     // *******************************************************************************************
  621.     // has the move power block down flag been set ?
  622.     if (power_down==1) {
  623.       // as we want to see the power block falling, re-enable block show
  624.       blocks[power_ptr].b_show=1;
  625.       // move power block down one pixel
  626.       blocks[power_ptr].by+=2;
  627.       // has the power block missed the bat and reached the bottom of the screen ?
  628.       if (blocks[power_ptr].by>455) {
  629.         power_down=0;
  630.         blocks[power_ptr].b_show=0;
  631.       }
  632.       // Has the power block hit the bat, if so set the enable power flag
  633.       if (((blocks[power_ptr].bx>bat[bat_type].bx)
  634.         &&(blocks[power_ptr].bx<bat[bat_type].bx+bat[bat_type].bw))
  635.         ||((blocks[power_ptr].bx+blocks[power_ptr].bw >bat[bat_type].bx)
  636.         &&(blocks[power_ptr].bx+blocks[power_ptr].bw <bat[bat_type].bx+bat[bat_type].bw))) {
  637.           if (blocks[power_ptr].by>450) {
  638.             power_enable=1;
  639.             play_sample(powerup,255,128,6000,FALSE);
  640.             score+=100;
  641.             blocks[power_ptr].b_show=0;
  642.           }
  643.       }
  644.     }
  645.     // *******************************************************************************************
  646.     // has the move plus life block down flag been set ?
  647.     if (plus_down==1) {
  648.       // as we want to see the plus block falling, re-enable block show
  649.       blocks[plus_ptr].b_show=1;
  650.       // move plus block down one pixel
  651.       blocks[plus_ptr].by+=2;
  652.       // has the plus block missed the bat and reached the bottom of the screen ?
  653.       if (blocks[plus_ptr].by>455) {
  654.         plus_down=0;
  655.         blocks[plus_ptr].b_show=0;
  656.       }
  657.       // Has the plus block hit the bat, if so set the enable plus flag
  658.       if (((blocks[plus_ptr].bx>bat[bat_type].bx)
  659.         &&(blocks[plus_ptr].bx<bat[bat_type].bx+bat[bat_type].bw))
  660.         ||((blocks[plus_ptr].bx+blocks[plus_ptr].bw >bat[bat_type].bx)
  661.         &&(blocks[plus_ptr].bx+blocks[plus_ptr].bw <bat[bat_type].bx+bat[bat_type].bw))) {
  662.           if (blocks[plus_ptr].by>450) {
  663.             plus_enable=1;
  664.             play_sample(new_life,255,128,1000,FALSE);
  665.             score+=100;
  666.             blocks[plus_ptr].b_show=0;
  667.           }
  668.       }
  669.     }
  670.     // *******************************************************************************************
  671.     // has the move next level block down flag been set ?
  672.     if (next_down==1) {
  673.       // as we want to see the next block falling, re-enable block show
  674.       blocks[next_ptr].b_show=1;
  675.       // move next block down one pixel
  676.       blocks[next_ptr].by+=2;
  677.       // has the next block missed the bat and reached the bottom of the screen ?
  678.       if (blocks[next_ptr].by>455) {
  679.         next_down=0;
  680.         blocks[next_ptr].b_show=0;
  681.       }
  682.       // Has the next block hit the bat, if so set the enable next flag
  683.       if (((blocks[next_ptr].bx>bat[bat_type].bx)
  684.       &&(blocks[next_ptr].bx<bat[bat_type].bx+bat[bat_type].bw))
  685.       ||((blocks[next_ptr].bx+blocks[next_ptr].bw >bat[bat_type].bx)
  686.       &&(blocks[next_ptr].bx+blocks[next_ptr].bw <bat[bat_type].bx+bat[bat_type].bw))) {
  687.         if (blocks[next_ptr].by>450) {
  688.           next_enable=1;
  689.           play_sample(powerup,255,128,6000,FALSE);
  690.           score+=100;
  691.           blocks[next_ptr].b_show=0;
  692.           }
  693.       }
  694.     }
  695.     // *******************************************************************************************
  696.     // has the move thru level block down flag been set ?
  697.     if (thru_down==1) {
  698.       // as we want to see the thru block falling, re-enable block show
  699.       blocks[thru_ptr].b_show=1;
  700.       // move thru block down one pixel
  701.       blocks[thru_ptr].by+=2;
  702.       // has the thru block missed the bat and reached the bottom of the screen ?
  703.       if (blocks[thru_ptr].by>455) {
  704.         thru_down=0;
  705.         blocks[thru_ptr].b_show=0;
  706.       }
  707.       // Has the thru block hit the bat, if so set the enable thru flag
  708.       if (((blocks[thru_ptr].bx>bat[bat_type].bx)
  709.         &&(blocks[thru_ptr].bx<bat[bat_type].bx+bat[bat_type].bw))
  710.         ||((blocks[thru_ptr].bx+blocks[thru_ptr].bw >bat[bat_type].bx)
  711.         &&(blocks[thru_ptr].bx+blocks[thru_ptr].bw <bat[bat_type].bx+bat[bat_type].bw))) {
  712.           if (blocks[thru_ptr].by>450) {
  713.             thru_enable=1;
  714.             play_sample(powerup,255,128,6000,FALSE);
  715.             score+=100;
  716.             blocks[thru_ptr].b_show=0;
  717.           }
  718.       }
  719.     }
  720.   }
  721. }
  722.  
  723.  
  724.  
  725.  
  726. void initial_ball_position()
  727. {
  728. int button,offset;
  729.  balls[1].bx=315;
  730.  balls[1].by=452;
  731.  balls[1].dx=1;
  732.  balls[1].dy=-1;
  733.  // initial bat position
  734.  bat[1].bx=310;
  735.  bat[1].by=460;
  736.  bat[1].bw=70;
  737.  
  738.  bat[2].bx=215;
  739.  bat[2].by=460;
  740.  bat[2].bw=100;
  741.  
  742.  bat[3].bx=315;
  743.  bat[3].by=460;
  744.  bat[3].bw=50;
  745.  
  746.  offset=0;
  747.  // hold onto the ball until left mouse button is pressed
  748.  
  749.  {show_score(); drawing_screen(); copy_drawing();}
  750. if (lives!=0) {
  751.    if (ball_out==0) fade_in(pallete1,1);
  752.    poll_joystick();
  753.    while (((bat[bat_type].bb!=1)&&(key[KEY_CONTROL])!=TRUE)&&(joy_b1!=1)) {
  754.      poll_joystick();
  755.      update_bat_position();
  756.      show_score();
  757.      balls[1].bx=(bat[bat_type].bx+(bat[bat_type].bw/2)-3)+offset;
  758.      draw_sprite(page1,ball,balls[1].bx,balls[1].by);
  759.      {drawing_screen(); copy_drawing(); copy_backgrnd();}
  760.  
  761.      if (bat[bat_type].bb==2) offset++;
  762.  
  763.      if ((balls[1].bx+offset)-12>bat[bat_type].bx+bat[bat_type].bw) {
  764.        offset=1-(bat[bat_type].bw/2);
  765.      }
  766. // if ball positioned on left side of bat start ball moving left
  767.    if (balls[1].bx+3<(bat[bat_type].bx+bat[bat_type].bw/2)) balls[1].dx=-1;
  768. // if ball positioned on right side of bat start ball moving right
  769.    if (balls[1].bx+3>=(bat[bat_type].bx+bat[bat_type].bw/2)) balls[1].dx=+1;
  770.  
  771.      move_blocks();
  772.      {frame_skip ++; if (frame_skip==10) frame_skip=1;}
  773.    }
  774. }
  775. // record time for fps routine
  776. frame_tstart=rawclock();
  777. frame_ctr=0;
  778. }
  779.  
  780.  
  781.  
  782.  
  783. void update_ball_position()
  784. {
  785.   int bat_centre;
  786.  
  787.       if (bounces>0)    {vel_x=2+bounce_angle; vel_y=2;}
  788.       if (bounces>2000) {vel_x=3+bounce_angle*2; vel_y=3;}
  789.       if (bounces>4000) {vel_x=4+(bounce_angle*3); vel_y=4;}
  790.  
  791.       // bounce ball around screen
  792.       balls[1].bx=balls[1].bx+(balls[1].dx)*vel_x;
  793.       balls[1].by=balls[1].by+(balls[1].dy)*vel_y;
  794.  
  795.       if (balls[1].bx>550) {balls[1].dx= -balls[1].dx;play_sample(bounce,255,255,1000,FALSE);score++;}
  796.       if (balls[1].bx<85) {balls[1].dx= -balls[1].dx;play_sample(bounce,255,0,1000,FALSE);score++;}
  797.       if (balls[1].by<62) {balls[1].dy= -balls[1].dy;play_sample(bounce,255,128,1000,FALSE);score++;}
  798.       // increase ball bounce counter
  799.       bounces++;
  800.       // if ball drops below level of bat then it is out of play
  801.       if (balls[1].by>452) {
  802.         // check to see if it is over the bat
  803.         if ((balls[1].bx+10<bat[bat_type].bx)||(balls[1].bx-10>bat[bat_type].bx+bat[bat_type].bw)) ball_out=1;
  804.            else {
  805.             //bounce ball off bat
  806.             // if the ball bounces off the outer section of the bat
  807.             // increase the bounce angle
  808.             bat_centre=bat[bat_type].bx+(bat[bat_type].bw/2);
  809.             balls[1].dy=-balls[1].dy;
  810.             bounce_angle=0;
  811.             if (bat_type==1) {if ((balls[1].bx+5<bat_centre-15)|| (balls[1].bx+5>bat_centre+15)) bounce_angle=1;}
  812.             if (bat_type==2) {if ((balls[1].bx+5<bat_centre-30)|| (balls[1].bx+5>bat_centre+30)) bounce_angle=1;}
  813.             if (bat_type==3) {if ((balls[1].bx+5<bat_centre-10)|| (balls[1].bx+5>bat_centre+10)) bounce_angle=1;}
  814.             play_sample(bounce,255,128,1000,FALSE);score++;
  815.             // start monitoring time between ball hitting bat
  816.             bounce_time=rawclock();
  817.             if (mouse_b==2) balls[1].bx+=2;
  818.          }
  819.       }
  820.     // update drawing screen with new ball position
  821.     if ((power_enable==1)|| (thru_enable==1)) {
  822.       draw_sprite(page1,pwr_ball,balls[1].bx,balls[1].by);
  823.     } else draw_sprite(page1,ball,balls[1].bx,balls[1].by);
  824. }
  825.  
  826.  
  827.  
  828.  
  829.  
  830.  
  831. // Check for ball collision with brick
  832. void ball_collide_brick()
  833. {
  834. int skip,ctr;
  835.   new_level=1;
  836.   for (ptr=0; ptr<303; ptr++) {
  837.     //  if there is a brick on the screen, set new level flag to false.
  838.     if (blocks[ptr].b_show==1) new_level=0;
  839.     // is the ball over a displayed brick
  840.     // but not one which is moving
  841.     if ((balls[1].bx+vel_x+5+bounce_angle>=blocks[ptr].bx) &&   //LEFT
  842.        (balls[1].bx-vel_x-bounce_angle<=blocks[ptr].bx+blocks[ptr].bw) && //RIGHT
  843.        (balls[1].by+vel_y+5>=blocks[ptr].by) &&                 //TOP
  844.        (balls[1].by-vel_y<=blocks[ptr].by+blocks[ptr].bh)&&     //BOTTOM
  845.        (blocks[ptr].b_show!=0) &&
  846.        (ptr!=laser_ptr) && (ptr!=catch_ptr) && (ptr!=power_ptr)) {
  847.        // Yes, the ball is over a brick
  848.        // Play sound
  849.        play_sample(hit_block,255,(balls[1].bx),1000,FALSE);
  850.  
  851.        // bounce ball
  852.        // only if the ball through flag is not set
  853.        // or if the block is invincible
  854.        if ((thru_enable==0)|| (blocks[ptr].b_type==15)){
  855.         skip=0;
  856.          // ball hits bottom of brick
  857.         for (ctr=0; ctr<=vel_y; ctr++) {
  858.          if (balls[1].by-ctr==blocks[ptr].by+blocks[ptr].bh) {
  859.            balls[1].dy=-balls[1].dy;
  860.            balls[1].by=balls[1].by+vel_y;
  861.            skip=1;
  862.            break;
  863.          }
  864.         }
  865.          // ball hits top of brick
  866.         for (ctr=0; ctr<=vel_y; ctr++) {
  867.          if ((balls[1].by+ctr+6==blocks[ptr].by)&& (skip==0)) {
  868.            balls[1].dy=-balls[1].dy;
  869.            balls[1].by=balls[1].by-vel_y;
  870.            skip=1;
  871.            break;
  872.          }
  873.         }
  874.          // ball hits left side of brick
  875.         for (ctr=0; ctr<=vel_x+bounce_angle; ctr++) {
  876.          if ((balls[1].bx+ctr+6+bounce_angle==blocks[ptr].bx)&&(skip==0)) {
  877.            balls[1].dx=-balls[1].dx;
  878.            balls[1].bx=balls[1].bx-vel_x;
  879.            skip=1;
  880.            break;
  881.          }
  882.         }
  883.  
  884.          // ball hits right side of brick
  885.         for (ctr=0; ctr<=vel_x+bounce_angle+1; ctr++) {
  886.          if ((balls[1].bx-ctr-bounce_angle==blocks[ptr].bx+blocks[ptr].bw)&&(skip==0)) {
  887.            balls[1].dx=-balls[1].dx;
  888.            balls[1].bx=balls[1].bx+vel_x;
  889.            break;
  890.          }
  891.         }
  892.  
  893.          // this is added insurance
  894.          if (balls[1].dy==0) balls[1].dy=1;
  895.          if (balls[1].dx==0) balls[1].dx=1;
  896.        }
  897.  
  898.  
  899.        // if the power ball is enabled, explode the surrounding bricks
  900.        if ((power_enable==1) && (blocks[ptr].b_show==1)) {
  901.          // Play sound
  902.          play_sample(explode,255,(blocks[ptr].bx),1000,FALSE);
  903.          // point to the bricks to explode
  904.          {explde[1]=ptr;blocks[ptr].b_show=0;score+=20;}
  905.          if (blocks[ptr+1].b_show==1) {explde[2]=ptr+1; blocks[ptr+1].b_show=0;score+=20;}
  906.          if (blocks[ptr-1].b_show==1) {explde[3]=ptr-1; blocks[ptr-1].b_show=0;score+=20;}
  907.          if (blocks[ptr-16].b_show==1){explde[4]=ptr-16;blocks[ptr-16].b_show=0;score+=20;}
  908.          if (blocks[ptr+16].b_show==1){explde[5]=ptr+16;blocks[ptr+16].b_show=0;score+=20;}
  909.        }
  910.  
  911.        // erase the brick if the blocks hit value is zero
  912.        if ((blocks[ptr].hits >0)&& (blocks[ptr].b_show!=2)) blocks[ptr].hits--;
  913.        if (blocks[ptr].hits <1) {blocks[ptr].b_show=0;score+=20;}
  914.        // The ball has just bounced off an exploding brick
  915.        if (blocks[ptr].b_type==6) {
  916.          // Play sound
  917.          play_sample(explode,255,(blocks[ptr].bx),1000,FALSE);
  918.          // point to the bricks to explode
  919.          explde[1]=ptr;
  920.          if (blocks[ptr+1].b_show==1) {explde[2]=ptr+1; blocks[ptr+1].b_show=0;score+=20;}
  921.          if (blocks[ptr-1].b_show==1) {explde[3]=ptr-1; blocks[ptr-1].b_show=0;score+=20;}
  922.          if (blocks[ptr-16].b_show==1){explde[4]=ptr-16;blocks[ptr-16].b_show=0;score+=20;}
  923.          if (blocks[ptr+16].b_show==1){explde[5]=ptr+16;blocks[ptr+16].b_show=0;score+=20;}
  924.        }
  925.        // The ball has just bounced off a laser brick
  926.        // set flag to start laser blocks moving down the screen
  927.        // dont move the laser block down if one is already moving
  928.        if ((blocks[ptr].b_type==5) && (laser_down!=1)) {
  929.           laser_down=1;
  930.           laser_ptr=ptr;
  931.           score+=100;
  932.        }
  933.        // The ball has just bounced off a catch brick
  934.        // set flag to start catch block moving down the screen
  935.        // dont move the catch block down if one is already moving
  936.        if ((blocks[ptr].b_type==7) && (catch_down!=1)) {
  937.           catch_down=1;
  938.           catch_ptr=ptr;
  939.        }
  940.        // The ball has just bounced off a slow ball brick
  941.        // adjust 'bounce' variable so that the ball moves slowly
  942.        if (blocks[ptr].b_type==10) {
  943.           bounces=0;
  944.           play_sample(ball_slow,255,128,1000,FALSE);
  945.        }
  946.        // The ball has just bounced off a fast ball brick
  947.        // adjust 'bounce' variable so that the ball moves fast
  948.        if (blocks[ptr].b_type==11) {
  949.           bounces=8000;
  950.           play_sample(ball_fast,255,128,1000,FALSE);
  951.        }
  952.        // The ball has just bounced off a power ball brick
  953.        // set flag to start power block moving down the screen
  954.        // dont move the power block down if one is already moving
  955.        if ((blocks[ptr].b_type==12) && (power_down!=1)) {
  956.           power_down=1;
  957.           power_ptr=ptr;
  958.        }
  959.  
  960.        // The ball has just bounced off a small bat brick
  961.        // set the bat type to small
  962.        if (blocks[ptr].b_type==13) {
  963.            bat[3].bx=bat[bat_type].bx; // copy x pos of last bat to new bat
  964.            bat_type=3;
  965.            play_sample(bat_sml,255,128,1000,FALSE);
  966.           {catch_enable=0;laser_enable=0;}
  967.        }
  968.  
  969.        // The ball has just bounced off a large bat brick
  970.        // set the bat type to large
  971.        if (blocks[ptr].b_type==14) {
  972.           {catch_enable=0;laser_enable=0;}
  973.           bat[2].bx=bat[bat_type].bx;  // copy x pos of last bat to new bat
  974.           bat_type=2;
  975.           play_sample(bat_lrg,255,128,1000,FALSE);
  976.        }
  977.        // The ball has just bounced off a plus 1 life brick
  978.        // set flag to start plus block moving down the screen
  979.        // dont move the plus block down if one is already moving
  980.        if ((blocks[ptr].b_type==16) && (plus_down!=1)) {
  981.           plus_down=1;
  982.           plus_ptr=ptr;
  983.        }
  984.        // The ball has just bounced off a next level brick
  985.        // set flag to start next level block moving down the screen
  986.        // dont move the next level block down if one is already moving
  987.        if ((blocks[ptr].b_type==17) && (next_down!=1)) {
  988.           next_down=1;
  989.           next_ptr=ptr;
  990.        }
  991.        // The ball has just bounced off a ball thru brick
  992.        // set flag to start ball thru block moving down the screen
  993.        // dont move the ball thru block down if one is already moving
  994.        if ((blocks[ptr].b_type==18) && (thru_down!=1)) {
  995.           thru_down=1;
  996.           thru_ptr=ptr;
  997.        }
  998.     }
  999.   }
  1000. }
  1001.  
  1002.  
  1003.  
  1004. void explode_bricks()
  1005. {
  1006. int n,x,y;
  1007. // array 'explode' hold the brick no. to explode
  1008. // array 'explode_frame' holds the animation frame to display.
  1009. //                       there are 10 animation frames per explosion.
  1010. for (n=0; n<10; n++) {
  1011.   if (explde[n]>0) {
  1012.     // advance frame every 10 frames of game
  1013.     if (frame_skip>5) explode_frame[n]++;
  1014.     x=blocks[explde[n]].bx;
  1015.     y=blocks[explde[n]].by;
  1016.     if (explode_frame[n]==1) blit (explosion_frames,page1,0,0,x,y,25,10);
  1017.     if (explode_frame[n]==2) blit (explosion_frames,page1,24,0,x,y,25,10);
  1018.     if (explode_frame[n]==3) blit (explosion_frames,page1,48,0,x,y,25,10);
  1019.     if (explode_frame[n]==4) blit (explosion_frames,page1,72,0,x,y,25,10);
  1020.     if (explode_frame[n]==5) blit (explosion_frames,page1,96,0,x,y,25,10);
  1021.     if (explode_frame[n]==6) blit (explosion_frames,page1,120,0,x,y,25,10);
  1022.     if (explode_frame[n]==7) blit (explosion_frames,page1,144,0,x,y,25,10);
  1023.     if (explode_frame[n]==8) blit (explosion_frames,page1,168,0,x,y,25,10);
  1024.     if (explode_frame[n]==9) blit (explosion_frames,page1,192,0,x,y,25,10);
  1025.     if (explode_frame[n]==10) {
  1026.       blit (explosion_frames,page1,279,0,x,y-10,31,31);
  1027.       explde[n]=0;
  1028.       explode_frame[n]=0;
  1029.     }
  1030.   }
  1031. }
  1032. }
  1033.  
  1034.  
  1035.  
  1036.  
  1037. void fire_laser()
  1038. {
  1039. // only fire the laser if the conditions below are true
  1040. // ie laser enabled, left mouse button pressed, laser not already firing
  1041. if((bat[1].bb==1) && (laser_enable==1) && (las_firing1==0)) {
  1042.   las_x1=bat[1].bx+10;
  1043.   las_y1=460;
  1044.   las_firing1=1;
  1045.   // Play sound
  1046.   play_sample(laser,255,bat[1].bx,2000,FALSE);
  1047. }
  1048. // move laser beam up screen
  1049. if(las_firing1==1) {
  1050.   if (frame_skip>1) las_y1-=12;
  1051.   vline(page1,las_x1-1,las_y1,las_y1-5,32);
  1052.   vline(page1,las_x1,las_y1,las_y1-10,178);
  1053.   vline(page1,las_x1+1,las_y1,las_y1-5,32);
  1054.   // if beam reaches top of screen set las_firing flag to false
  1055.   if (las_y1<=70) {
  1056.     las_firing1=0;
  1057.   }
  1058.   //check for laser beam hitting brick
  1059.   // check every brick
  1060.   for (ptr=0; ptr<303; ptr++) {
  1061.     if ((las_x1>=blocks[ptr].bx) &&
  1062.        (las_x1<=blocks[ptr].bx+blocks[ptr].bw) &&
  1063.        (las_y1>=blocks[ptr].by) &&
  1064.        (las_y1<=blocks[ptr].by+blocks[ptr].bh)&&
  1065.        (blocks[ptr].b_show!=0)) {
  1066.          // Yes, the laser is over a brick
  1067.          // erase the brick
  1068.          if (blocks[ptr].b_show==1) {blocks[ptr].b_show=0; blocks[ptr].hits=0; score+=20; las_firing1=0;}
  1069.          if (blocks[ptr].b_show==2) {las_firing1=0;}
  1070.          // The laser has just hit an exploding brick
  1071.          // Play sound
  1072.          play_sample(explode,255,(bat[1].bx),1000,FALSE);
  1073.          // point to the bricks to explode
  1074.          explde[1]=ptr;
  1075.          if (blocks[ptr+1].b_show==1) {explde[2]=ptr+1; blocks[ptr+1].b_show=0;score+=20;}
  1076.          if (blocks[ptr-1].b_show==1) {explde[3]=ptr-1; blocks[ptr-1].b_show=0;score+=20;}
  1077.          if (blocks[ptr-16].b_show==1){explde[4]=ptr-16;blocks[ptr-16].b_show=0;score+=20;}
  1078.          if (blocks[ptr+16].b_show==1){explde[5]=ptr+16;blocks[ptr+16].b_show=0;score+=20;}
  1079.     }
  1080.   }
  1081. }
  1082.  
  1083. if((bat[1].bb==1) && (laser_enable==1) && (las_firing2==0)) {
  1084.   las_x2=bat[1].bx+50;
  1085.   las_y2=460;
  1086.   las_firing2=1;
  1087.   // Play sound
  1088.   play_sample(laser,255,bat[1].bx,2000,FALSE);
  1089. }
  1090. // move laser beam up screen
  1091. if(las_firing2==1) {
  1092.   if (frame_skip>1) las_y2-=12;
  1093.   vline(page1,las_x2-1,las_y2,las_y2-5,32);
  1094.   vline(page1,las_x2,las_y2,las_y2-10,178);
  1095.   vline(page1,las_x2+1,las_y2,las_y2-5,32);
  1096.   // if beam reaches top of screen set las_firing flag to false
  1097.   if (las_y2<=70) {
  1098.     las_firing2=0;
  1099.   }
  1100.   //check for laser beam hitting brick
  1101.   // check every brick
  1102.   for (ptr=0; ptr<303; ptr++) {
  1103.     if ((las_x2>=blocks[ptr].bx) &&
  1104.        (las_x2<=blocks[ptr].bx+blocks[ptr].bw) &&
  1105.        (las_y2>=blocks[ptr].by) &&
  1106.        (las_y2<=blocks[ptr].by+blocks[ptr].bh)&&
  1107.        (blocks[ptr].b_show!=0)) {
  1108.          // Yes, the laser is over a brick
  1109.          // erase the brick
  1110.          if (blocks[ptr].b_show==1) {blocks[ptr].b_show=0; blocks[ptr].hits=0; score+=20; las_firing2=0;}
  1111.          if (blocks[ptr].b_show==2) {las_firing2=0;}
  1112.          // The laser has just hit an exploding brick
  1113.          // Play sound
  1114.          play_sample(explode,255,(bat[1].bx),1000,FALSE);
  1115.          // point to the bricks to explode
  1116.          explde[1]=ptr;
  1117.          if (blocks[ptr+1].b_show==1) {explde[2]=ptr+1; blocks[ptr+1].b_show=0;score+=20;}
  1118.          if (blocks[ptr-1].b_show==1) {explde[3]=ptr-1; blocks[ptr-1].b_show=0;score+=20;}
  1119.          if (blocks[ptr-16].b_show==1){explde[4]=ptr-16;blocks[ptr-16].b_show=0;score+=20;}
  1120.          if (blocks[ptr+16].b_show==1){explde[5]=ptr+16;blocks[ptr+16].b_show=0;score+=20;}
  1121.     }
  1122.   }
  1123. }
  1124.  
  1125. }
  1126.  
  1127.  
  1128.  
  1129.  
  1130.  
  1131.  
  1132. void catch_ball()
  1133. {
  1134. int temp1,temp2,button, offset;
  1135. // check to see if it is over the bat
  1136. // and the catch flag is set
  1137. if ((balls[1].bx+8>bat[1].bx)&&
  1138.    (balls[1].bx-8<bat[1].bx+bat[1].bw)&&
  1139.    (balls[1].by>452)&&
  1140.    (next_enable!=1)&&
  1141.    (catch_enable==1)) {
  1142.       play_sample(catch,255,0,1000,FALSE);
  1143.    // store position of ball and bat when ball hit the bat
  1144.    temp1=balls[1].bx;
  1145.    temp2=bat[1].bx;
  1146.    offset=0;
  1147.    // hold onto the ball until left mouse button is pressed
  1148.    while (((bat[bat_type].bb!=1)&&(key[KEY_CONTROL])!=TRUE)&&(joy_b1!=1)) {
  1149.      update_bat_position();
  1150.      balls[1].bx=(bat[bat_type].bx+(bat[bat_type].bw/2)-3)+offset;
  1151.  
  1152.  
  1153.      if (bat[bat_type].bb) offset++;
  1154.      if ((balls[1].bx+offset)-12>bat[bat_type].bx+bat[bat_type].bw) {
  1155.        offset=1-(bat[bat_type].bw/2);
  1156.      }
  1157.      if (power_enable==1) {
  1158.        draw_sprite(page1,pwr_ball,balls[1].bx,balls[1].by);
  1159.      } else draw_sprite(page1,ball,balls[1].bx,balls[1].by);
  1160.      show_score();
  1161.      {drawing_screen(); copy_drawing(); copy_backgrnd();}
  1162.      button=mouse_b;
  1163.      move_blocks();
  1164.      {frame_skip ++; if (frame_skip==10) frame_skip=1;}
  1165.    }
  1166.    play_sample(catch,255,255,1000,FALSE);
  1167.    //bounce ball off bat
  1168.    // if ball positioned on left side of bat start ball moving left
  1169.    if (balls[1].bx+3<(bat[bat_type].bx+bat[bat_type].bw/2)) balls[1].dx=-1;
  1170. // if ball positioned on right side of bat start ball moving right
  1171.    if (balls[1].bx+3>=(bat[bat_type].bx+bat[bat_type].bw/2)) balls[1].dx=+1;
  1172.    balls[1].by=451;
  1173.    // record time for fps routine
  1174.    frame_tstart=rawclock();
  1175.    frame_ctr=0;
  1176. }
  1177. }
  1178.  
  1179.  
  1180.  
  1181.  
  1182. void next_level()
  1183. {
  1184. int n;
  1185. if (level!=0) {
  1186.  show_score();drawing_screen(); copy_drawing(); copy_backgrnd();
  1187.  n=rawclock()+18;
  1188.  while (rawclock()<n);
  1189.  play_sample(newlevel,255,128,1000,FALSE);
  1190.  fade_out(1);
  1191.  if (level==40) level=0;
  1192.  bat_type=1;    // set bat size back to normal size
  1193.  bounces=0;
  1194.  las_firing1=0;
  1195.  laser_down=0; //
  1196.  laser_enable=0;// disable laser
  1197.  laser_ptr=-1;
  1198.  catch_down=0;
  1199.  catch_enable=0;
  1200.  catch_ptr=-1;
  1201.  power_down=0;
  1202.  power_enable=0;
  1203.  power_ptr=-1;
  1204.  plus_down=0;
  1205.  plus_enable=0;
  1206.  plus_ptr=-1;
  1207.  next_down=0;
  1208.  next_enable=0;
  1209.  next_ptr=-1;
  1210.  thru_down=0;
  1211.  thru_enable=0;
  1212.  thru_ptr=-1;
  1213.  // ensure that nothing is exploded at start of game
  1214.  for (n=1 ;n<11 ;n++) {
  1215.   explde[n]=0;
  1216.   explode_frame[n]=0;
  1217.  }
  1218. }
  1219. //set_pallete(pallete2);                 // set pallete
  1220. level ++;
  1221. clear(screen);
  1222. blit(bg1,screen,5,0,0,0,640,480);
  1223. text_mode(-1);
  1224. textout(screen,fontfile[LARGE].dat,"Get Ready !",160,220,97);
  1225. textout(screen,fontfile[LARGE].dat,"Get Ready !",162,222,98);
  1226. play_sample(newlev2,255,128,1000,FALSE);
  1227. fade_in(pallete2,1);
  1228. fade_out(1);
  1229. bounce_time=rawclock();
  1230. }
  1231.  
  1232.  
  1233.  
  1234.  
  1235. void out_of_play()
  1236. {
  1237. int n;
  1238. play_sample(loose1,255,128,1000,FALSE);
  1239. // remove any blocks that are falling
  1240. // by setting the 'y psn of the blocks to 186
  1241. // they will be removed the next time 'remove_blocks is called
  1242. if (laser_down==1) {blocks[laser_ptr].by=500;}
  1243. if (catch_down==1) {blocks[catch_ptr].by=500;}
  1244. if (power_down==1) {blocks[power_ptr].by=500;}
  1245. if (plus_down==1) {blocks[plus_ptr].by=500;}
  1246. if (next_down==1) {blocks[next_ptr].by=500;}
  1247. if (thru_down==1) {blocks[thru_ptr].by=500;}
  1248.  
  1249. lives--;
  1250. initial_ball_position();
  1251. ball_out=0;
  1252. bat_type=1;    // set bat size back to narmal size
  1253. // return bat to normal bat
  1254. laser_down=0; //
  1255. laser_enable=0;// disable laser
  1256. laser_ptr=-1;
  1257. catch_down=0;
  1258. catch_enable=0;
  1259. catch_ptr=-1;
  1260. power_down=0;
  1261. power_enable=0;
  1262. power_ptr=-1;
  1263. plus_down=0;
  1264. plus_enable=0;
  1265. plus_ptr=-1;
  1266. next_down=0;
  1267. next_enable=0;
  1268. next_ptr=-1;
  1269. thru_down=0;
  1270. thru_enable=0;
  1271. thru_ptr=-1;
  1272. vel_x=2;
  1273. vel_y=2;
  1274. bounce_angle=0;
  1275. bounces=0;
  1276. bounce_time=rawclock();
  1277. // ensure that nothing is exploded at start of game
  1278. for (n=1 ;n<11 ;n++) {
  1279.  explde[n]=0;
  1280.  explode_frame[n]=0;
  1281. }
  1282. }
  1283.  
  1284.  
  1285.  
  1286. void extras()
  1287. {
  1288. int i,n;
  1289. // add a new life
  1290. if (plus_enable==1) {
  1291.   plus_enable=0;
  1292.   plus_down=0;
  1293.   lives++;
  1294.   blocks[plus_ptr].by=300;
  1295. }
  1296. // the next level block has been collected
  1297. // explode each block in turn and then go
  1298. // to the next level
  1299. if (next_enable==1) {
  1300.   next_enable=0;
  1301.   for (ptr=0;ptr<155;ptr++) {
  1302.     if ((blocks[ptr].b_show!=0)||(blocks[302-ptr].b_show!=0))  {
  1303.       play_sample(explode,255,128,1000,FALSE);
  1304.       blocks[302-ptr].b_show=0;
  1305.       blocks[ptr].b_show=0;
  1306.  
  1307.       i=rawclock()+0;
  1308.       while (rawclock()<i);
  1309.       score+=20;
  1310.       show_score();drawing_screen(); copy_drawing(); copy_backgrnd();
  1311.     }
  1312.   }
  1313.   new_level=1;
  1314. }
  1315. // increase frame counter
  1316. frame_ctr++;
  1317. }
  1318.  
  1319.  
  1320.  
  1321. void test()
  1322. {
  1323. int ptr;
  1324.   for (ptr=0;ptr<440;ptr++) {
  1325.     {drawing_screen(); copy_drawing(); copy_backgrnd();}
  1326.     sprintf(ch_tmp,"%d",ptr);
  1327.     textout(screen,fontfile[SMALL].dat,ch_tmp,10,5,5);
  1328.     sprintf(ch_tmp,"%d",blocks[ptr].b_show);
  1329.     textout(screen,fontfile[SMALL].dat,ch_tmp,100,5,5);
  1330.  
  1331.     readkey();
  1332.   }
  1333. }
  1334.  
  1335.  
  1336. void fps()
  1337. {
  1338. int n;
  1339. // has one second elapsed
  1340. if (rawclock()-frame_tstart>18) {
  1341.   frame_fps=frame_ctr;
  1342.   frame_ctr=0;
  1343.   frame_tstart=rawclock();
  1344. }
  1345. // delay to slow game down on fast machines
  1346. if (frame_fps>70) frame_delay+=2;
  1347. for (n=0;n<frame_delay;n++) vsync();
  1348. // DISPLAY THE FRAMES PER SECOND
  1349. //sprintf(ch_tmp,"%d",frame_fps);
  1350. //textout(page1,fontfile[SMALL].dat,ch_tmp,200,11,20);
  1351. //sprintf(ch_tmp,"%d",frame_delay);
  1352. //textout(page1,fontfile[SMALL].dat,ch_tmp,250,11,20);
  1353. }
  1354.  
  1355.  
  1356.  
  1357. void exit_screen()
  1358. {
  1359. fade_out(60);
  1360. blit(finish_screen,screen,0,0,0,0,640,480);
  1361. play_sample(finish,255,128,1000,FALSE);
  1362. fade_in(pal_finish,1);
  1363. readkey();
  1364. exit(0);
  1365. }
  1366.  
  1367.  
  1368.  
  1369. void display_gameover()
  1370. {
  1371. int i;
  1372. fade_out(2);
  1373. blit(gameover_screen,screen,0,0,0,0,640,480);
  1374. play_sample(finish,255,128,1000,FALSE);
  1375. fade_in(pal_gamover,2);
  1376. i=rawclock()+18;
  1377. while (rawclock()<i);
  1378. fade_out(2);
  1379. }
  1380.  
  1381.  
  1382.  
  1383.  
  1384.  
  1385. void display_hiscore()
  1386. {
  1387.  
  1388. int ptr,psn,i, sorted,k;
  1389. char ch[20], temp[80],name[22];
  1390. // load hiscore data
  1391. data=fopen("hiscore","r");
  1392. for (ptr=0;ptr<10;ptr++){
  1393.   fgets(hiscores[ptr].names,20,data);
  1394.   fscanf(data,"%d",&hiscores[ptr].scores);
  1395.   fscanf(data,"%d",&i);  // has to be done twice for some reason
  1396. }
  1397. fclose(data);
  1398.  
  1399. // display hi-score table
  1400. show_mouse(NULL);
  1401. blit(hiscore_screen,screen,0,0,0,0,640,480);
  1402. play_sample(hiscore,255,128,1000,TRUE);
  1403. fade_in(pal_hiscore,20);
  1404. text_mode(-1);
  1405. psn=0;
  1406. for (ptr=160;ptr<410;ptr+=25) {
  1407.   // draw border around each score
  1408.   rectfill(screen,29,ptr-3,598,ptr+18,101);
  1409.   rectfill(screen,30,ptr-1,600,ptr+20,100);
  1410.  
  1411.   // this is the name
  1412.   textout(screen,fontfile[SMALL].dat,hiscores[psn].names,40,ptr,1);
  1413.   textout(screen,fontfile[SMALL].dat,hiscores[psn].names,41,ptr+1,2);
  1414.   // this is the score
  1415.   sprintf(ch_tmp,"%d",hiscores[psn].scores);
  1416.   textout(screen,fontfile[SMALL].dat,ch_tmp,470,ptr,1);
  1417.   textout(screen,fontfile[SMALL].dat,ch_tmp,471,ptr+1,1);
  1418.   psn++;
  1419. }
  1420.  
  1421. // set score
  1422. // clear keyboard buffer
  1423.     clear_keybuf();
  1424. if (score>hiscores[9].scores) {
  1425.   // Erase EXIT box for now
  1426.   rectfill(screen,520,410,640,480,93);
  1427.  
  1428.   // border around text
  1429.   rectfill(screen,2,430,410,460,101);
  1430.   rectfill(screen,415,430,630,460,102);
  1431.   textout(screen,fontfile[SMALL].dat,"A TOP 10 SCORE  ENTER YOUR NAME >",5,435,1);
  1432.  
  1433.  
  1434.   // Enter player name
  1435.   //read in each character individually
  1436. ptr=0;
  1437. do {
  1438.   // GET KEYBOARD INPUT
  1439.   k=readkey();
  1440.   // CHECK FOR VALID ASCII CHARACTER
  1441.   if (((k & 0xFF)>31) && ((k & 0xFF)<127) && (ptr<15)) {
  1442.     // PLACE ASCII CHARACTER IN ARRAY name
  1443.     name[ptr]=(k & 0xFF);
  1444.     // THIS IS HERE TO SKIP A MISSING CHARACTER IN THE FONT TABLE
  1445.     if (name[ptr]>96) name[ptr]++;
  1446.     // CLEAR STRING name OF UNWANTED CHARACTERS (A BUG IN ALLEGRO ?)
  1447.     for (i=ptr+1; i<15 ;i++) name[i]=32;
  1448.     ptr++;
  1449.   }
  1450.   // BACKSPACE
  1451.   if ((k&0xFF)==8) {ptr--; name[ptr]=32;}
  1452.  
  1453.   // UPDATE TEXT ONTO THE SCREEN
  1454.   //OUTPUT ARRAY name TO SCREEN
  1455.   rectfill(screen,415,430,630,460,102);
  1456.   sprintf(ch,"%s",name);
  1457.   // convert characters to upper case
  1458.   textout(screen,fontfile[SMALL].dat,ch,430,435,1);
  1459. } while ((k & 0xFF) !=13);
  1460.   sprintf(hiscores[9].names,"%s \n",name);
  1461.   hiscores[9].scores=score;
  1462.   // sort hiscore table
  1463.   sorted=0;
  1464.   while(sorted==0) {
  1465.     sorted=1;
  1466.     for (ptr=0;ptr<9;ptr++) {
  1467.       if (hiscores[ptr].scores<hiscores[ptr+1].scores){
  1468.         i=hiscores[ptr].scores;
  1469.         hiscores[ptr].scores=hiscores[ptr+1].scores;
  1470.         hiscores[ptr+1].scores=i;
  1471.         sprintf(temp,"%s",hiscores[ptr].names);
  1472.         sprintf(hiscores[ptr].names,"%s",hiscores[ptr+1].names);
  1473.         sprintf(hiscores[ptr+1].names,"%s",temp);
  1474.         sorted=0;
  1475.       }
  1476.     }
  1477.   }
  1478.  
  1479.   // display hi-score table
  1480.   show_mouse(NULL);
  1481.   blit(hiscore_screen,screen,0,0,0,0,640,480);
  1482.   fade_in(pal_hiscore,20);
  1483.   text_mode(-1);
  1484.   psn=0;
  1485.   for (ptr=160;ptr<410;ptr+=25) {
  1486.   // draw border around each score
  1487.   rectfill(screen,29,ptr-3,598,ptr+18,101);
  1488.   rectfill(screen,30,ptr-1,600,ptr+20,100);
  1489.  
  1490.   // this is the name
  1491.   textout(screen,fontfile[SMALL].dat,hiscores[psn].names,40,ptr,1);
  1492.   textout(screen,fontfile[SMALL].dat,hiscores[psn].names,41,ptr+1,2);
  1493.   // this is the score
  1494.   sprintf(ch_tmp,"%d",hiscores[psn].scores);
  1495.   textout(screen,fontfile[SMALL].dat,ch_tmp,470,ptr,1);
  1496.   textout(screen,fontfile[SMALL].dat,ch_tmp,471,ptr+1,1);
  1497.   psn++;
  1498.   }
  1499.  
  1500.   // save hiscore data
  1501.   data=fopen("hiscore","w");
  1502.   for (ptr=0;ptr<10;ptr++){
  1503.     fputs(hiscores[ptr].names,data);
  1504.     fprintf(data,"%d",hiscores[ptr].scores);
  1505.     fputc(10,data);
  1506.     fputc(13,data);
  1507.   }
  1508. fclose(data);
  1509. score=0;
  1510. }
  1511.  
  1512. set_mouse_range(520,410,630,475);
  1513. position_mouse(520,410);
  1514. show_mouse(screen);
  1515. while ((mouse_b==0) || (mouse_x<520)) {
  1516.   position_mouse(mouse_x,mouse_y);
  1517.   show_mouse(screen);
  1518.   i=rawclock()+1;
  1519.   while (rawclock()<i);
  1520.   show_mouse(screen);
  1521. }
  1522. // reduce volume to zero
  1523. for (ptr=0;ptr<255;ptr+=10) {
  1524.   adjust_sample(hiscore,255-ptr,128,1000,FALSE);
  1525.   // slight delay
  1526.   i=rawclock()+1;
  1527.   while (rawclock()<i);
  1528. }
  1529. stop_sample(hiscore);
  1530. fade_out(4);
  1531. clear(screen);
  1532. }
  1533.  
  1534.  
  1535.  
  1536. void help()
  1537. {
  1538. int i,exit_flag;
  1539. blit(help_screen,screen,0,0,100,150,414,202);
  1540.  
  1541. i=rawclock();
  1542. while ((rawclock()-i)<8);
  1543. clear_keybuf();
  1544. exit_flag=0;
  1545. while (exit_flag==0) {
  1546.   // select input device 1=mouse, 2=keyboard, 3=joystick
  1547.   if(key[KEY_M])input_device=1;
  1548.   if(key[KEY_K])input_device=2;
  1549.   if(key[KEY_J])input_device=3;
  1550.  
  1551.   if(key[KEY_F12])exit_flag=1;
  1552. }
  1553. i=rawclock();
  1554. while ((rawclock()-i)<6);
  1555. }
  1556.  
  1557.  
  1558.  
  1559.  
  1560. void main_menu()
  1561. {
  1562. int ptr,i,box_selected;
  1563. while (box_selected!=1) {
  1564.   box_selected=0;
  1565.   clear(screen);
  1566.   blit(startup,screen,0,0,0,0,640,480);
  1567.   play_sample(half_amin,255,128,1000,TRUE);
  1568.   fade_in(pal_startup,1);
  1569.   set_mouse_range(10,350,630,440);
  1570.   position_mouse(360,400);
  1571.   while ((mouse_b !=1)|| (box_selected ==0)) {
  1572.     position_mouse(mouse_x,mouse_y);
  1573.     show_mouse(screen);
  1574.     i=rawclock()+1;
  1575.     while (rawclock()<i);
  1576.     show_mouse(screen);
  1577.     // erase option boxes
  1578.     {rect(screen,2,345,210,425,123); rect(screen,225,345,440,425,123); rect(screen,470,345,625,425,123);}
  1579.     // draw box around option if mouse is over it
  1580.     if ((mouse_x>0)&&(mouse_x<210))  {rect(screen,2,345,210,425,129);box_selected=1;}
  1581.     if ((mouse_x>225)&&(mouse_x<440)) {rect(screen,225,345,440,425,129);box_selected=2;}
  1582.     if ((mouse_x>470)&&(mouse_x<625)) {rect(screen,470,345,625,425,129);box_selected=3;}
  1583.     if (mouse_b!=1) box_selected=0;
  1584.     if(key[KEY_F12]) {
  1585.       help();
  1586.       blit(startup,screen,0,0,0,0,640,480);
  1587.     }
  1588.   }
  1589.   // reduce volume to zero
  1590.   for (ptr=0;ptr<255;ptr+=10) {
  1591.     adjust_sample(half_amin,255-ptr,128,1000,FALSE);
  1592.     // slight delay
  1593.     i=rawclock()+1;
  1594.     while (rawclock()<i);
  1595.   }
  1596.   fade_out(4);
  1597.   if (box_selected==3) exit_screen();
  1598.   if (box_selected==2) display_hiscore();
  1599.  
  1600.   stop_sample(half_amin);
  1601.   show_mouse(NULL);
  1602. }
  1603. }
  1604.  
  1605.  
  1606. void ball_stuck()
  1607. {
  1608. int between_bounces;
  1609. between_bounces=(rawclock()-bounce_time)/18;
  1610. if (between_bounces>40) {next_enable=1; between_bounces=rawclock();}
  1611. }
  1612.  
  1613.  
  1614. void pause()
  1615. {
  1616.  int flag,i;
  1617.  flag=0;
  1618.  rectfill(screen,210,195,420,270,1);
  1619.  textout(screen,fontfile[LARGE].dat,"PAUSE",220,200,213);
  1620.  textout(screen,fontfile[LARGE].dat,"PAUSE",222,202,210);
  1621.  i=rawclock();
  1622.  while ((rawclock()-i)<8);
  1623.  readkey();
  1624.  while (flag==0){
  1625.    if(key[KEY_P]) flag=1;
  1626.  }
  1627. i=rawclock();
  1628.  while ((rawclock()-i)<6);
  1629. }
  1630.  
  1631.  
  1632.  
  1633.  
  1634. void main()
  1635. {
  1636. int ptr,exit_flag;
  1637.   /* you should always do this at the start of Allegro programs */
  1638.   allegro_init();
  1639.   /* set up the keyboard handler */
  1640.   install_keyboard();
  1641.   /* set VGA graphics mode 13h (sized 320x200) */
  1642.   set_gfx_mode(GFX_AUTODETECT, 640,480, 0, 0);
  1643.   /* install mouse driver */
  1644.   install_mouse();
  1645.   /* initialise joystick driver */
  1646.   initialise_joystick();
  1647.   /* install sound driver */
  1648.   install_sound(DIGI_AUTODETECT,MIDI_NONE,NULL);
  1649.  
  1650.   // Initalise program
  1651.   // load various bitmaps into memory
  1652.   load_bitmaps();
  1653.   load_samples();
  1654.  
  1655. while (TRUE==TRUE) {
  1656.   exit_flag=0;
  1657.  
  1658.   // Display startup screen
  1659.   initialise_variables();
  1660.   main_menu();
  1661.   next_level();
  1662.   // MAIN GAME LOOP
  1663.   while ((lives !=0)&&(exit_flag==0)) {
  1664.     load_data(level);
  1665.     initial_ball_position();
  1666.     new_level=0;
  1667.     while ((new_level==0) && (exit_flag==0) && (lives!=0)) {
  1668.         show_score();
  1669.         update_ball_position();
  1670.         update_bat_position();
  1671.         ball_collide_brick();
  1672.         explode_bricks();
  1673.         move_blocks();
  1674.         fire_laser();
  1675.         catch_ball();
  1676.         extras();
  1677.         fps();
  1678.         drawing_screen();
  1679.         copy_drawing();
  1680.         copy_backgrnd();
  1681.         ball_stuck();
  1682.         // Is the ball out of play (ie missed bat)
  1683.         if (ball_out==1) out_of_play();
  1684.         // allow frame skipping for some procedures
  1685.         // ie only call procedure when 'frame_skip equals a certain value
  1686.         {frame_skip ++; if (frame_skip==10) frame_skip=1;}
  1687.         // Space button or right mouse to exit
  1688.         if (key[KEY_F1]) save_pcx("scrnshot.pcx",screen,pallete1);
  1689.         if (key[KEY_P]) pause();
  1690.         if (key[KEY_0]) exit(0);
  1691.     }
  1692.     if (lives==0) {display_gameover();display_hiscore();}
  1693.     if ((exit_flag==0)&&(lives>0)) next_level();
  1694.   }
  1695. }
  1696. }
  1697.  
  1698.