home *** CD-ROM | disk | FTP | other *** search
- /* ACK-3D ( Animation Construction Kit 3D ) */
- /* Object routines */
- /* Author: Lary Myers */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <dos.h>
- #include <mem.h>
- #include <alloc.h>
- #include <io.h>
- #include <fcntl.h>
- #include <time.h>
- #include <string.h>
- #include <sys\stat.h>
- #include "ack3d.h"
- #include "ackext.h"
-
- /****************************************************************************
- ** Runs the list of objects generated during xRay and yRay to determine if **
- ** they are really visible, what column should be displayed and which **
- ** bitmap to use. **
- ** **
- ** First the object coordinates are translated to be 0,0 relative to **
- ** the player coordinates. **
- ** **
- ** Next the object coordinates are rotated to the player angle. This **
- ** allows the tangent of the angle to be used to determine the column of **
- ** the bitmap. Some checks are made to insure the column and distance are **
- ** not out of bounds. **
- ** **
- ** The width of the object is determined from the same table as the height **
- ** to keep the object (which is 64x64 for now) in the same ratio as the **
- ** walls. **
- ** **
- ** If the object has multiple sides the angle is used to determine which **
- ** side to display. This value is then used to get the correct bitmap **
- ** number to display. The current object center row is also used to allow **
- ** objects to bounce up and down. **
- ** **
- ** Finally the objects is displayed if it will fit on the display and the **
- ** distance is closer than the corresonding wall slice. **
- ** **
- ****************************************************************************/
- void FindObject(int xPlayer,int yPlayer,int PlayerAngle)
- {
- int i,j,count,SaveCenter;
- int ObjX,ObjY,ObjNum;
- int NewX,NewY;
- int MaxOpp,Column;
- int wt,ObjIndex;
- long deltax,deltay;
- long xp,yp,distance;
- long SinValue,CosValue;
-
- if (!TotalObjects) /* No objects found during ray casts */
- return;
-
- SinValue = SinTable[PlayerAngle];
- CosValue = CosTable[PlayerAngle];
-
- for (i = 0; i < TotalObjects; i++)
- {
- ObjIndex = ObjNumber[i];
- ObjNum = ObjList[ObjIndex].bmNum[ObjList[ObjIndex].CurNum];
- ObjX = ObjList[ObjIndex].x;
- ObjY = ObjList[ObjIndex].y;
-
- /* Translate coordinates to 0,0 */
- NewX = ObjX - xPlayer;
- NewY = ObjY - yPlayer;
-
-
- /* Rotate coordinates to current player angle */
- xp = ((NewX * CosValue) + (NewY * SinValue)) >> FP_SHIFT;
- yp = ((NewY * CosValue) - (NewX * SinValue)) >> FP_SHIFT;
-
- deltax = xp;
- deltay = yp;
- distance = long_sqrt((deltax * deltax) + (deltay * deltay));
-
- MaxOpp = ((LongTanTable[INT_ANGLE_30] * (long)deltax) >> FP_SHIFT);
-
- if (NewY < ObjY)
- MaxOpp = -MaxOpp;
-
- Column = 160;
-
- if (MaxOpp)
- Column = 160 - ((deltay * 160) / MaxOpp);
-
- yp = ViewCosTable[Column];
- xp = distance;
- if (yp)
- {
- distance = distance * yp;
-
- xp = distance >> 14;
- if (distance - (xp << 14) >= 8096)
- xp++;
-
- }
- distance = xp;
-
- if (distance < 0)
- continue;
-
- if (distance >= (MAX_DISTANCE - 10))
- distance = MAX_DISTANCE-11;
-
- wt = DistanceTable[distance];
-
- if (wt > 300)
- continue;
-
- if (wt < 16) wt = 16;
- if (wt > 300) wt = 300;
-
- yp = AdjustTable[distance];
- xp = 0;
- wt >>= 1;
- NewX = Column;
-
- if (ObjList[ObjIndex].Sides)
- ObjNum =
- ObjList[ObjIndex].bmNum[((PlayerAngle / ObjList[ObjIndex].Sides) & 7)];
-
- SaveCenter = CenterRow;
- CenterRow = ObjList[ObjIndex].VidRow;
-
- for (Column = NewX - wt; Column < NewX + wt; Column++)
- {
- if (Column >= 0 && Column < 320)
- {
- if (distance < (Walls[Column].Distance + 10))
- DrawOneObject(ObjNum,xp >> FP_SHIFT,distance,Column,PageNum);
- }
- xp += yp;
- }
-
- CenterRow = SaveCenter;
- }
-
- }
-
-
- /****************************************************************************
- ** **
- ****************************************************************************/
- long CheckObjects(int xPlayer,int yPlayer,int PlayerAngle)
- {
- int i,j,count;
- int mPos,ObjX,ObjY,ObjNum;
- int NewX,NewY;
- int MaxOpp,Column;
- int wt,ObjIndex;
- long MinDistance;
- long xp,yp,distance;
- long SinValue,CosValue;
-
- MinDistance = 3000000L;
-
- if (!TotalObjects)
- return(MinDistance);
-
- SinValue = SinTable[PlayerAngle];
- CosValue = CosTable[PlayerAngle];
-
- for (i = 0; i < TotalObjects; i++)
- {
- ObjIndex = ObjNumber[i];
-
- if (Grid[ObjList[ObjIndex].mPos] & 0x40)
- continue;
-
- ObjX = ObjList[ObjIndex].x;
- ObjY = ObjList[ObjIndex].y;
-
- /* Translate coordinates to 0,0 */
- NewX = ObjX - xPlayer;
- NewY = ObjY - yPlayer;
-
- /* Rotate coordinates to current player angle */
- xp = ((NewX * CosValue) + (NewY * SinValue)) >> FP_SHIFT;
- yp = ((NewY * CosValue) - (NewX * SinValue)) >> FP_SHIFT;
-
- distance = long_sqrt((xp * xp) + (yp * yp));
-
- MaxOpp = ((LongTanTable[INT_ANGLE_30] * xp) >> FP_SHIFT);
- if (NewY < ObjY)
- MaxOpp = -MaxOpp;
-
- Column = 160;
-
- if (MaxOpp)
- Column = 160 - ((yp * 160) / MaxOpp);
-
- yp = ViewCosTable[Column];
- xp = distance;
- if (yp)
- {
- distance = distance * yp;
-
- xp = distance >> 14;
- if (distance - (xp << 14) >= 8096)
- xp++;
-
- }
- distance = xp;
-
- if (distance < 0)
- continue;
-
- if (distance >= MAX_DISTANCE)
- distance = MAX_DISTANCE-1;
-
- if (DistanceTable[distance] > 300)
- continue;
-
- if (distance < MinDistance)
- MinDistance = distance;
-
- }
-
- return(MinDistance);
- }
-
- /****************************************************************************
- ** **
- ****************************************************************************/
- void MoveObject(int Index,int dx,int dy)
- {
- int Pos,NewPos,x1,y1;
-
- Pos = ObjList[Index].mPos;
- ObjList[Index].y += dy;
- ObjList[Index].x += dx;
-
- x1 = ObjList[Index].x >> 6;
- y1 = ObjList[Index].y >> 6;
- NewPos = (y1 * GRID_WIDTH) + x1;
- if (NewPos != Pos)
- {
- xObjGrid[Pos] = xObjGrid[Pos-1];
- xObjGrid[Pos+1] = xObjGrid[Pos+2];
- yObjGrid[Pos] = yObjGrid[Pos-GRID_WIDTH];
- yObjGrid[Pos+GRID_WIDTH] = yObjGrid[Pos + (GRID_WIDTH << 1)];
- Grid[Pos] &= 0x7F;
-
- ObjList[Index].mPos = NewPos;
-
- xObjGrid[NewPos] = Index;
- xObjGrid[NewPos+1] = Index;
- yObjGrid[NewPos] = Index;
- yObjGrid[NewPos+GRID_WIDTH] = Index;
- Grid[NewPos] |= 0x80;
- }
-
- }
-
- /****************************************************************************
- ** **
- ****************************************************************************/
- void CheckObjectMovement(void)
- {
- int i,speed;
- int dx,dy,dir;
- int NewDx,NewDy;
-
- for (i = 1; i < MaxObjects; i++)
- {
- if (!ObjList[i].Active)
- continue;
-
- if (!(speed = ObjList[i].Speed))
- continue;
-
- dir = ObjList[i].Dir;
-
- if (dir == 8)
- {
- ObjList[i].VidRow -= speed;
- if (ObjList[i].VidRow < 110)
- {
- ObjList[i].VidRow = 110;
- ObjList[i].Dir = 9;
- }
- continue;
- }
-
- if (dir == 9)
- {
- ObjList[i].VidRow += speed;
- if (ObjList[i].VidRow > 130)
- {
- ObjList[i].VidRow = 130;
- ObjList[i].Dir = 8;
- }
- continue;
- }
-
- if (dir == 10)
- {
- dx = ObjList[i].CurNum + 1;
- if (dx > ObjList[i].MaxNum)
- dx = 0;
-
- ObjList[i].CurNum = dx;
- continue;
- }
-
- dx = DirDx[dir] * speed;
- dy = DirDy[dir] * speed;
-
- NewDx = ObjList[i].x + dx;
- NewDy = ObjList[i].y + dy;
-
- if (NewDy < 96 ||
- NewDy > 4000 ||
- NewDx < 96 ||
- NewDx > 4000 ||
- CheckHit(ObjList[i].x,ObjList[i].y,DirAngle[dir]))
- {
- dir += 2;
- if (dir > 7)
- dir = 0;
-
- if (CheckHit(ObjList[i].x,ObjList[i].y,DirAngle[dir]))
- {
- dir -= 4;
- if (dir < 0)
- dir = 7;
- }
-
- ObjList[i].Dir = dir;
- continue;
- }
-
- MoveObject(i,dx,dy);
- }
-
- }
-
-