home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1993 #2
/
Image.iso
/
graphics
/
acksrc.zip
/
ACKOBJ.C
< prev
next >
Wrap
Text File
|
1993-06-14
|
8KB
|
344 lines
/* 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);
}
}