home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / progmisc / acksrc.zip / ACKOBJ.C < prev    next >
Text File  |  1993-06-14  |  8KB  |  344 lines

  1. /*           ACK-3D ( Animation Construction Kit 3D )              */
  2. /* Object routines    */
  3. /* Author: Lary Myers */
  4.  
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <dos.h>
  8. #include <mem.h>
  9. #include <alloc.h>
  10. #include <io.h>
  11. #include <fcntl.h>
  12. #include <time.h>
  13. #include <string.h>
  14. #include <sys\stat.h>
  15. #include "ack3d.h"
  16. #include "ackext.h"
  17.  
  18. /****************************************************************************
  19. ** Runs the list of objects generated during xRay and yRay to determine if **
  20. ** they are really visible, what column should be displayed and which       **
  21. ** bitmap to use.                               **
  22. **                                       **
  23. ** First the object coordinates are translated to be 0,0 relative to       **
  24. ** the player coordinates.                           **
  25. **                                       **
  26. ** Next the object coordinates are rotated to the player angle. This       **
  27. ** allows the tangent of the angle to be used to determine the column of   **
  28. ** the bitmap. Some checks are made to insure the column and distance are  **
  29. ** not out of bounds.                               **
  30. **                                       **
  31. ** The width of the object is determined from the same table as the height **
  32. ** to keep the object (which is 64x64 for now) in the same ratio as the       **
  33. ** walls.                                   **
  34. **                                       **
  35. ** If the object has multiple sides the angle is used to determine which   **
  36. ** side to display. This value is then used to get the correct bitmap       **
  37. ** number to display. The current object center row is also used to allow  **
  38. ** objects to bounce up and down.                       **
  39. **                                       **
  40. ** Finally the objects is displayed if it will fit on the display and the  **
  41. ** distance is closer than the corresonding wall slice.               **
  42. **                                       **
  43. ****************************************************************************/
  44. void FindObject(int xPlayer,int yPlayer,int PlayerAngle)
  45. {
  46.     int        i,j,count,SaveCenter;
  47.     int        ObjX,ObjY,ObjNum;
  48.     int        NewX,NewY;
  49.     int        MaxOpp,Column;
  50.     int        wt,ObjIndex;
  51.     long    deltax,deltay;
  52.     long    xp,yp,distance;
  53.     long    SinValue,CosValue;
  54.  
  55. if (!TotalObjects)    /* No objects found during ray casts */
  56.     return;
  57.  
  58. SinValue = SinTable[PlayerAngle];
  59. CosValue = CosTable[PlayerAngle];
  60.  
  61. for (i = 0; i < TotalObjects; i++)
  62.     {
  63.     ObjIndex = ObjNumber[i];
  64.     ObjNum = ObjList[ObjIndex].bmNum[ObjList[ObjIndex].CurNum];
  65.     ObjX = ObjList[ObjIndex].x;
  66.     ObjY = ObjList[ObjIndex].y;
  67.  
  68. /* Translate coordinates to 0,0 */
  69.     NewX = ObjX - xPlayer;
  70.     NewY = ObjY - yPlayer;
  71.  
  72.  
  73. /* Rotate coordinates to current player angle */
  74.     xp = ((NewX * CosValue) + (NewY * SinValue)) >> FP_SHIFT;
  75.     yp = ((NewY * CosValue) - (NewX * SinValue)) >> FP_SHIFT;
  76.  
  77.     deltax = xp;
  78.     deltay = yp;
  79.     distance = long_sqrt((deltax * deltax) + (deltay * deltay));
  80.  
  81.     MaxOpp = ((LongTanTable[INT_ANGLE_30] * (long)deltax) >> FP_SHIFT);
  82.  
  83.     if (NewY < ObjY)
  84.     MaxOpp = -MaxOpp;
  85.  
  86.     Column = 160;
  87.  
  88.     if (MaxOpp)
  89.     Column = 160 - ((deltay * 160) / MaxOpp);
  90.  
  91.     yp = ViewCosTable[Column];
  92.     xp = distance;
  93.     if (yp)
  94.     {
  95.     distance = distance * yp;
  96.  
  97.     xp = distance >> 14;
  98.     if (distance - (xp << 14) >= 8096)
  99.         xp++;
  100.  
  101.     }
  102.     distance = xp;
  103.  
  104.     if (distance < 0)
  105.     continue;
  106.  
  107.     if (distance >= (MAX_DISTANCE - 10))
  108.     distance = MAX_DISTANCE-11;
  109.  
  110.     wt = DistanceTable[distance];
  111.  
  112.     if (wt > 300)
  113.     continue;
  114.  
  115.     if (wt < 16) wt = 16;
  116.     if (wt > 300) wt = 300;
  117.  
  118.     yp = AdjustTable[distance];
  119.     xp = 0;
  120.     wt >>= 1;
  121.     NewX = Column;
  122.  
  123.     if (ObjList[ObjIndex].Sides)
  124.     ObjNum =
  125.      ObjList[ObjIndex].bmNum[((PlayerAngle / ObjList[ObjIndex].Sides) & 7)];
  126.  
  127.     SaveCenter = CenterRow;
  128.     CenterRow = ObjList[ObjIndex].VidRow;
  129.  
  130.     for (Column = NewX - wt; Column < NewX + wt; Column++)
  131.     {
  132.     if (Column >= 0 && Column < 320)
  133.         {
  134.         if (distance < (Walls[Column].Distance + 10))
  135.         DrawOneObject(ObjNum,xp >> FP_SHIFT,distance,Column,PageNum);
  136.         }
  137.     xp += yp;
  138.     }
  139.  
  140.     CenterRow = SaveCenter;
  141.     }
  142.  
  143. }
  144.  
  145.  
  146. /****************************************************************************
  147. **                                       **
  148. ****************************************************************************/
  149. long CheckObjects(int xPlayer,int yPlayer,int PlayerAngle)
  150. {
  151.     int        i,j,count;
  152.     int        mPos,ObjX,ObjY,ObjNum;
  153.     int        NewX,NewY;
  154.     int        MaxOpp,Column;
  155.     int        wt,ObjIndex;
  156.     long    MinDistance;
  157.     long    xp,yp,distance;
  158.     long    SinValue,CosValue;
  159.  
  160. MinDistance = 3000000L;
  161.  
  162. if (!TotalObjects)
  163.     return(MinDistance);
  164.  
  165. SinValue = SinTable[PlayerAngle];
  166. CosValue = CosTable[PlayerAngle];
  167.  
  168. for (i = 0; i < TotalObjects; i++)
  169.     {
  170.     ObjIndex = ObjNumber[i];
  171.  
  172.     if (Grid[ObjList[ObjIndex].mPos] & 0x40)
  173.     continue;
  174.  
  175.     ObjX = ObjList[ObjIndex].x;
  176.     ObjY = ObjList[ObjIndex].y;
  177.  
  178. /* Translate coordinates to 0,0 */
  179.     NewX = ObjX - xPlayer;
  180.     NewY = ObjY - yPlayer;
  181.  
  182. /* Rotate coordinates to current player angle */
  183.     xp = ((NewX * CosValue) + (NewY * SinValue)) >> FP_SHIFT;
  184.     yp = ((NewY * CosValue) - (NewX * SinValue)) >> FP_SHIFT;
  185.  
  186.     distance = long_sqrt((xp * xp) + (yp * yp));
  187.  
  188.     MaxOpp = ((LongTanTable[INT_ANGLE_30] * xp) >> FP_SHIFT);
  189.     if (NewY < ObjY)
  190.     MaxOpp = -MaxOpp;
  191.  
  192.     Column = 160;
  193.  
  194.     if (MaxOpp)
  195.     Column = 160 - ((yp * 160) / MaxOpp);
  196.  
  197.     yp = ViewCosTable[Column];
  198.     xp = distance;
  199.     if (yp)
  200.     {
  201.     distance = distance * yp;
  202.  
  203.     xp = distance >> 14;
  204.     if (distance - (xp << 14) >= 8096)
  205.         xp++;
  206.  
  207.     }
  208.     distance = xp;
  209.  
  210.     if (distance < 0)
  211.     continue;
  212.  
  213.     if (distance >= MAX_DISTANCE)
  214.     distance = MAX_DISTANCE-1;
  215.  
  216.     if (DistanceTable[distance] > 300)
  217.     continue;
  218.  
  219.     if (distance < MinDistance)
  220.     MinDistance = distance;
  221.  
  222.     }
  223.  
  224. return(MinDistance);
  225. }
  226.  
  227. /****************************************************************************
  228. **                                       **
  229. ****************************************************************************/
  230. void MoveObject(int Index,int dx,int dy)
  231. {
  232.     int        Pos,NewPos,x1,y1;
  233.  
  234. Pos = ObjList[Index].mPos;
  235. ObjList[Index].y += dy;
  236. ObjList[Index].x += dx;
  237.  
  238. x1 = ObjList[Index].x >> 6;
  239. y1 = ObjList[Index].y >> 6;
  240. NewPos = (y1 * GRID_WIDTH) + x1;
  241. if (NewPos != Pos)
  242.     {
  243.     xObjGrid[Pos] = xObjGrid[Pos-1];
  244.     xObjGrid[Pos+1] = xObjGrid[Pos+2];
  245.     yObjGrid[Pos] = yObjGrid[Pos-GRID_WIDTH];
  246.     yObjGrid[Pos+GRID_WIDTH] = yObjGrid[Pos + (GRID_WIDTH << 1)];
  247.     Grid[Pos] &= 0x7F;
  248.  
  249.     ObjList[Index].mPos = NewPos;
  250.  
  251.     xObjGrid[NewPos] = Index;
  252.     xObjGrid[NewPos+1] = Index;
  253.     yObjGrid[NewPos] = Index;
  254.     yObjGrid[NewPos+GRID_WIDTH] = Index;
  255.     Grid[NewPos] |= 0x80;
  256.     }
  257.  
  258. }
  259.  
  260. /****************************************************************************
  261. **                                       **
  262. ****************************************************************************/
  263. void CheckObjectMovement(void)
  264. {
  265.         int        i,speed;
  266.         int        dx,dy,dir;
  267.         int        NewDx,NewDy;
  268.  
  269. for (i = 1; i < MaxObjects; i++)
  270.     {
  271.     if (!ObjList[i].Active)
  272.     continue;
  273.  
  274.     if (!(speed = ObjList[i].Speed))
  275.     continue;
  276.  
  277.     dir = ObjList[i].Dir;
  278.  
  279.     if (dir == 8)
  280.     {
  281.     ObjList[i].VidRow -= speed;
  282.     if (ObjList[i].VidRow < 110)
  283.         {
  284.         ObjList[i].VidRow = 110;
  285.         ObjList[i].Dir = 9;
  286.         }
  287.     continue;
  288.     }
  289.  
  290.     if (dir == 9)
  291.     {
  292.     ObjList[i].VidRow += speed;
  293.     if (ObjList[i].VidRow > 130)
  294.         {
  295.         ObjList[i].VidRow = 130;
  296.         ObjList[i].Dir = 8;
  297.         }
  298.     continue;
  299.     }
  300.  
  301.     if (dir == 10)
  302.     {
  303.     dx = ObjList[i].CurNum + 1;
  304.     if (dx > ObjList[i].MaxNum)
  305.         dx = 0;
  306.  
  307.     ObjList[i].CurNum = dx;
  308.     continue;
  309.     }
  310.  
  311.     dx = DirDx[dir] * speed;
  312.     dy = DirDy[dir] * speed;
  313.  
  314.     NewDx = ObjList[i].x + dx;
  315.     NewDy = ObjList[i].y + dy;
  316.  
  317.     if (NewDy < 96 ||
  318.     NewDy > 4000 ||
  319.     NewDx < 96 ||
  320.     NewDx > 4000 ||
  321.     CheckHit(ObjList[i].x,ObjList[i].y,DirAngle[dir]))
  322.     {
  323.     dir += 2;
  324.     if (dir > 7)
  325.         dir = 0;
  326.  
  327.     if (CheckHit(ObjList[i].x,ObjList[i].y,DirAngle[dir]))
  328.         {
  329.         dir -= 4;
  330.         if (dir < 0)
  331.         dir = 7;
  332.         }
  333.  
  334.     ObjList[i].Dir = dir;
  335.     continue;
  336.     }
  337.  
  338.     MoveObject(i,dx,dy);
  339.     }
  340.  
  341. }
  342.  
  343.  
  344.