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

  1. /***************************************************************************
  2.  *
  3.  * Points.c -- Functions used for calculations and displaying of points.
  4.  *
  5.  *-------------------------------------------------------------------------
  6.  * Authors: Casper Gripenberg  (casper@alpha.hut.fi)
  7.  *          Kjetil Jacobsen  (kjetilja@stud.cs.uit.no)
  8.  *
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <math.h>
  14. #include <exec/types.h>
  15. #include <intuition/intuition.h>    /* Intuition data strucutres, etc.    */
  16. #ifdef PURE_OS
  17. #include <proto/graphics.h>
  18. #endif
  19.  
  20. #include "lists_protos.h"
  21. #include "misc_protos.h"
  22. #include "points_protos.h"
  23. #include "prefs.h"
  24. #include "common.h"
  25. #include "defs.h"
  26. #include "map.h"
  27.  
  28. /*--------------------------------------------------------------------------*/
  29.  
  30. extern int sina[];
  31. extern int cosa[];
  32. extern int atana[];
  33.  
  34. extern AWorld World;
  35.  
  36. APoint explosion_point[EXP_MAXSIZE];
  37.  
  38. /*--------------------------------------------------------------------------*/
  39.  
  40. /*
  41.  * init_explosion -- Precalculate a nice big eye-catching random explosion.
  42.  */
  43. void
  44. init_explosion( void )
  45. {
  46.   int i;
  47.   int expangle, expmult;
  48.  
  49.   for (i = 0; i < EXP_MAXSIZE; i++) {
  50.     rand();  /* Why not? We wan't it REAL random don't we? :-) */
  51.     rand();
  52.     explosion_point[i].life = EXP_LIFE + ((rand() % EXP_LIFESPREAD*2)
  53.                               - EXP_LIFESPREAD);
  54.     expmult  = (int) ((((float)(rand() % 10) + 8.0)/4.0) * (float)PRECS);
  55.     expangle = rand() % 360;      
  56.  
  57.     explosion_point[i].xvel =  (sina[expangle] * expmult) / PRECS;    
  58.     explosion_point[i].yvel =  (cosa[expangle] * expmult) / PRECS;
  59.   }
  60. }
  61.  
  62. /*--------------------------------------------------------------------------*/
  63.  
  64. /*
  65.  * add_bullets -- Adds bullet to the world from the ship aShip.
  66.  *
  67.  */
  68. void
  69. add_bullets( AShip *aShip, int isin, int icos )
  70. {
  71.   int i, j;
  72.   int nbull;
  73.   int sinval, cosval;
  74.   int spreadangle, shangle, bulangle;
  75.   APoint *bullet;
  76.  
  77.   shangle = aShip->angle;
  78.   spreadangle = BUL_ANGLE;
  79.   
  80.   nbull= aShip->fw_nbul;
  81.  
  82.   /* Do this only two times; once for forward bullets and once for backward */
  83.   for (j = 0; j < 2; j++) {
  84.     /* Check if we have a bullet in the same direction as the ship */
  85.     if ( nbull & 1 ) {
  86.       if ((bullet = alloc_point()) == NULL)
  87.         return;
  88.       bullet->type = BULLET;
  89.       bullet->mass = BUL_MASS;
  90.       bullet->xvel = aShip->xvel + isin * BUL_SPEED;    
  91.       bullet->yvel = aShip->yvel - icos * BUL_SPEED;
  92.       bullet->life = BUL_LIFE;
  93.       bullet->color = WHITE;
  94.       bullet->pos.x = (aShip->pos.x + ((aShip->buldist * isin) >> SHFTPR));
  95.       bullet->pos.y = (aShip->pos.y - ((aShip->buldist * icos) >> SHFTPR));
  96.       nbull--;
  97.     }
  98.     for (i = 1; i <= nbull; i++) {
  99.       if ((bullet = alloc_point()) == NULL)
  100.         return;
  101.       if (i & 1) {
  102.         bulangle = (shangle - i * spreadangle) % 360;
  103.         if (bulangle < 0)
  104.           bulangle = bulangle + 360;
  105.         sinval = sina[bulangle];
  106.         cosval = cosa[bulangle];
  107.       } else {
  108.         bulangle = (shangle + (i-1) * spreadangle) % 360;
  109.         if (bulangle < 0)
  110.           bulangle = bulangle + 360;
  111.         sinval = sina[bulangle];
  112.         cosval = cosa[bulangle];
  113.       }
  114.       bullet->type = BULLET;
  115.       bullet->mass = BUL_MASS;
  116.       bullet->xvel = aShip->xvel + sinval * BUL_SPEED;    
  117.       bullet->yvel = aShip->yvel - cosval * BUL_SPEED;
  118.       bullet->life = BUL_LIFE;
  119.       bullet->color = WHITE;
  120.       bullet->pos.x = (aShip->pos.x + ((aShip->buldist * sinval) >> SHFTPR));
  121.       bullet->pos.y = (aShip->pos.y - ((aShip->buldist * cosval) >> SHFTPR));
  122.     }
  123.     /* Switch to backward bullets */
  124.     nbull = aShip->bw_nbul;
  125.     shangle = (shangle + 180) % 360;
  126.     isin *= -1;
  127.     icos *= -1;
  128.   }
  129. }
  130.  
  131. /*--------------------------------------------------------------------------*/
  132.  
  133. /*
  134.  * add_explosion -- Add an explosion at the specified coordinates. Copies the
  135.  *                  precalculated explosion parameters into the list of points
  136.  *                  moving on screen.
  137.  */
  138. void
  139. add_explosion( int x, int y )
  140. {
  141.   int i;
  142.  
  143.   APoint *expPoint;
  144.  
  145.   /* Copy precalc explosion to screen-points */
  146.   for (i = 0; i < EXP_MAXSIZE; i++) {
  147.     if ((expPoint = alloc_point()) == NULL)
  148.       return;
  149.     expPoint->type  = EXPLOSION;
  150.     expPoint->mass  = EXP_MASS;
  151.     expPoint->color = RED;
  152.     expPoint->pos.x = x;
  153.     expPoint->pos.y = y;
  154.     expPoint->xvel = explosion_point[i].xvel;
  155.     expPoint->yvel = explosion_point[i].yvel;
  156.     expPoint->life = explosion_point[i].life;
  157.   }
  158. }
  159.  
  160. /*--------------------------------------------------------------------------*/
  161.  
  162. /*
  163.  * add_exhaust -- Adds exhaust to a ship. shsin, shcos and shangle provided to
  164.  *                minimize time spent on calculations.
  165.  */
  166. void
  167. add_exhaust(AShip *aShip, int isin, int icos, UWORD nframes)
  168. {
  169.   int i, xoffset, xoffsign, edist;
  170.   int exhmult, exhangle;
  171.  
  172.   APoint *exhPoint;
  173.   
  174.   for (i = 0; i < (aShip->exhcount * nframes); i++) {
  175.     if ((exhPoint = alloc_point()) == NULL)
  176.       return;
  177.  
  178.     exhPoint->type  = EXHAUST;
  179.     exhPoint->mass  = EXH_MASS;
  180.     exhPoint->color = RED;
  181.     exhPoint->life = aShip->exhlife + ((rand() % EXH_LIFESPREAD*2)
  182.                      - EXH_LIFESPREAD);
  183.     xoffset  = (rand() % aShip->exhwidth) - (aShip->exhwidth-1)/2;
  184.     xoffsign = (xoffset == 0) ? 0 : xoffset/abs(xoffset);
  185.     exhmult  = (((rand() % 20) + 8) << SHFTPR)/10;
  186.     
  187.     exhangle = (aShip->angle - xoffsign * atana[((xoffsign*xoffset) << SHFTPR)
  188.                 /aShip->exhdist]) % 360;
  189.     if (exhangle < 0)
  190.       exhangle += 360;
  191.  
  192.     /*
  193.      * This is so that we won't get a line of collected points at exhdist;
  194.      * if for example nframes = 3 we would get aShip->exhcount * 3 number
  195.      * of points at exhdist from ship center..Doesn't look nice..
  196.      */
  197.     edist = aShip->exhdist + (rand() % 5);
  198.  
  199.     /* Rotate the starting point */ 
  200.     exhPoint->pos.x = aShip->pos.x + 
  201.                       ((xoffset * icos - edist * isin) >> SHFTPR);
  202.     exhPoint->pos.y = aShip->pos.y + 
  203.                       ((xoffset * isin + edist * icos) >> SHFTPR);
  204.  
  205.     /* Set exhaust vels */
  206.     exhPoint->xvel = aShip->xvel - ((sina[exhangle] * exhmult) >> SHFTPR);    
  207.     exhPoint->yvel = aShip->yvel + ((cosa[exhangle] * exhmult) >> SHFTPR);
  208.   }
  209. }
  210.  
  211. /*--------------------------------------------------------------------------*/
  212.  
  213. /*
  214.  * move_points -- Moves all the points to their next positions.
  215.  *
  216.  */
  217. void
  218. move_points( UWORD buf, UWORD nframes )
  219. {
  220.   APoint *point = World.points->next;  
  221.  
  222.   while (point->next != point) {
  223.     if (point->life > 0) {
  224.       point->xcount += point->xvel * nframes;
  225.       point->ycount += point->yvel * nframes;
  226.       point->pos.x += (point->xcount < 0) ? -((-point->xcount) >> SHFTPR) 
  227.                                           :     (point->xcount >> SHFTPR);
  228.       point->pos.y += (point->ycount < 0) ? -((-point->ycount) >> SHFTPR) 
  229.                                           :     (point->ycount >> SHFTPR);
  230.       point->ycount = point->ycount % PRECS;
  231.       point->xcount = point->xcount % PRECS;
  232.     }
  233.     point = point->next;
  234.   }
  235. }
  236.  
  237. /*--------------------------------------------------------------------------*/
  238.  
  239. /*
  240.  * draw_points -- Removes previous points, checks if points life has
  241.  *                run out and draws new points.
  242.  */
  243. void
  244. #ifdef PURE_OS
  245. draw_points( AShip *player, struct RastPort *rp, UWORD buf, UWORD nframes )
  246. #else
  247. draw_points( AShip *player, struct BitMap *bm, UWORD buf, UWORD nframes )
  248. #endif
  249. {
  250.   int bp_x, bp_y;
  251.   int cu_x, cu_y;
  252.   APoint *point = World.points->next;  
  253.   APoint *after_delete;
  254.  
  255. #ifndef PURE_OS
  256.   PLANEPTR plane0 = bm->Planes[0];
  257.   PLANEPTR plane1 = bm->Planes[1];
  258. #endif
  259.  
  260.   bp_x = player->pos.x-(SCR_WIDTH+MAP_BLOCKSIZE*2)/2;
  261.   bp_y = player->pos.y-(SCR_HEIGHT+MAP_BLOCKSIZE*2)/2;
  262.  
  263.   /*
  264.    * Remove points...
  265.    */
  266. #ifdef PURE_OS
  267.   SetAPen(rp,0); /* Want to erase pixels */
  268. #endif
  269.   while (point->next != point) {
  270.     if (point->drawn != 0) {
  271.       point->drawn &= ~(1 << buf);
  272. #ifdef PURE_OS
  273.       WritePixel(rp, point->p_pos[buf].x,point->p_pos[buf].y);
  274. #else
  275.       myWritePixel(plane0, point->p_pos[buf].x, point->p_pos[buf].y, 0);
  276.       if (point->color == WHITE)
  277.         myWritePixel(plane1, point->p_pos[buf].x, point->p_pos[buf].y, 0);
  278. #endif
  279.     }      
  280.  
  281.     /* 
  282.      * Check if the point's life has run out...
  283.      */
  284.     if ((point->life -= nframes) <= 0) {
  285.       point->draw_it = FALSE;
  286.       if (point->drawn == 0) {
  287.         after_delete = point->next;
  288.         free_point(point);
  289.         point = after_delete;
  290.         continue;
  291.       }
  292.       point = point->next;
  293.       continue;
  294.     }
  295.     point = point->next;
  296.   }
  297.  
  298.   /*
  299.    * Draw points...
  300.    */
  301.   point = World.points->next;  
  302.   while (point->next != point) {
  303.     if (point->draw_it && point->life > 0) {
  304.       point->drawn |= (1 << buf);
  305.       cu_x = point->p_pos[buf].x = point->pos.x-bp_x;
  306.       cu_y = point->p_pos[buf].y = point->pos.y-bp_y;
  307.  
  308. #ifdef PURE_OS
  309.       if (point->color == WHITE) {
  310.     SetAPen(rp,3);
  311.     WritePixel(rp, cu_x, cu_y);
  312.       } else {
  313.     SetAPen(rp,1);
  314.     WritePixel(rp, cu_x, cu_y);
  315.       }
  316. #else
  317.       myWritePixel(plane0, cu_x, cu_y, 1);
  318.       if (point->color == WHITE)
  319.           myWritePixel(plane1, cu_x, cu_y, 1);
  320. #endif
  321.     }
  322.     point = point->next;
  323.   }
  324. }
  325.  
  326.