home *** CD-ROM | disk | FTP | other *** search
/ messroms.de / 2007-01-13_www.messroms.de.zip / VZ200 / IMAGES / DEFENSE.ZIP / defense.c next >
C/C++ Source or Header  |  2000-03-13  |  25KB  |  1,174 lines

  1. #define ENEMY_MAX            8
  2. #define BOTTLE_MAX            16
  3. #define SHOT_MAX            8
  4. #define EXPLOSION_MAX        6
  5. #define EXPLOSION_PIECES    12
  6.  
  7. #define FLAGSHIP_APPEAR 100
  8. #define BONUSSHIP_AWARD 500
  9.  
  10. #define BOTTLE_Y        45
  11.  
  12. #define EN_FLAGSHIP     0
  13. #define EN_SLICER        6
  14.  
  15. #define SCRSIZE     0x600
  16.  
  17. char scr[32*64];
  18.  
  19. char *mem;
  20. char cntr;
  21. int sound1, sound2;
  22. int score, score0, score1, hiscore;
  23. int speed;
  24.  
  25. /* enemies current x,y (represented in 8.8 fractional integers) */
  26. int enemy_x[ENEMY_MAX];
  27. int enemy_y[ENEMY_MAX];
  28. /* enemies step x,y */
  29. int enemy_sx[ENEMY_MAX];
  30. int enemy_sy[ENEMY_MAX];
  31. char enemy_flag[ENEMY_MAX];
  32. char enemy_type[ENEMY_MAX];
  33. char enemy_bottle[ENEMY_MAX];
  34.  
  35. /* flag ship may occur? */
  36. char enemy_fship;
  37.  
  38. /* bottles current x,y (represented in 8.8 fractional integers) */
  39. char bottle_x[BOTTLE_MAX];
  40. char bottle_y[BOTTLE_MAX];
  41. char bottle_dy[BOTTLE_MAX];
  42. char bottle_flag[BOTTLE_MAX];
  43. #define BOTTLE_AVAIL    0x01
  44. #define BOTTLE_STOLEN    0x20
  45. #define BOTTLE_FALLING  0x40
  46. #define BOTTLE_STEAL    0x80
  47. char bottle_cnt;
  48. char bottle_live;
  49.  
  50. /* shots current x,y and color (colour = type) */
  51. char shot_x[SHOT_MAX];
  52. char shot_y[SHOT_MAX];
  53. char shot_c[SHOT_MAX];
  54. char enemy_shot_cnt;
  55. char ship_shot_cnt;
  56.  
  57. /* explosions current x,y and count (>0 is size) */
  58. char expl_x[EXPLOSION_MAX];
  59. char expl_y[EXPLOSION_MAX];
  60. char expl_cnt[EXPLOSION_MAX];
  61. char expl_max[EXPLOSION_MAX];
  62. char expl_pieces[EXPLOSION_MAX];
  63. int expl_dx[EXPLOSION_MAX*EXPLOSION_PIECES];
  64. int expl_dy[EXPLOSION_MAX*EXPLOSION_PIECES];
  65. int expl_sx[EXPLOSION_MAX*EXPLOSION_PIECES];
  66. int expl_sy[EXPLOSION_MAX*EXPLOSION_PIECES];
  67.  
  68. /* ship x,y coordinates */
  69. int ship_x, ship_y;
  70. char ship_explode, ships;
  71.  
  72. /* display scoring */
  73. char add_cnt;
  74.  
  75. /**************************************************************************
  76.  * Initialize variables
  77.  **************************************************************************/
  78. init_enemy()
  79. {
  80.     memset(enemy_flag, 0, sizeof(enemy_flag));
  81.     enemy_fship = 0;
  82. }
  83.  
  84. reinit_enemy()
  85. {
  86.     int i, b;
  87.     for (i = 0; i < ENEMY_MAX; i++)
  88.     {
  89.         b = enemy_bottle[i];
  90.         if (b >= 0)
  91.         {
  92.             /* put back the bottle to the floor */
  93.             bottle_y[b] = BOTTLE_Y;
  94.             bottle_flag[b] = BOTTLE_AVAIL;
  95.             bottle_cnt++;
  96.         }
  97.         /* enemy is dead */
  98.         enemy_flag[i] = 0;
  99.     }
  100. }
  101.  
  102. init_bottle()
  103. {
  104.     int i;
  105.     for (i = 0; i < BOTTLE_MAX; i++)
  106.     {
  107.         bottle_x[i] = i * 6 + 16;
  108.         bottle_y[i] = BOTTLE_Y;
  109.         bottle_flag[i] = BOTTLE_AVAIL;
  110.     }
  111.     bottle_cnt = BOTTLE_MAX;
  112.     bottle_live = BOTTLE_MAX;
  113. }
  114.  
  115. init_ship()
  116. {
  117.     ship_x = 64;
  118.     ship_y = BOTTLE_Y - 4;
  119.     ship_explode = 0;
  120. }
  121.  
  122. init_shot()
  123. {
  124.     memset(shot_c, 0, sizeof(shot_c));
  125.     ship_shot_cnt = 0;
  126. }
  127.  
  128. init_explosion()
  129. {
  130.     memset(expl_cnt, 0, sizeof(expl_cnt));
  131. }
  132.  
  133. /**************************************************************************
  134.  * Find specific slots
  135.  **************************************************************************/
  136. find_bottle()
  137. {
  138.     int i;
  139.     i = rand(BOTTLE_MAX);
  140.     if (bottle_flag[i] == BOTTLE_AVAIL)
  141.         return i;
  142.     for (i = BOTTLE_MAX; i > 0; --i)
  143.     {
  144.         if (bottle_flag[i] == BOTTLE_AVAIL)
  145.             return i;
  146.     }
  147.     return -1;
  148. }
  149.  
  150. find_shot()
  151. {
  152.     int i;
  153.     for (i = 0; i < SHOT_MAX; i++)
  154.     {
  155.         if (!shot_c[i])
  156.             return i;
  157.     }
  158.     return 0;
  159. }
  160.  
  161. find_explosion(x,y,p,n,m,sy)
  162. int x,y,p,n,m,sy;
  163. {
  164.     int i, j, k;
  165.     for (i = 0; i < EXPLOSION_MAX; i++)
  166.     {
  167.         if (expl_cnt[i] == 0)
  168.         {
  169.             expl_x[i] = x;
  170.             expl_y[i] = y;
  171.             expl_cnt[i] = 1;
  172.             expl_max[i] = n;
  173.             expl_pieces[i] = p;
  174.             for (j = 0; j < p; j++)
  175.             {
  176.                 k = i * EXPLOSION_PIECES + j;
  177.                 expl_dx[k] = 0;
  178.                 expl_dy[k] = 0;
  179.                 expl_sx[k] = (rand(256) - 128) * m;
  180.                 expl_sy[k] = (rand(256) - 128) * m + sy * 128;
  181.             }
  182.             return;
  183.         }
  184.     }
  185. }
  186.  
  187. hit_enemy(x,y)
  188. int x,y;
  189. {
  190.     int i, j, b, t;
  191.     x *= 256;
  192.     y *= 256;
  193.     for (i = 0; i < ENEMY_MAX; i++)
  194.     {
  195.         if (enemy_flag[i] == 0)
  196.             continue;
  197.         if (x > enemy_x[i] - 0x300 && x < enemy_x[i] + 0x300 &&
  198.             y > enemy_y[i] - 0x200 && y < enemy_y[i] + 0x200)
  199.         {
  200.             shape(enemy_x[i]/256-3,enemy_y[i]/256-1,7,3,0,"\xfe\xfe\xfe");
  201.             if (enemy_type[i] == EN_FLAGSHIP)
  202.             {
  203.                 t = rand(4);    /* sometimes let the slicers appear ;-) */
  204.                 for (j = 0; j < ENEMY_MAX; j++)
  205.                 {
  206.                     if (i == j || enemy_flag[j] || (rand()&1) != 0 )
  207.                         continue;
  208.                     enemy_x[j] = enemy_x[i] + rand(2048) - 1024;
  209.                     enemy_y[j] = y = enemy_y[i] + rand(1024);
  210.                     enemy_bottle[j] = -1;
  211.                     if (t == 0)
  212.                     {
  213.                         enemy_sx[j] = 0;
  214.                         enemy_sy[j] = 128;
  215.                         enemy_flag[j] = 3;
  216.                         enemy_type[j] = EN_SLICER;
  217.                     }
  218.                     else
  219.                     {
  220.                         x = (rand(112) + 8) * 256;
  221.                         enemy_sx[j] = (x - enemy_x[i]) / (48 - y/256);
  222.                         enemy_sy[j] = 128 + rand(128);
  223.                         enemy_flag[j] = 2;
  224.                         enemy_type[j] = rand(EN_SLICER-1) + 1;
  225.                     }
  226.                 }
  227.                 t = 12;
  228.             }
  229.             else
  230.             if (enemy_type[i] == EN_SLICER)
  231.             {
  232.                 t = 8;
  233.             }
  234.             else
  235.             {
  236.                 t = 5;
  237.                 b = enemy_bottle[i];
  238.                 if (b >= 0)
  239.                 {
  240.                     /* he looses the claim on the bottle now */
  241.                     bottle_flag[b] &= ~BOTTLE_STEAL;
  242.                     bottle_cnt++;
  243.                     /* did the enemy already go up? */
  244.                     if (bottle_flag[b] & BOTTLE_STOLEN)
  245.                     {
  246.                         bottle_flag[b] &= ~BOTTLE_STOLEN;
  247.                         /* the bottle starts falling now */
  248.                         bottle_flag[b] |= BOTTLE_FALLING;
  249.                         /* depth 0 */
  250.                         bottle_dy[b] = 0;
  251.                     }
  252.                 }
  253.             }
  254.             /* don't move the enemy anymore */
  255.             enemy_sx[i] = 0;
  256.             enemy_sy[i] = 0;
  257.             enemy_flag[i] = 0;
  258.             if (enemy_type[i] != EN_FLAGSHIP)
  259.                 find_explosion(enemy_x[i]/256,enemy_y[i]/256,EXPLOSION_PIECES/2,t,4,-1);
  260.             return t;
  261.         }
  262.     }
  263.     return 0;
  264. }
  265.  
  266. hit_ship(x,y)
  267. int x,y;
  268. {
  269.     if (ship_explode)
  270.         return 0;
  271.     if (x > ship_x - 4 && x < ship_x + 4 && y > ship_y - 1 && y < ship_y + 4)
  272.         return 1;
  273.     return 0;
  274. }
  275.  
  276. hit_bottle(x)
  277. int x;
  278. {
  279.     int i;
  280.     for (i = 0; i < BOTTLE_MAX; i++)
  281.     {
  282.         if ((bottle_flag[i] & BOTTLE_AVAIL) == 0)
  283.             continue;
  284.         if ((bottle_flag[i] & BOTTLE_FALLING) != 0)
  285.             continue;
  286.         if (x == bottle_x[i] && BOTTLE_Y == bottle_y[i])
  287.         {
  288.             /* the bottle is now broken... */
  289.             find_explosion(bottle_x[i],BOTTLE_Y,EXPLOSION_PIECES/2,10,3,-2);
  290.             bottle_flag[i] = 0;
  291.             bottle_live--;
  292.             bottle_cnt--;
  293.             sound2 = 200;
  294.             return 1;
  295.         }
  296.     }
  297.     return 0;
  298. }
  299.  
  300. /**************************************************************************
  301.  * Draw to screen (or screen buffer)
  302.  **************************************************************************/
  303. draw_string(x,y,color,src)
  304. int x,y,color;
  305. char *src;
  306. {
  307.     while (*src)
  308.     {
  309.         char_draw(x,y,color,*src);
  310.         x += 6;
  311.         src++;
  312.     }
  313. }
  314.  
  315. draw_enemy_type(x,y,color,type)
  316. int x,y,color,type;
  317. {
  318.     int c, s;
  319.     char *enmy;
  320.  
  321.     c = cntr & 3;
  322.     s = cntr & 7;
  323.     x -= 3;
  324.     y -= 1;
  325.     switch (type)
  326.     {
  327.     case 0:
  328.         /*
  329.          *     .xxxx.. .xxxx.. .xxxx.. .xxxx..
  330.          *     x...xx. xx...x. x.x..x. x..x.x.
  331.          *     .xxxx.. .xxxx.. .xxxx.. .xxxx..
  332.          */
  333.         switch (c)
  334.         {
  335.         case 0: shape(x,y,7,3,color,"\x78\x8c\x78"); break;
  336.         case 1: shape(x,y,7,3,color,"\x78\xc4\x78"); break;
  337.         case 2: shape(x,y,7,3,color,"\x78\xa4\x78"); break;
  338.         case 3: shape(x,y,7,3,color,"\x78\x94\x78"); break;
  339.         }
  340.         switch (s)
  341.         {
  342.         case 0: sound2 = 60; break;
  343.         case 1: sound1 = 62; break;
  344.         case 2: sound2 = 40; break;
  345.         case 3: sound1 =100; break;
  346.         case 4: sound2 = 20; break;
  347.         case 5: sound1 = 19; break;
  348.         case 6: sound2 = 40; break;
  349.         case 7: sound1 = 80; break;
  350.         }
  351.         break;
  352.     case 1:
  353.         /*
  354.          *    ..xxx.. ..xxx.. ..xxx.. ..xxx..
  355.          *    xx.x.xx xx.x.xx xx.x.xx xx.x.xx
  356.          *    x.xxx.x ..xxx.. x.xxx.x ..xxx..
  357.          */
  358.         switch (c)
  359.         {
  360.         case 0: shape(x,y,7,3,color,"\x38\xd6\xba"); break;
  361.         case 1: shape(x,y,7,3,color,"\x38\xd6\x38"); break;
  362.         case 2: shape(x,y,7,3,color,"\x38\xd6\xba"); break;
  363.         case 3: shape(x,y,7,3,color,"\x38\xd6\x38"); break;
  364.         }
  365.         break;
  366.     case 2:
  367.         /*
  368.          *    x.xxx.. ..xxx.. ..xxx.x ..xxx..
  369.          *    xxx.xxx xxx.xxx xxx.xxx xxx.xxx
  370.          *    ..xxx.x ..xxx.. x.xxx.. ..xxx..
  371.          */
  372.         switch (c)
  373.         {
  374.         case 0: shape(x,y,7,3,color,"\xb8\xee\x3a"); break;
  375.         case 1: shape(x,y,7,3,color,"\x38\xee\x38"); break;
  376.         case 2: shape(x,y,7,3,color,"\x3a\xee\xb8"); break;
  377.         case 3: shape(x,y,7,3,color,"\x38\xee\x38"); break;
  378.         }
  379.         break;
  380.     case 3:
  381.         /*
  382.          *    .xx.xx. ..x.x.. .xx.xx. ..x.x..
  383.          *    x..x..x .x.x.x. x..x..x .x.x.x.
  384.          *    .xx.xx. ..x.x.. .xx.xx. ..x.x..
  385.          */
  386.         switch (c)
  387.         {
  388.         case 0: shape(x,y,7,3,color,"\x6c\x92\x6c"); break;
  389.         case 1: shape(x,y,7,3,color,"\x28\x54\x28"); break;
  390.         case 2: shape(x,y,7,3,color,"\x6c\x92\x6c"); break;
  391.         case 3: shape(x,y,7,3,color,"\x28\x54\x28"); break;
  392.         }
  393.         break;
  394.     case 4:
  395.         /*
  396.          *    ..x.x.. .xx.xx. ..x.x.. .xx.xx.
  397.          *    .x.x.x. xx.x.xx .x.x.x. xx.x.xx
  398.          *    x..x..x x..x..x x..x..x x..x..x
  399.          */
  400.         switch (c)
  401.         {
  402.         case 0: shape(x,y,7,3,color,"\x28\x54\x92"); break;
  403.         case 1: shape(x,y,7,3,color,"\x6c\xd6\x92"); break;
  404.         case 2: shape(x,y,7,3,color,"\x28\x54\x92"); break;
  405.         case 3: shape(x,y,7,3,color,"\x6c\xd6\x92"); break;
  406.         }
  407.         break;
  408.     case 5:
  409.         /*
  410.          *    ..xxx.. x.xxx.x ..xxx.. x.xxx.x
  411.          *    .xx.xx. .xx.xx. .xx.xx. .xx.xx.
  412.          *    x.xxx.x ..xxx.. x.xxx.x ..xxx..
  413.          */
  414.         switch (c)
  415.         {
  416.         case 0: shape(x,y,7,3,color,"\x38\x6c\xba"); break;
  417.         case 1: shape(x,y,7,3,color,"\xba\x6c\x38"); break;
  418.         case 2: shape(x,y,7,3,color,"\x38\x6c\xba"); break;
  419.         case 3: shape(x,y,7,3,color,"\xba\x6c\x38"); break;
  420.         }
  421.         break;
  422.     case EN_SLICER:
  423.         /*
  424.          *    ...x... ....x.. ....... ..x....
  425.          *    ...x... ...x... .xxxxx. ...x...
  426.          *    ...x... ..x.... ....... ....x..
  427.          */
  428.         switch (c)
  429.         {
  430.         case 0: shape(x,y,7,3,color,"\x10\x10\x10"); break;
  431.         case 1: shape(x,y,7,3,color,"\x08\x10\x20"); break;
  432.         case 2: shape(x,y,7,3,color,"\x00\x7c\x00"); break;
  433.         case 3: shape(x,y,7,3,color,"\x20\x10\x08"); break;
  434.         }
  435.         switch (s)
  436.         {
  437.         case 0: sound1 = 20; break;
  438.         case 1: sound1 = 40; break;
  439.         case 2: sound2 = 21; break;
  440.         case 3: sound1 = 22; break;
  441.         case 5: sound1 = 23; break;
  442.         case 6: sound2 = 30; break;
  443.         }
  444.         break;
  445.     }
  446. }
  447.  
  448. clear_enemy()
  449. {
  450.     int i, x, y;
  451.  
  452.     for (i = 0; i < ENEMY_MAX; i++)
  453.     {
  454.         if (enemy_flag[i] == 0)
  455.             continue;
  456.         x = enemy_x[i] / 256;
  457.         y = enemy_y[i] / 256;
  458.         shape(x-3,y-1,7,3,0,"\xfe\xfe\xfe");
  459.         if (enemy_type[i] == EN_SLICER && y == (BOTTLE_Y + 1))
  460.         {
  461.             /* did the slicer hit a bottle? */
  462.             if (hit_bottle(x))
  463.                 enemy_flag[i] = 0;
  464.         }
  465.     }
  466. }
  467.  
  468. init_ship_explosion()
  469. {
  470.     find_explosion(ship_x,ship_y+3,EXPLOSION_PIECES,30,3,-4);
  471.     ship_explode = 1;
  472. }
  473.  
  474. draw_enemy()
  475. {
  476.     int i, b, j, x, y;
  477.  
  478.     for (i = 0; i < ENEMY_MAX; i++)
  479.     {
  480.         if (enemy_flag[i] == 0)
  481.         {
  482.             /* eventually create a new enemy */
  483.             if (rand(0x7fff) > 0x7fc0 - sqrt(score))
  484.             {
  485.                 /* start at a random x offset between 32...95 */
  486.                 enemy_x[i] = 256 * (rand(64) + 32);
  487.                 enemy_y[i] = 0;
  488.                 enemy_type[i] = rand(EN_SLICER-1) + 1;
  489.                 enemy_bottle[i] = -1;  /* no bottle */
  490.                 /* the fewer bottles left, the more likely slicers appear */
  491.                 if (rand(bottle_cnt*2) == 0)
  492.                     enemy_type[i] = EN_SLICER;
  493.  
  494.                 /* time for a flagship occurance? */
  495.                 if (enemy_fship)
  496.                 {
  497.                     enemy_x[i] = 0x0200;
  498.                     enemy_y[i] = 0x0c00;
  499.                     enemy_type[i] = EN_FLAGSHIP;
  500.                     enemy_sx[i] = 128;        /* move right */
  501.                     enemy_sy[i] = 0;        /* horizontally only */
  502.                     enemy_flag[i] = 2;        /* blue */
  503.                     enemy_fship = 0;
  504.                 }
  505.                 else
  506.                 if (enemy_type[i] == EN_SLICER)
  507.                 {
  508.                     enemy_sx[i] = 0;        /* don't move horizontally */
  509.                     enemy_sy[i] = 128;        /* half speed down */
  510.                     enemy_flag[i] = 3;        /* red */
  511.                 }
  512.                 else
  513.                 {
  514.                     int dy;
  515.                     dy = BOTTLE_Y - enemy_y[i] / 256;
  516.                     x = (rand(64) + 32) * 256;
  517.                     if (bottle_cnt > 0)
  518.                     {
  519.                         b = find_bottle();        /* find a target bottle */
  520.                         enemy_bottle[i] = b;    /* set target */
  521.                         if (b >= 0)
  522.                         {
  523.                             bottle_flag[b] |= BOTTLE_STEAL;
  524.                             bottle_cnt--;
  525.                             x = bottle_x[b] * 256;
  526.                             if (x > enemy_x[i])
  527.                                 x = enemy_x[i] + rand(x - enemy_x[i]);
  528.                             else
  529.                                 x = x + rand(enemy_x[i] - x);
  530.                             dy = bottle_y[b] - enemy_y[i] / 256;
  531.                         }
  532.                     }
  533.                     enemy_sx[i] = (x - enemy_x[i]) / dy;
  534.                     enemy_sy[i] = speed;
  535.                     enemy_flag[i] = 2;        /* blue */
  536.                 }
  537.             }
  538.             else
  539.                 continue;
  540.         }
  541.         enemy_x[i] += enemy_sx[i];
  542.         enemy_y[i] += enemy_sy[i];
  543.         x = enemy_x[i] / 256;
  544.         y = enemy_y[i] / 256;
  545.         b = enemy_bottle[i];
  546.  
  547.         if (hit_ship(x,y) || hit_ship(x-2,y) || hit_ship(x+2,y))
  548.         {
  549.  
  550.             enemy_flag[i] = 0;
  551.             init_ship_explosion();
  552.             continue;
  553.         }
  554.  
  555.         if (y < -4 || y >= 48)    /* off the screen? */
  556.         {
  557.             enemy_flag[i] = 0;    /* ship is gone now */
  558.             /* is the bottle gone too? */
  559.             if (b >= 0 && (bottle_flag[b] & BOTTLE_STOLEN) != 0)
  560.                 bottle_flag[b] = 0;
  561.             continue;
  562.         }
  563.  
  564.         if (enemy_type[i] == EN_FLAGSHIP && x > 123)
  565.         {
  566.             enemy_flag[i] = 0;    /* ship is gone now */
  567.             continue;
  568.         }
  569.  
  570.         draw_enemy_type(x,y,enemy_flag[i],enemy_type[i]);
  571.  
  572.         if (y == BOTTLE_Y/3)     /* upper third of the screen? */
  573.         {
  574.             if (enemy_shot_cnt < 5 && rand(256-speed) == 0)
  575.             {
  576.                 int s;
  577.  
  578.                 s = find_shot();
  579.                 shot_c[s] = 2;
  580.                 shot_x[s] = x;
  581.                 shot_y[s] = y+1;
  582.                 enemy_shot_cnt++;
  583.                 for (s = 10; s < 250; s += 40)
  584.                     sound(s,4);
  585.             }
  586.         }
  587.         else
  588.         if (y == BOTTLE_Y/2)     /* middle of the screen? */
  589.         {
  590.             /* got a bottle? */
  591.             if (b >= 0 && (bottle_flag[b] & BOTTLE_STOLEN) != 0)
  592.             {
  593.                 /* fly away vertically */
  594.                 enemy_sx[i] = 0;
  595.                 enemy_sy[i] = -speed;
  596.             }
  597.             else
  598.             if (bottle_flag[b] & BOTTLE_STEAL)     /* steal a bottle? */
  599.             {
  600.                 int bx, dx, dy;
  601.                 /* fly to target bottle */
  602.                 bx = bottle_x[b] * 256;
  603.                 if (bx > enemy_x[i])
  604.                 {
  605.                     dx = bx - enemy_x[i];
  606.                     dx = enemy_x[i] + dx*3/4 + rand(dx/4);
  607.                 }
  608.                 else
  609.                 {
  610.                     dx = enemy_x[i] - bx;
  611.                     dx = bx + rand(dx/4);
  612.                 }
  613.                 dy = BOTTLE_Y - enemy_y[i] / 256;
  614.                 enemy_sx[i] = (dx - enemy_x[i]) / dy;
  615.                 enemy_sy[i] = speed;
  616.             }
  617.         }
  618.         else
  619.         /* normal enemy reached the row above the bottles now? */
  620.         if (y == (BOTTLE_Y - 2) && b >= 0 && (bottle_flag[b] & BOTTLE_STEAL) != 0)
  621.         {
  622.             if (x == bottle_x[b])
  623.             {
  624.                 /* take it up or drop the bottle now */
  625.                 bottle_flag[b] ^= BOTTLE_STOLEN;
  626.                 j = 256 * (rand(64) + 32);
  627.                 enemy_sx[i] = (j - enemy_x[i]) / (BOTTLE_Y/2);
  628.                 enemy_sy[i] = -speed;
  629.             }
  630.             else
  631.             {
  632.                 int bx;
  633.                 bx = bottle_x[b] * 256;
  634.                 enemy_sx[i] = (bx - enemy_x[i]) / 128;
  635.                 if (bx < enemy_x[i])
  636.                     enemy_sx[i] -= 128;
  637.                 else
  638.                     enemy_sx[i] += 128;
  639.                 enemy_sy[i] = 0;
  640.             }
  641.         }
  642.         else
  643.         /* slicer reached the bottom row? */
  644.         if (y == (BOTTLE_Y + 1) && enemy_type[i] == EN_SLICER)
  645.         {
  646.             if (x < 1)
  647.                 enemy_sx[i] = speed;
  648.             else
  649.             if (x > 125)
  650.                 enemy_sx[i] = -speed;
  651.             else
  652.             {
  653.                 if (enemy_sx[i] == 0)
  654.                     enemy_sx[i] = rand(1) ? -speed : speed;
  655.                 enemy_sy[i] = 0;
  656.             }
  657.         }
  658.         if (bottle_flag[b] & BOTTLE_STOLEN)    /* bottle stolen? */
  659.         {
  660.             bottle_x[b] = x;        /* move bottle with */
  661.             bottle_y[b] = y + 2;    /* ship (below center) */
  662.         }
  663.     }
  664. }
  665.  
  666. clear_bottle()
  667. {
  668.     int i, x, y, s;
  669.  
  670.     for (i = 0; i < BOTTLE_MAX; i++)
  671.     {
  672.         if (bottle_flag[i] == 0)
  673.             continue;
  674.         x = bottle_x[i];
  675.         y = bottle_y[i];
  676.         shape(x-1,y,3,3,0,"\x40\xe0\xe0");
  677.         /* bottle falling? */
  678.         if (bottle_flag[i] & BOTTLE_FALLING)
  679.         {
  680.             bottle_y[i] += 1;
  681.             bottle_dy[i] += 1;    /* depth */
  682.             /* ship catched a falling bottle? */
  683.             if (bottle_dy[i] > 8 && hit_ship(x,y))
  684.             {
  685.                 bottle_y[i] = BOTTLE_Y;
  686.                 bottle_flag[i] &= ~BOTTLE_FALLING;
  687.                 draw_score(25);
  688.                 for (s = 10; s < 120; s += 10)
  689.                     sound(s,5);
  690.             }
  691.             else
  692.             if (bottle_y[i] >= BOTTLE_Y)
  693.             {
  694.                 bottle_y[i] = BOTTLE_Y;
  695.                 bottle_flag[i] &= ~BOTTLE_FALLING;
  696.                 /* bottle fell too fast? darn.. smash it.. */
  697.                 if (bottle_dy[i] > 8)
  698.                 {
  699.                     find_explosion(bottle_x[i],BOTTLE_Y,EXPLOSION_PIECES/2,10,2,-3);
  700.                     bottle_flag[i] = 0;
  701.                     bottle_cnt--;
  702.                     bottle_live--;
  703.                     sound2 = 10;
  704.                     continue;
  705.                 }
  706.             }
  707.         }
  708.     }
  709. }
  710.  
  711. draw_bottle()
  712. {
  713.     int i;
  714.  
  715.     for (i = 0; i < BOTTLE_MAX; i++)
  716.     {
  717.         /* bottle is gone? */
  718.         if (bottle_flag[i] == 0)
  719.             continue;
  720.         shape(bottle_x[i]-1,bottle_y[i],3,3,1,"\x40\xe0\xe0");
  721.         plot(bottle_x[i],bottle_y[i]+2,cntr&3);
  722.     }
  723. }
  724.  
  725. clear_ship()
  726. {
  727.     shape(ship_x-3,ship_y,7,4,0,"\xfe\xfe\xfe\xfe");
  728. }
  729.  
  730. draw_ship()
  731. {
  732.     static int dir, shot;
  733.  
  734.     if (ship_explode)
  735.         return;
  736.  
  737.     if ((mem[0x68ef] & 0x20) == 0)  /* left (M) ? */
  738.     {
  739.         dir = (dir > 0) ? 0 : dir - 1;
  740.         if (ship_x > 3)
  741.             ship_x--;
  742.         if (dir < -2 && ship_x > 3)
  743.             ship_x--;
  744.         if (dir < -7 && ship_x > 3)
  745.             ship_x--;
  746.     }
  747.     else
  748.     if( dir < 0 )
  749.         dir = 0;
  750.     if ((mem[0x68ef] & 0x08) == 0)    /* right (,) ? */
  751.     {
  752.         dir = (dir < 0) ? 0 : dir + 1;
  753.         if (ship_x < 124)
  754.             ship_x++;
  755.         if (dir > +2 && ship_x < 124)
  756.             ship_x++;
  757.         if (dir > +7 && ship_x < 124)
  758.             ship_x++;
  759.     }
  760.     else
  761.     if( dir > 0 )
  762.         dir = 0;
  763.     if ((mem[0x68fb] & 0x04) == 0)    /* shoot (CTRL) ? */
  764.     {
  765.         if (!shot && ship_shot_cnt < 3)
  766.         {
  767.             int s;
  768.  
  769.             shot = 1;
  770.             s = find_shot();
  771.             shot_c[s] = 3;
  772.             ship_shot_cnt++;
  773.             shot_x[s] = ship_x;
  774.             shot_y[s] = ship_y;
  775.             for (s = 1; s < 512; s <<= 1)
  776.                 sound(s,3);
  777.         }
  778.     }
  779.     else
  780.         shot = 0;
  781.     /*    ...x...
  782.      *    ..xxx..
  783.      *    .xxxxx.
  784.      *    xxx.xxx
  785.      */
  786.     shape(ship_x-3,ship_y,7,4,2,"\x10\x38\x7c\xee");
  787.     if (ship_shot_cnt < 3)
  788.         plot(ship_x,ship_y,3);
  789. }
  790.  
  791. clear_shot()
  792. {
  793.     int i,x,y;
  794.     for (i = 0; i < SHOT_MAX; i++)
  795.     {
  796.         if (!shot_c[i])
  797.             continue;
  798.         x = shot_x[i];
  799.         y = shot_y[i];
  800.         plot(x,y,0);
  801.         plot(x,y+1,0);
  802.         plot(x,y+2,0);
  803.     }
  804. }
  805.  
  806. draw_shot()
  807. {
  808.     int i, x, y, t;
  809.  
  810.     for (i = 0; i < SHOT_MAX; i++)
  811.     {
  812.         x = shot_x[i];
  813.         y = shot_y[i];
  814.         if (shot_c[i] == 2) /* enemy drop bombs */
  815.         {
  816.             if ((y += 2) >= BOTTLE_Y)
  817.             {
  818.                 shot_c[i] = 0;
  819.             }
  820.             else
  821.             {
  822.                 if (!ship_explode && hit_ship(x,y))
  823.                 {
  824.                     shot_c[i] = 0;
  825.                     enemy_shot_cnt--;
  826.                     init_ship_explosion();
  827.                 }
  828.                 else
  829.                 {
  830.                     shot_y[i] = y;
  831.                     plot(x,y,2);
  832.                     plot(x,y+1,2);
  833.                 }
  834.             }
  835.         }
  836.         else
  837.         if (shot_c[i] == 3) /* ship shots */
  838.         {
  839.             if ((y -= 3) < 0)
  840.             {
  841.                 shot_c[i] = 0;
  842.                 ship_shot_cnt--;
  843.             }
  844.             else
  845.             {
  846.                 t = hit_enemy(x,y);
  847.                 if (t == 0) t = hit_enemy(x,y+1);
  848.                 if (t == 0) t = hit_enemy(x,y+2);
  849.                 if (t)
  850.                 {
  851.                     shot_c[i] = 0;
  852.                     ship_shot_cnt--;
  853.                     draw_score(t);
  854.                 }
  855.                 else
  856.                 {
  857.                     shot_y[i] = y;
  858.                     plot(x,y,3);
  859.                     plot(x,y+1,3);
  860.                     plot(x,y+2,3);
  861.                 }
  862.             }
  863.         }
  864.     }
  865. }
  866.  
  867. clear_explosion()
  868. {
  869.     int i, j, k, x, y, c;
  870.     for (i = 0; i < EXPLOSION_MAX; i++)
  871.     {
  872.         c = expl_cnt[i];
  873.         if (!c)
  874.             continue;
  875.         expl_cnt[i] = c + 1;
  876.         x = expl_x[i];
  877.         y = expl_y[i];
  878.         for (j = 0; j < expl_pieces[i]; j++)
  879.         {
  880.             k = i * EXPLOSION_PIECES + j;
  881.             plot(x+expl_dx[k]/256,y+expl_dy[k]/256,0);
  882.             if (y+expl_dy[k]/256 >= 47)
  883.                 expl_sy[k] = -expl_sy[k];
  884.             expl_dx[k] += expl_sx[k];
  885.             expl_dy[k] += expl_sy[k];
  886.             if (expl_sy[k] < 0)
  887.                 expl_sy[k] /= 2;
  888.             expl_sy[k] += 32;
  889.         }
  890.     }
  891. }
  892.  
  893. draw_explosion()
  894. {
  895.     int i, j, k, x, y, c;
  896.     for (i = 0; i < EXPLOSION_MAX; i++)
  897.     {
  898.         c = expl_cnt[i];
  899.         if (c == 0)
  900.             continue;
  901.         if (c > expl_max[i])
  902.         {
  903.             expl_cnt[i] = 0;
  904.             continue;
  905.         }
  906.         sound2 = c * 8;
  907.         x = expl_x[i];
  908.         y = expl_y[i];
  909.         for (j = 0; j < expl_pieces[i]; j++)
  910.         {
  911.             k = i * EXPLOSION_PIECES + j;
  912.             plot(x+expl_dx[k]/256,y+expl_dy[k]/256,(j&2)|1);
  913.         }
  914.     }
  915. }
  916.  
  917. clear_score_add()
  918. {
  919.     int i;
  920.     if (--add_cnt == 0)
  921.     {
  922.         setbase(0x7000);
  923.         char_draw(76+5*6, 52, 0, '0');
  924.         for (i = 4; i >= 0; i--)
  925.             char_draw(76+i*6, 52, 0, 0x7f);  /* erase character */
  926.         setbase(scr);
  927.     }
  928. }
  929.  
  930. draw_hiscore()
  931. {
  932.     int i, n;
  933.     n = hiscore;
  934.     setbase(0x7000);
  935.     char_draw(2+5*6, 58, 3, '0');
  936.     for (i = 4; n > 0 && i >= 0; i--)
  937.     {
  938.         char_draw(2+i*6, 58, 0, 0x7f);    /* erase character */
  939.         char_draw(2+i*6, 58, 3, 0x30 + (n % 10));
  940.         n = n / 10;
  941.     }
  942.     setbase(scr);
  943. }
  944.  
  945. draw_score(add)
  946. int add;
  947. {
  948.     int i, n;
  949.     score += add;
  950.     n = score;
  951.  
  952.     if (score >= score0)
  953.     {
  954.         score0 += FLAGSHIP_APPEAR;
  955.         enemy_fship = 1;
  956.     }
  957.     if (score >= score1)
  958.     {
  959.         score1 += BONUSSHIP_AWARD;
  960.         ships++;
  961.         draw_ships();
  962.     }
  963.     if (score > hiscore)
  964.     {
  965.         hiscore = score;
  966.         draw_hiscore();
  967.     }
  968.     setbase(0x7000);
  969.     char_draw(2+5*6, 52, 3, '0');
  970.     for (i = 4; n > 0 && i >= 0; i--)
  971.     {
  972.         char_draw(2+i*6, 52, 0, 0x7f);    /* erase character */
  973.         char_draw(2+i*6, 52, 3, 0x30 + (n % 10));
  974.         n = n / 10;
  975.     }
  976.     if (add > 0)
  977.     {
  978.         n = add;
  979.         char_draw(76+5*6, 52, 2, '0');
  980.         for (i = 4; n > 0 && i >= 0; i--)
  981.         {
  982.             char_draw(76+i*6, 52, 0, 0x7f);  /* erase character */
  983.             char_draw(76+i*6, 52, 2, 0x30 + (n % 10));
  984.             n = n / 10;
  985.         }
  986.         add_cnt = 5;
  987.     }
  988.     setbase(scr);
  989. }
  990.  
  991. draw_ships()
  992. {
  993.     int i;
  994.     setbase(0x7000);
  995.     for (i = 0; i < 7; i++)
  996.         char_draw(44+i*6, 52, (i < ships) ? 2 : 0, 0x5e);
  997.     setbase(scr);
  998. }
  999.  
  1000. update_once(enemies)
  1001. int enemies;
  1002. {
  1003.     cntr++;
  1004.     if (cntr == 0 && speed < 256)
  1005.         speed++;
  1006.     setbase(scr);
  1007.     /* remove sprites from screen buffer */
  1008.     if (enemies)
  1009.         clear_enemy();
  1010.     clear_bottle();
  1011.     clear_ship();
  1012.     clear_shot();
  1013.     clear_explosion();
  1014.     /* draw sprites to screen buffer */
  1015.     if (enemies)
  1016.         draw_enemy();    /* move and draw enemies */
  1017.     draw_bottle();        /* move and draw bottles */
  1018.     draw_ship();        /* move and draw ship */
  1019.     draw_shot();        /* move and draw shots */
  1020.     draw_explosion();
  1021.     if (add_cnt > 0)
  1022.         clear_score_add();
  1023.     setbase(0x7000);
  1024.     soundcopy(0x7000,scr,SCRSIZE,sound1,sound2);
  1025.     sound1 = 0;
  1026.     sound2 = 0;
  1027. }
  1028.  
  1029. greeting()
  1030. {
  1031.     int y;
  1032.     setbase(scr);
  1033.     memset(scr,0x00,SCRSIZE);
  1034.     if (cntr < 66)
  1035.         y = 48 - cntr;
  1036.     else
  1037.         y = -18;
  1038.     draw_string(2, y+ 0, 2, " Juergen Buchmueller ");
  1039.     draw_string(2, y+ 6, 2, "  proudly presents:  ");
  1040.     draw_string(2, y+12, 2, "    THE RETURN OF    ");
  1041.     draw_string(2, y+18, (cntr&2)|1, "-* DEFENSE COMMAND *-");
  1042.     if( cntr < 0 || cntr >= 96)
  1043.     {
  1044.         if (cntr < 0)
  1045.         {
  1046.             cntr++;
  1047.             draw_string(38, 32, 3, "Game Over");
  1048.         }
  1049.         else
  1050.             draw_string(8, 32, 2, "Press 'S' to start!");
  1051.         setbase(0x7000);
  1052.         soundcopy(0x7000,scr,SCRSIZE,sound1,sound2);
  1053.     }
  1054.     else
  1055.     if (cntr < 48)
  1056.     {
  1057.         cntr++;
  1058.         sound1 = 7 + rand(12);
  1059.         sound1 *= sound1;
  1060.         if (y & 1)
  1061.             sound2 = 100;
  1062.         setbase(0x7000);
  1063.         soundcopy(0x7000,scr,SCRSIZE,sound1,sound2);
  1064.         sound1 = 0;
  1065.         sound2 = 0;
  1066.     }
  1067.     else
  1068.     if (cntr < 66)
  1069.     {
  1070.         setbase(0x7000);
  1071.         soundcopy(0x7000,scr,SCRSIZE,sound1,sound2);
  1072.         cntr++;
  1073.     }
  1074.     else
  1075.     if (cntr < 96)
  1076.     {
  1077.         if (!(cntr & 2))
  1078.             draw_string(8, 32, 2, "Press 'S' to start!");
  1079.         setbase(0x7000);
  1080.         soundcopy(0x7000,scr,SCRSIZE,sound1,sound2);
  1081.         cntr++;
  1082.     }
  1083. }
  1084.  
  1085. /**************************************************************************
  1086.  * The main loop
  1087.  **************************************************************************/
  1088. main(ac,av)
  1089. int ac;
  1090. char *av;
  1091. {
  1092.     int i;
  1093.  
  1094.     mem = 0;
  1095.     srand(0);
  1096.  
  1097.     hiscore = 1000;
  1098.  
  1099.     mode(1);
  1100.     setbase(0x7000);
  1101.  
  1102.     line(  0,48,127,48,2);
  1103.     line(  0,49,127,49,3);
  1104.     line(  0,50,127,50,1);
  1105.  
  1106.     speed = 196;
  1107.  
  1108.     asm("di\n");
  1109.     cntr = 0;
  1110.     for (;;)
  1111.     {
  1112.         do
  1113.         {
  1114.             greeting();
  1115.         } while (inch() != 'S');
  1116.  
  1117.         memset(scr,0x00,SCRSIZE);
  1118.         init_enemy();
  1119.         init_bottle();
  1120.         init_ship();
  1121.         init_shot();
  1122.         init_explosion();
  1123.         score = 0;
  1124.         score0 = FLAGSHIP_APPEAR;
  1125.         score1 = BONUSSHIP_AWARD;
  1126.         ships = 3;
  1127.  
  1128.         while (ships > 0)
  1129.         {
  1130.             draw_hiscore();
  1131.             draw_score(0);
  1132.             draw_ships();
  1133.             do
  1134.             {
  1135.                 update_once(1);
  1136.                 if (inch() == 3)
  1137.                 {
  1138.                     ships = 0;
  1139.                     break;
  1140.                 }
  1141.                 if (bottle_live == 0)
  1142.                 {
  1143.                     ships = 0;
  1144.                     ship_explode = 1;
  1145.                 }
  1146.             } while (!ship_explode);
  1147.             if (ship_explode)
  1148.             {
  1149.                 ships -= 1;
  1150.                 draw_ships();
  1151.                 /* let the ship explosion happen */
  1152.                 for (i = 0; i < 30; i++)
  1153.                 {
  1154.                     if (ships == 0)
  1155.                         draw_string(38, 32, 3, "Game Over");
  1156.                     update_once(1);
  1157.                 }
  1158.                 if (ships > 0)
  1159.                 {
  1160.                     setbase(scr);
  1161.                     clear_bottle();
  1162.                     clear_enemy();
  1163.                     reinit_enemy();
  1164.                     /* update another 30 frames */
  1165.                     for (i = 0; i < 30; i++)
  1166.                         update_once(0);
  1167.                 }
  1168.                 init_ship();
  1169.             }
  1170.         }
  1171.         cntr = -128;
  1172.     }
  1173. }
  1174.