home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / apilot.lha / APilot / APilot_Ser / ships.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-03  |  11.5 KB  |  424 lines

  1. /****************************************************************************
  2.  *
  3.  * Ships.c -- Functions used for calculations and displaying of ships.
  4.  *
  5.  *-------------------------------------------------------------------------
  6.  * Authors: Casper Gripenberg  (casper@alpha.hut.fi)
  7.  *          Kjetil Jacobsen  (kjetilja@stud.cs.uit.no)
  8.  *
  9.  */
  10.  
  11. #include <stdlib.h>
  12. #include <math.h>
  13. #include <exec/types.h>             /* The Amiga data types file.         */
  14. #include <libraries/dos.h>          /* Official return codes defined here */
  15.  
  16. #include <proto/intuition.h>
  17. #include <proto/graphics.h>
  18.  
  19. #include "main_protos.h"
  20. #include "points_protos.h"
  21. #include "ships_protos.h"
  22. #include "lists_protos.h"
  23. #include "fuelpod_protos.h"
  24.  
  25. #include "common.h"
  26. #include "defs.h"
  27. #include "map.h"
  28. #include "prefs.h"
  29. #include "ships.h"
  30.  
  31. /*---------------------------------------------------------------------------*/
  32.  
  33. extern int sina[];
  34. extern int cosa[];
  35.  
  36. extern AWorld World;
  37.  
  38. struct Coordinates triangle[] = {
  39.   { 0,-11},
  40.   { 7,  7},
  41.   {-7,  7},
  42.   {0, -11}
  43. };
  44.  
  45. /*---------------------------------------------------------------------------*/
  46.  
  47. /*
  48.  * init_ship -- Inizialize ship parameterers. (May be changed to accept
  49.  *              parameters as function arguments later...)
  50.  *
  51.  */
  52.  
  53. void
  54. init_ship( AShip *aShip )
  55. {
  56.   int i, j;
  57.   ABase *shipbase;
  58.  
  59.   shipbase = get_base(aShip);
  60.   /*
  61.    * Should be made to handle out-of-bases situations more gracefully
  62.    * in the future.
  63.    */ 
  64.   if (shipbase == NULL)
  65.     cleanExit( RETURN_WARN, "** Out of bases for new ship." );
  66.  
  67.   shipbase->owner = aShip;
  68.   aShip->base.x = shipbase->mapos.x * MAP_BLOCKSIZE + MAP_BLOCKSIZE/2;
  69.   aShip->base.y = shipbase->mapos.y * MAP_BLOCKSIZE + MAP_BLOCKSIZE/2;
  70.  
  71.   aShip->shape     = triangle;  
  72.   aShip->shapesize = sizeof(triangle)/sizeof(struct Coordinates);
  73.   aShip->mass      = SHP_MASS;
  74.   aShip->draw_it   = FALSE;
  75.   aShip->fueling   = FALSE;
  76.   aShip->fuel      = MAXFUEL/5;
  77.   aShip->fuelcount = 0;
  78.  
  79.   for (i = 0; i < MY_BUFFERS; i++) {
  80.     aShip->s_drawn[i] = FALSE;
  81.     aShip->f_drawn[i] = FALSE;
  82.   }
  83.  
  84.   aShip->pos.x     = aShip->base.x;
  85.   aShip->pos.y     = aShip->base.y;
  86.   aShip->xvel      = aShip->yvel   = 0;
  87.   aShip->xcount    = aShip->ycount = 0;
  88.   aShip->status    = 0;
  89.   aShip->shields   = TRUE;
  90.   aShip->power     = THR_POWER * PRECS;
  91.   aShip->exhcount  = EXH_COUNT; 
  92.   aShip->exhwidth  = EXH_WIDTH;
  93.   aShip->exhdist   = EXH_DIST;
  94.   aShip->exhlife   = 25;   /* 50 = one second on 50fps */
  95.   aShip->rotspeed  = ROT_SPEED;
  96.   aShip->angle     = 0;
  97.   aShip->local     = TRUE;
  98.   aShip->fireing   = FALSE;
  99.   aShip->buldist   = BUL_DIST;
  100.   aShip->bul_life  = BUL_LIFE;
  101.   aShip->fw_nbul   = 3;
  102.   aShip->bw_nbul   = 1;
  103.   aShip->thrusting = FALSE;
  104.  
  105.   aShip->currc     = (struct Coordinates *) 
  106.                       malloc( aShip->shapesize * sizeof(struct Coordinates) );
  107.   if (aShip->currc == NULL)
  108.     cleanExit( RETURN_WARN, "** Unable to allocate space for ship structure.\n" );
  109.  
  110.   aShip->prevc     = (struct Coordinates **)
  111.                       malloc( MY_BUFFERS * sizeof(struct Coordinates) );
  112.   if (aShip->prevc == NULL)
  113.     cleanExit( RETURN_WARN, "** Unable to allocate space for ship structure.\n" );
  114.  
  115.   for (i = 0; i < MY_BUFFERS; i++) {
  116.     if ( (aShip->prevc[i] = 
  117.           (struct Coordinates *)
  118.            malloc( aShip->shapesize * sizeof(struct Coordinates) )) == NULL )
  119.       cleanExit( RETURN_WARN, "** Unable to allocate space for ship structure.\n" );
  120.   }     
  121.  
  122.   /* Copy the shape into current coordinates */
  123.   for(i = 0; i < aShip->shapesize; i++) {
  124.     aShip->currc[i].x = aShip->shape[i].x;
  125.     aShip->currc[i].y = aShip->shape[i].y;
  126.   }
  127.   for(i = 0; i < MY_BUFFERS; i++) {
  128.     aShip->p_pos[i].x = aShip->p_pos[i].y = 0;
  129.     for(j = 0; j < aShip->shapesize; j++) {
  130.       aShip->prevc[i][j].x = aShip->shape[j].x;
  131.       aShip->prevc[i][j].y = aShip->shape[j].y;
  132.     }
  133.   }
  134.  
  135. }
  136.  
  137. /*---------------------------------------------------------------------------*/
  138.  
  139. /*
  140.  * landing -- Returns TRUE if the ship is in a landing configuration,
  141.  *            ie. nose up, slow speed.
  142.  *
  143.  */
  144. BOOL
  145. landing( AShip *ship )
  146. {
  147.   if (ship->angle < 15 || ship->angle > 345)
  148.     if (ship->yvel <= PRECS && ship->yvel >= 0)
  149.       return TRUE;
  150.  
  151.   return FALSE;
  152. }
  153.  
  154. /*---------------------------------------------------------------------------*/
  155.  
  156. /*
  157.  * update_ship -- Updates the ship position, angle, fireing and exhaust. Checks
  158.  *                for ship out of window range etc. etc..
  159.  */
  160. void
  161. update_ship( AShip *aShip, UWORD buf, UWORD nframes )
  162. {
  163.   int i;
  164.   int isin, icos;
  165.  
  166.   /*
  167.    * Check if ship exploded 
  168.    */
  169.   if (aShip->status > 0)
  170.     return;
  171.  
  172.   if (aShip->turning != NO || aShip->thrusting || aShip->fireing) {
  173.  
  174.     if (aShip->turning == RIGHT) {
  175.       aShip->angle = (aShip->angle + aShip->rotspeed * nframes) % 360;
  176.     } else if (aShip->turning == LEFT) {
  177.       aShip->angle = (aShip->angle - aShip->rotspeed * nframes) % 360;
  178.      }
  179.  
  180.     if (aShip->angle < 0)
  181.       aShip->angle = 360 + aShip->angle;
  182.  
  183.     isin = sina[aShip->angle];
  184.     icos = cosa[aShip->angle];
  185.  
  186.     if (aShip->turning != NO) {
  187.       if (aShip->turning == YES) aShip->turning = NO;
  188.       /* Rotate the points */
  189.       for(i = 0; i < aShip->shapesize; i++) {
  190.         aShip->currc[i].x = (aShip->shape[i].x * icos - aShip->shape[i].y * isin) >> SHFTPR;
  191.         aShip->currc[i].y = (aShip->shape[i].x * isin + aShip->shape[i].y * icos) >> SHFTPR;
  192.       }
  193.     }
  194.   }
  195.  
  196.   for (i = nframes; i > 0; i--) {
  197.     if (aShip->thrusting && aShip->fuel > 0) {
  198.       aShip->xvel += (isin * aShip->power) >> SHFTPR;
  199.       aShip->yvel -= (icos * aShip->power) >> SHFTPR;
  200.     }
  201.     aShip->yvel += World.gravity;
  202.     aShip->xcount += aShip->xvel;
  203.     aShip->ycount += aShip->yvel;
  204.   }
  205.  
  206.   /* Move ship */
  207.   aShip->pos.x  += (aShip->xcount < 0) ? -((-aShip->xcount) >> SHFTPR) : (aShip->xcount >> SHFTPR);
  208.   aShip->xcount  = aShip->xcount % PRECS;
  209.   aShip->pos.y  += (aShip->ycount < 0) ? -((-aShip->ycount) >> SHFTPR) : (aShip->ycount >> SHFTPR);
  210.   aShip->ycount  = aShip->ycount % PRECS;
  211.  
  212.   if (aShip->thrusting && aShip->fuel > 0) {
  213.     add_exhaust(aShip, isin, icos, nframes);
  214.     aShip->fuelcount += (nframes << 1);
  215.   }
  216.  
  217.   if (aShip->fireing) {
  218.     aShip->fireing = FALSE;
  219.     if (!aShip->shields && aShip->fuel > 0) {
  220.       /* Every bullet grabs one fuel */
  221.       aShip->fuel -= aShip->fw_nbul + aShip->bw_nbul;
  222.       add_bullets(aShip, isin, icos);
  223.     }
  224.   }
  225.  
  226.   if (aShip->shields)
  227.     aShip->fuelcount += nframes;
  228.   if (aShip->fuelcount >= 50) {
  229.     aShip->fuelcount = 0;
  230.     aShip->fuel--;
  231.   }
  232.   if (aShip->fuel <= 0) {
  233.     aShip->shields = FALSE;
  234.     aShip->fuel = 0;
  235.   }
  236.  
  237.   if (aShip->fueling)
  238.     fuel_ship(aShip);
  239.  
  240.   if (aShip->pos.x >= MAP_BLOCKSIZE*World.Width) {
  241.     aShip->pos.x = MAP_BLOCKSIZE*World.Width-1;
  242.     aShip->xvel  = -(aShip->xvel >> 1);
  243.   } else if (aShip->pos.x < 0) {
  244.     aShip->pos.x = 0;
  245.     aShip->xvel  = -(aShip->xvel >> 1);
  246.   }
  247.   if (aShip->pos.y >= MAP_BLOCKSIZE*World.Height) {
  248.     aShip->pos.y = MAP_BLOCKSIZE*World.Height-1;
  249.     aShip->yvel  = -(aShip->yvel >> 1);
  250.   } else if (aShip->pos.y < 0) {
  251.     aShip->pos.y = 0;
  252.     aShip->yvel  = -(aShip->yvel >> 1);
  253.   }
  254. }
  255.  
  256. /*---------------------------------------------------------------------------*/
  257.  
  258. /*
  259.  * draw_ship.c -- Draws a ship on the display
  260.  *
  261.  */
  262. void
  263. draw_ship( AShip *aShip, struct RastPort *rp, UWORD buf )
  264. {
  265.   static int animno = 0;   /* Need this for shield animation */
  266.  
  267.   int bp_x, bp_y, i;
  268.   int pos_x, pos_y;
  269.   struct Coordinates *prevc;
  270.   struct Coordinates *currc;
  271.  
  272.   prevc = aShip->prevc[buf];
  273.   currc = aShip->currc;
  274.  
  275.   SetWriteMask(rp, 3l);
  276.   SetAPen(rp, 0);
  277.  
  278.   /* Remove ship */
  279.   if (aShip->local) {
  280.     Move(rp, LOCL_X+prevc[0].x, LOCL_Y+prevc[0].y);
  281.     for (i = 1; i < aShip->shapesize; i++) {
  282.       Draw(rp, LOCL_X+prevc[i].x, LOCL_Y+prevc[i].y);
  283.       /* Store new coordinates */
  284.       prevc[i].x = currc[i].x;
  285.       prevc[i].y = currc[i].y;
  286.     }
  287.     prevc[0].x = currc[0].x;
  288.     prevc[0].y = currc[0].y;
  289.    
  290.     /*
  291.      * Remove shield image...
  292.      */
  293.     if (aShip->sh_drawn[buf]) {
  294.       BltBitMap(World.shld_bm, (SHL_SIZE*2+1)*(SHL_ANIM-1), 0, rp->BitMap, 
  295.                 LOCL_X-SHL_SIZE, LOCL_Y-SHL_SIZE,
  296.                 SHL_SIZE*2+1, SHL_SIZE*2+1, 0x22, 0x03, NULL);
  297.     }
  298.     aShip->sh_drawn[buf] = FALSE;
  299.     
  300.     /*
  301.      * This removes the fuelline...
  302.      */
  303.     if (aShip->f_drawn[buf]) {
  304.       aShip->f_drawn[buf] = FALSE;  
  305.       Move(rp, LOCL_X, LOCL_Y);
  306.       Draw(rp, aShip->fuell[buf].x, aShip->fuell[buf].y);
  307.     }
  308.   } else { 
  309.     if (aShip->s_drawn[buf]) {
  310.       pos_x = aShip->p_pos[buf].x;
  311.       pos_y = aShip->p_pos[buf].y;
  312.       
  313.       if (aShip->sh_drawn[buf]) {
  314.         BltBitMap(World.shld_bm, (SHL_SIZE*2+1)*(SHL_ANIM-1), 0, rp->BitMap, 
  315.                   pos_x-SHL_SIZE, pos_y-SHL_SIZE,
  316.                   SHL_SIZE*2+1, SHL_SIZE*2+1, 0x22, 0x03, NULL);
  317.       }
  318.       aShip->sh_drawn[buf] = FALSE;
  319.  
  320.       Move(rp, pos_x+prevc[0].x, pos_y+prevc[0].y);
  321.       for (i = 1; i < aShip->shapesize; i++) {
  322.         Draw(rp, pos_x+prevc[i].x, pos_y+prevc[i].y);
  323.       }
  324.  
  325.       aShip->s_drawn[buf] = FALSE;
  326.     }      
  327.   }
  328.  
  329.   /*
  330.    * Check if our ship is dead
  331.    */
  332.   if (aShip->status > 0) {
  333.     aShip->status -= (World.framerate * 2);
  334.     if (aShip->status <= 0) {
  335.       /*
  336.        * Been dead long enough, restore default values...
  337.        */
  338.       if (aShip->local)
  339.         World.hudon = TRUE;
  340.       aShip->fuel    = MAXFUEL/5;
  341.       aShip->fueling = FALSE;
  342.       aShip->fpod    = NULL;
  343.       aShip->shields = TRUE;
  344.       aShip->angle   = 0;
  345.       aShip->turning = YES;
  346.       aShip->pos.x = aShip->base.x;
  347.       aShip->pos.y = aShip->base.y;
  348.       aShip->xvel = aShip->xcount = 0;
  349.       aShip->yvel = aShip->ycount = 0;
  350.     }
  351.     return;
  352.   }
  353.  
  354.   SetAPen(rp, 3);
  355.  
  356.   /* 
  357.    *  Draw ship..
  358.    */
  359.   if (aShip->local) {
  360.  
  361.    /* 
  362.     * Animate the shield...
  363.     */
  364.     animno += World.framerate; 
  365.     if (animno >= SHL_ANIM-1)
  366.       animno -= SHL_ANIM-1;
  367.  
  368.     if (aShip->shields) {
  369.       BltBitMap(World.shld_bm, (SHL_SIZE*2+1)*animno, 0, rp->BitMap, 
  370.                 LOCL_X-SHL_SIZE, LOCL_Y-SHL_SIZE,
  371.                 SHL_SIZE*2+1, SHL_SIZE*2+1, 0xEE, 0x03, NULL);
  372.       aShip->sh_drawn[buf] = TRUE;
  373.     }
  374.  
  375.     if (aShip->fueling) {
  376.       bp_x = World.local_ship->pos.x-(SCR_WIDTH+MAP_BLOCKSIZE*2)/2;
  377.       bp_y = World.local_ship->pos.y-(SCR_HEIGHT+MAP_BLOCKSIZE*2)/2;
  378.       Move(rp, LOCL_X, LOCL_Y);
  379.       aShip->fuell[buf].x = aShip->fpod->pos.x-bp_x;
  380.       aShip->fuell[buf].y = aShip->fpod->pos.y-bp_y;
  381.       Draw(rp, aShip->fuell[buf].x, aShip->fuell[buf].y);
  382.       aShip->f_drawn[buf] = TRUE;
  383.     }
  384.  
  385.     Move(rp, LOCL_X+currc[0].x, LOCL_Y+currc[0].y);
  386.     for (i = 1; i < aShip->shapesize; i++)
  387.       Draw(rp, LOCL_X+currc[i].x, LOCL_Y+currc[i].y);
  388.  
  389.   } else {
  390.     /*
  391.      * Remote ship fuelline drawing needs to be implemented. This
  392.      * may require line clipping depending on how it's done.
  393.      */
  394.     if (aShip->draw_it) {
  395.       bp_x = World.local_ship->pos.x-(SCR_WIDTH+MAP_BLOCKSIZE*2)/2;
  396.       bp_y = World.local_ship->pos.y-(SCR_HEIGHT+MAP_BLOCKSIZE*2)/2;
  397.       pos_x = aShip->pos.x-bp_x;
  398.       pos_y = aShip->pos.y-bp_y;
  399.  
  400.       aShip->p_pos[buf].x = pos_x;
  401.       aShip->p_pos[buf].y = pos_y;
  402.  
  403.       if (aShip->shields) {
  404.         BltBitMap(World.shld_bm, (SHL_SIZE*2+1)*animno, 0, rp->BitMap, 
  405.                   pos_x-SHL_SIZE, pos_y-SHL_SIZE,
  406.                   SHL_SIZE*2+1, SHL_SIZE*2+1, 0xEE, 0x03, NULL);
  407.         aShip->sh_drawn[buf] = TRUE;
  408.       }
  409.  
  410.       Move(rp, pos_x+currc[0].x, pos_y+currc[0].y);
  411.       for (i = 1; i < aShip->shapesize; i++) {
  412.         Draw(rp, pos_x+currc[i].x, pos_y+currc[i].y);
  413.         prevc[i].x = currc[i].x;
  414.         prevc[i].y = currc[i].y;
  415.       }
  416.       prevc[0].x = currc[0].x;
  417.       prevc[0].y = currc[0].y;
  418.      
  419.  
  420.       aShip->s_drawn[buf] = TRUE;
  421.     }
  422.   }
  423. }
  424.