borland conditionals have been removed. asm sources converted fully to tasm ideal mode. keyboard and timer interrupt handlers moved to c code copied from fdemo watcom sources
628 lines
17 KiB
C
628 lines
17 KiB
C
//****************** ( Animation Construction Kit 3D ) **********************
|
|
// Ray Casting Routines
|
|
// CopyRight (c) 1993 Author: Lary Myers
|
|
//***************************************************************************
|
|
|
|
#include "ack3d.h"
|
|
#include "ackeng.h"
|
|
#include "ackext.h"
|
|
|
|
extern short ViewAngle;
|
|
|
|
//**************************************************************************
|
|
//
|
|
//**************************************************************************
|
|
short ObjectExist(UCHAR onum)
|
|
{
|
|
short i;
|
|
short result = 0;
|
|
|
|
if (!FoundObjectCount)
|
|
return(result);
|
|
|
|
for (i = 0; i < FoundObjectCount; i++)
|
|
{
|
|
if (ObjectsSeen[i] == onum)
|
|
return(1);
|
|
}
|
|
|
|
return(result);
|
|
}
|
|
|
|
// long x_xPos,x_yPos,x_xNext,x_yNext;
|
|
// long y_xPos,y_yPos,y_xNext,y_yNext;
|
|
|
|
//*************************************************************************
|
|
//
|
|
//*************************************************************************
|
|
/*
|
|
void xRaySetup(void)
|
|
{
|
|
|
|
x_yNext = yNextTable[ViewAngle]; // PreCalc'd value of BITMAP_WIDTH * Tan(angle)
|
|
|
|
if (ViewAngle > INT_ANGLE_270 || ViewAngle < INT_ANGLE_90)
|
|
{
|
|
x_xPos = xBegGlobal + BITMAP_WIDTH; // Looking to the right
|
|
x_xNext = BITMAP_WIDTH; // Positive direction
|
|
}
|
|
else
|
|
{
|
|
x_xPos = xBegGlobal; // Looking to the left
|
|
x_xNext = -BITMAP_WIDTH; // Negative direction
|
|
x_yNext = -x_yNext;
|
|
}
|
|
|
|
// Calculate the Y coordinate for the current square
|
|
x_yPos = (((long)x_xPos - (long)xPglobal) * LongTanTable[ViewAngle]) + yPglobalHI;
|
|
|
|
}
|
|
*/
|
|
|
|
//**************************************************************************
|
|
//
|
|
//**************************************************************************
|
|
/*
|
|
UINT xRayCast(void)
|
|
{
|
|
UINT Color;
|
|
short i,j,mx,my;
|
|
short TablePosn;
|
|
short MapPosn,CurPosn;
|
|
short xBeg;
|
|
short BitmapColumn;
|
|
short xCenter,yCenter,xAdj;
|
|
short ObjPosn;
|
|
short oBegX,oBegY;
|
|
long xd,yd,sy;
|
|
long ObjDist;
|
|
|
|
while (1)
|
|
{
|
|
if (x_xPos < 0 || x_xPos > GRID_XMAX ||
|
|
x_yPos < 0 || x_yPos > GRID_YMAXLONG)
|
|
break;
|
|
|
|
//************* Fixed point Y/64 * 64 X / 64 **********
|
|
MapPosn = ((x_yPos >> FP_SHIFT) & 0xFFC0) + (x_xPos >> 6);
|
|
|
|
|
|
if ((Color = ObjGrid[MapPosn]) != 0)
|
|
{
|
|
Color &= 0x7F;
|
|
if (!ObjectExist(Color))
|
|
ObjectsSeen[FoundObjectCount++] = Color;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check to see if a wall is being struck by the ray
|
|
if ((Color = xGridGlobal[MapPosn]) != 0)
|
|
{
|
|
xMapPosn = MapPosn; // Hold onto the map location
|
|
iLastX = x_xPos;
|
|
LastY1 = x_yPos;
|
|
if ((Color & 0xFF) == DOOR_XCODE) // Is this a door?
|
|
{
|
|
yd = ((x_yPos >> FP_SHIFT) & GRID_MASK); // Get the left side
|
|
xd = yd + BITMAP_WIDTH; // And the right side
|
|
ObjDist = (x_yPos + (x_yNext >> 1)) >> FP_SHIFT; // Calc door distance
|
|
if (ObjDist < yd || ObjDist > xd) // Is door visible?
|
|
{
|
|
x_xPos += x_xNext; // Nope, continue casting
|
|
x_yPos += x_yNext; // the ray as before
|
|
continue;
|
|
}
|
|
|
|
LastY1 = x_yPos + (x_yNext >> 1); // Adjust the X,Y values so
|
|
iLastX += (x_xNext >> 1); // the door is halfway in sq.
|
|
}
|
|
|
|
if (Color & DOOR_TYPE_SECRET)
|
|
{
|
|
if (xSecretColumn != 0)
|
|
{
|
|
sy = xSecretColumn * LongTanTable[ViewAngle];
|
|
ObjDist = (x_yPos + sy) >> FP_SHIFT;
|
|
yd = ((x_yPos >> FP_SHIFT) & GRID_MASK); // Get the left side
|
|
xd = yd + BITMAP_WIDTH; // And the right side
|
|
if (ObjDist < yd || ObjDist > xd) // Is door visible?
|
|
{
|
|
x_xPos += x_xNext; // Nope, continue casting
|
|
x_yPos += x_yNext; // the ray as before
|
|
continue;
|
|
}
|
|
LastY1 = x_yPos + sy;
|
|
iLastX += xSecretColumn;
|
|
}
|
|
}
|
|
|
|
return(Color);
|
|
}
|
|
|
|
x_xPos += x_xNext; // Next X coordinate (fixed at 64 or -64)
|
|
x_yPos += x_yNext; // Next calculated Y coord for a delta of X
|
|
}
|
|
|
|
return(0); // Return that no wall was found
|
|
}
|
|
*/
|
|
|
|
//*************************************************************************
|
|
//
|
|
//*************************************************************************
|
|
UINT OldxRay(void)
|
|
{
|
|
UINT Color;
|
|
short i,j,mx,my;
|
|
short TablePosn;
|
|
short MapPosn,CurPosn;
|
|
short xBeg;
|
|
long xPos,xNext;
|
|
short BitmapColumn;
|
|
short xCenter,yCenter,xAdj;
|
|
short ObjPosn;
|
|
short oBegX,oBegY;
|
|
long yPos;
|
|
long yNext;
|
|
long xd,yd,sy;
|
|
long ObjDist;
|
|
|
|
yNext = yNextTable[ViewAngle]; // PreCalc'd value of BITMAP_WIDTH * Tan(angle)
|
|
|
|
if (ViewAngle > INT_ANGLE_270 || ViewAngle < INT_ANGLE_90)
|
|
{
|
|
xPos = xBegGlobal + BITMAP_WIDTH; // Looking to the right
|
|
xNext = BITMAP_WIDTH; // Positive direction
|
|
}
|
|
else
|
|
{
|
|
xPos = xBegGlobal; // Looking to the left
|
|
xNext = -BITMAP_WIDTH; // Negative direction
|
|
yNext = -yNext;
|
|
}
|
|
|
|
// Calculate the Y coordinate for the current square
|
|
yPos = (((long)xPos - (long)xPglobal) * LongTanTable[ViewAngle]) + yPglobalHI;
|
|
|
|
while (1)
|
|
{
|
|
if (xPos < 0 || xPos > GRID_XMAX ||
|
|
yPos < 0 || yPos > GRID_YMAXLONG)
|
|
break;
|
|
|
|
//************* Fixed point Y/64 * 64 X / 64 ***********
|
|
MapPosn = ((yPos >> FP_SHIFT) & 0xFFC0) + (xPos >> 6);
|
|
|
|
|
|
if ((Color = ObjGrid[MapPosn]) != 0)
|
|
{
|
|
Color &= 0x7F;
|
|
if (!ObjectExist(Color))
|
|
ObjectsSeen[FoundObjectCount++] = Color;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check to see if a wall is being struck by the ray
|
|
if ((Color = xGridGlobal[MapPosn]) != 0)
|
|
{
|
|
xMapPosn = MapPosn; // Hold onto the map location
|
|
iLastX = xPos;
|
|
LastY1 = yPos;
|
|
if ((Color & 0xFF) == DOOR_XCODE) // Is this a door?
|
|
{
|
|
yd = ((yPos >> FP_SHIFT) & GRID_MASK); // Get the left side
|
|
xd = yd + BITMAP_WIDTH; // And the right side
|
|
ObjDist = (yPos + (yNext >> 1)) >> FP_SHIFT; // Calc door distance
|
|
if (ObjDist < yd || ObjDist > xd) // Is door visible?
|
|
{
|
|
xPos += xNext; // Nope, continue casting
|
|
yPos += yNext; // the ray as before
|
|
continue;
|
|
}
|
|
|
|
LastY1 = yPos + (yNext >> 1); // Adjust the X,Y values so
|
|
iLastX += (xNext >> 1); // the door is halfway in sq.
|
|
}
|
|
|
|
if (Color & DOOR_TYPE_SECRET)
|
|
{
|
|
if (xSecretColumn != 0)
|
|
{
|
|
sy = xSecretColumn * LongTanTable[ViewAngle];
|
|
ObjDist = (yPos + sy) >> FP_SHIFT;
|
|
yd = ((yPos >> FP_SHIFT) & GRID_MASK); // Get the left side
|
|
xd = yd + BITMAP_WIDTH; // And the right side
|
|
if (ObjDist < yd || ObjDist > xd) // Is door visible?
|
|
{
|
|
xPos += xNext; // Nope, continue casting
|
|
yPos += yNext; // the ray as before
|
|
continue;
|
|
}
|
|
LastY1 = yPos + sy;
|
|
iLastX += xSecretColumn;
|
|
}
|
|
}
|
|
|
|
return(Color);
|
|
}
|
|
|
|
xPos += xNext; // Next X coordinate (fixed at 64 or -64)
|
|
yPos += yNext; // Next calculated Y coord for a delta of X
|
|
}
|
|
|
|
return(0); // Return that no wall was found
|
|
}
|
|
|
|
|
|
//*************************************************************************
|
|
//
|
|
//*************************************************************************
|
|
/*
|
|
void yRaySetup(void)
|
|
{
|
|
|
|
y_xNext = xNextTable[ViewAngle]; // Pre-calc'd value of BITMAP_WIDTH / tan(angle)
|
|
|
|
if (ViewAngle < INT_ANGLE_180)
|
|
{
|
|
y_yPos = yBegGlobal + BITMAP_WIDTH; // Looking down
|
|
y_yNext = BITMAP_WIDTH; // Positive direction
|
|
}
|
|
else
|
|
{
|
|
y_yPos = yBegGlobal; // Looking up
|
|
y_yNext = -BITMAP_WIDTH; // Negative direction
|
|
y_xNext = -y_xNext;
|
|
}
|
|
|
|
// Calculate the X coordinate for the current square
|
|
y_xPos = (((long)y_yPos - (long)yPglobal) * LongInvTanTable[ViewAngle]) + xPglobalHI;
|
|
|
|
}
|
|
*/
|
|
|
|
//*************************************************************************
|
|
//
|
|
//*************************************************************************
|
|
/*
|
|
UINT yRayCast(void)
|
|
{
|
|
UINT Color;
|
|
short i,j,mx,my;
|
|
short MapPosn;
|
|
short yBeg;
|
|
short BitmapColumn;
|
|
short xCenter,yCenter,yAdj;
|
|
short ObjPosn;
|
|
short oBegX;
|
|
long xd,yd,ObjDist,sx;
|
|
|
|
while (1)
|
|
{
|
|
if (y_xPos < 0 || y_xPos > GRID_XMAXLONG ||
|
|
y_yPos < 0 || y_yPos > GRID_YMAX)
|
|
break;
|
|
|
|
//********** Y/64 * 64 Fixed point and /64 *****
|
|
MapPosn = (y_yPos & 0xFFC0) + (y_xPos >> (FP_SHIFT+6));
|
|
|
|
|
|
if ((Color = ObjGrid[MapPosn]) != 0)
|
|
{
|
|
Color &= 0x7F;
|
|
if (!ObjectExist(Color))
|
|
ObjectsSeen[FoundObjectCount++] = Color;
|
|
|
|
}
|
|
|
|
|
|
// Check for a wall being struck
|
|
if ((Color = yGridGlobal[MapPosn]) != 0)
|
|
{
|
|
yMapPosn = MapPosn; // Hold onto map position
|
|
LastX1 = y_xPos;
|
|
iLastY = y_yPos;
|
|
|
|
if ((Color & 0xFF) == DOOR_YCODE) // Is this a door?
|
|
{
|
|
yd = ((y_xPos >> FP_SHIFT) & GRID_MASK); // Calc top side of square
|
|
xd = yd + BITMAP_WIDTH; // And bottom side of square
|
|
ObjDist = (y_xPos + (y_xNext >> 1)) >> FP_SHIFT;
|
|
if (ObjDist < yd || ObjDist > xd) // Is door visible?
|
|
{
|
|
y_xPos += y_xNext; // No, continue on with ray cast
|
|
y_yPos += y_yNext;
|
|
continue;
|
|
}
|
|
|
|
LastX1 = y_xPos + (y_xNext >> 1); // Adjust coordinates so door is
|
|
iLastY += (y_yNext >> 1); // Halfway into wall
|
|
}
|
|
|
|
if (Color & DOOR_TYPE_SECRET)
|
|
{
|
|
if (ySecretColumn != 0)
|
|
{
|
|
sx = ySecretColumn * LongInvTanTable[ViewAngle];
|
|
ObjDist = (y_xPos + sx) >> FP_SHIFT;
|
|
yd = ((y_xPos >> FP_SHIFT) & GRID_MASK); // Get the top side
|
|
xd = yd + BITMAP_WIDTH; // And the bottom side
|
|
if (ObjDist < yd || ObjDist > xd) // Is door visible?
|
|
{
|
|
y_xPos += y_xNext; // Nope, continue casting
|
|
y_yPos += y_yNext; // the ray as before
|
|
continue;
|
|
}
|
|
LastX1 = y_xPos + sx;
|
|
iLastY += ySecretColumn;
|
|
}
|
|
|
|
}
|
|
|
|
return(Color);
|
|
}
|
|
|
|
y_xPos += y_xNext; // Next calculated X value for delta Y
|
|
y_yPos += y_yNext; // Next fixed value of 64 or -64
|
|
|
|
}
|
|
|
|
return(0); // Return here if no Y wall is found
|
|
}
|
|
*/
|
|
|
|
//*************************************************************************
|
|
//
|
|
//*************************************************************************
|
|
UINT OldyRay(void)
|
|
{
|
|
UINT Color;
|
|
short i,j,mx,my;
|
|
short MapPosn;
|
|
short yBeg;
|
|
long yPos,yNext;
|
|
short BitmapColumn;
|
|
short xCenter,yCenter,yAdj;
|
|
short ObjPosn;
|
|
short oBegX;
|
|
long xPos;
|
|
long xNext;
|
|
long xd,yd,ObjDist,sx;
|
|
|
|
xNext = xNextTable[ViewAngle]; // Pre-calc'd value of BITMAP_WIDTH / tan(angle)
|
|
|
|
if (ViewAngle < INT_ANGLE_180)
|
|
{
|
|
yPos = yBegGlobal + BITMAP_WIDTH; /* Looking down */
|
|
yNext = BITMAP_WIDTH; /* Positive direction */
|
|
}
|
|
else
|
|
{
|
|
yPos = yBegGlobal; /* Looking up */
|
|
yNext = -BITMAP_WIDTH; /* Negative direction */
|
|
xNext = -xNext;
|
|
}
|
|
|
|
/* Calculate the X coordinate for the current square */
|
|
xPos = (((long)yPos - (long)yPglobal) * LongInvTanTable[ViewAngle]) + xPglobalHI;
|
|
|
|
while (1)
|
|
{
|
|
if (xPos < 0 || xPos > GRID_XMAXLONG ||
|
|
yPos < 0 || yPos > GRID_YMAX)
|
|
break;
|
|
|
|
/*********** Y/64 * 64 Fixed point and /64 ******/
|
|
// MapPosn = ((yPos / BITMAP_WIDTH) * GRID_WIDTH) + (xPos >> (FP_SHIFT+BITMAP_SHIFT));
|
|
// MapPosn = ((yPos & GRID_MASK) >> 1) + (xPos >> (FP_SHIFT+BITMAP_SHIFT));
|
|
MapPosn = (yPos & 0xFFC0) + (xPos >> (FP_SHIFT+6));
|
|
|
|
|
|
if ((Color = ObjGrid[MapPosn]) != 0)
|
|
{
|
|
Color &= 0x7F;
|
|
if (!ObjectExist(Color))
|
|
ObjectsSeen[FoundObjectCount++] = Color;
|
|
|
|
}
|
|
|
|
|
|
/** Check for a wall being struck **/
|
|
if ((Color = yGridGlobal[MapPosn]) != 0)
|
|
{
|
|
yMapPosn = MapPosn; /* Hold onto map position */
|
|
LastX1 = xPos;
|
|
iLastY = yPos;
|
|
|
|
if ((Color & 0xFF) == DOOR_YCODE) /* Is this a door? */
|
|
{
|
|
yd = ((xPos >> FP_SHIFT) & GRID_MASK); /* Calc top side of square */
|
|
xd = yd + BITMAP_WIDTH; /* And bottom side of square */
|
|
ObjDist = (xPos + (xNext >> 1)) >> FP_SHIFT;
|
|
if (ObjDist < yd || ObjDist > xd) /* Is door visible? */
|
|
{
|
|
xPos += xNext; /* No, continue on with ray cast */
|
|
yPos += yNext;
|
|
continue;
|
|
}
|
|
|
|
LastX1 = xPos + (xNext >> 1); /* Adjust coordinates so door is */
|
|
iLastY += (yNext >> 1); /* Halfway into wall */
|
|
}
|
|
|
|
if (Color & DOOR_TYPE_SECRET)
|
|
{
|
|
if (ySecretColumn != 0)
|
|
{
|
|
sx = ySecretColumn * LongInvTanTable[ViewAngle];
|
|
ObjDist = (xPos + sx) >> FP_SHIFT;
|
|
yd = ((xPos >> FP_SHIFT) & GRID_MASK); /* Get the top side */
|
|
xd = yd + BITMAP_WIDTH; /* And the bottom side */
|
|
if (ObjDist < yd || ObjDist > xd) /* Is door visible? */
|
|
{
|
|
xPos += xNext; /* Nope, continue casting */
|
|
yPos += yNext; /* the ray as before */
|
|
continue;
|
|
}
|
|
LastX1 = xPos + sx;
|
|
iLastY += ySecretColumn;
|
|
}
|
|
|
|
}
|
|
|
|
return(Color);
|
|
}
|
|
|
|
xPos += xNext; /* Next calculated X value for delta Y */
|
|
yPos += yNext; /* Next fixed value of 64 or -64 */
|
|
|
|
}
|
|
|
|
return(0); /* Return here if no Y wall is found */
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
** **
|
|
****************************************************************************/
|
|
UINT xRayMulti(UINT MinDist,short MinHeight)
|
|
{
|
|
UINT Color;
|
|
short i,j,mx,my;
|
|
short TablePosn;
|
|
short MapPosn,CurPosn;
|
|
short xBeg;
|
|
long xPos,xNext;
|
|
short BitmapColumn;
|
|
short xCenter,yCenter,xAdj;
|
|
short ObjPosn;
|
|
short oBegX,oBegY;
|
|
long yPos;
|
|
long yNext;
|
|
long xd,yd,sy;
|
|
long ObjDist;
|
|
|
|
yNext = yNextTable[ViewAngle]; /* PreCalc'd value of BITMAP_WIDTH * Tan(angle) */
|
|
|
|
if (ViewAngle > INT_ANGLE_270 || ViewAngle < INT_ANGLE_90)
|
|
{
|
|
xPos = xBegGlobal + BITMAP_WIDTH; /* Looking to the right */
|
|
xNext = BITMAP_WIDTH; /* Positive direction */
|
|
}
|
|
else
|
|
{
|
|
xPos = xBegGlobal; /* Looking to the left */
|
|
xNext = -BITMAP_WIDTH; /* Negative direction */
|
|
yNext = -yNext;
|
|
}
|
|
|
|
/* Calculate the Y coordinate for the current square */
|
|
yPos = (((long)xPos - (long)xPglobal) * LongTanTable[ViewAngle]) + yPglobalHI;
|
|
|
|
while (1)
|
|
{
|
|
if (xPos < 0 || xPos > GRID_XMAX ||
|
|
yPos < 0 || yPos > GRID_YMAXLONG)
|
|
break;
|
|
|
|
/************** Fixed point Y/64 * 64 X / 64 ***********/
|
|
MapPosn = ((yPos >> FP_SHIFT) & 0xFFC0) + (xPos >> 6);
|
|
|
|
/* Check to see if a wall is being struck by the ray */
|
|
if ((Color = xGridGlobal[MapPosn]) & WALL_TYPE_MULTI)
|
|
{
|
|
if ((Color & 0xFF) > MinHeight)
|
|
{
|
|
xd = xPos - xPglobal;
|
|
yd = InvCosTable[ViewAngle] >> 4;
|
|
if (MinDist < ((xd * yd) >> 10))
|
|
{
|
|
xMapPosn = MapPosn; /* Hold onto the map location */
|
|
iLastX = xPos;
|
|
LastY1 = yPos;
|
|
return(Color);
|
|
}
|
|
}
|
|
}
|
|
|
|
xPos += xNext; /* Next X coordinate (fixed at 64 or -64) */
|
|
yPos += yNext; /* Next calculated Y coord for a delta of X */
|
|
}
|
|
|
|
return(0); /* Return that no wall was found */
|
|
}
|
|
|
|
/****************************************************************************
|
|
** **
|
|
****************************************************************************/
|
|
UINT yRayMulti(UINT MinDist,short MinHeight)
|
|
{
|
|
UINT Color;
|
|
short i,j,mx,my;
|
|
short MapPosn;
|
|
short yBeg;
|
|
long yPos,yNext;
|
|
short BitmapColumn;
|
|
short xCenter,yCenter,yAdj;
|
|
short ObjPosn;
|
|
short oBegX;
|
|
long xPos;
|
|
long xNext;
|
|
long xd,yd,ObjDist,sx;
|
|
|
|
xNext = xNextTable[ViewAngle]; /* Pre-calc'd value of BITMAP_WIDTH / tan(angle) */
|
|
|
|
if (ViewAngle < INT_ANGLE_180)
|
|
{
|
|
yPos = yBegGlobal + BITMAP_WIDTH; /* Looking down */
|
|
yNext = BITMAP_WIDTH; /* Positive direction */
|
|
}
|
|
else
|
|
{
|
|
yPos = yBegGlobal; /* Looking up */
|
|
yNext = -BITMAP_WIDTH; /* Negative direction */
|
|
xNext = -xNext;
|
|
}
|
|
|
|
/* Calculate the X coordinate for the current square */
|
|
xPos = (((long)yPos - (long)yPglobal) * LongInvTanTable[ViewAngle]) + xPglobalHI;
|
|
|
|
while (1)
|
|
{
|
|
if (xPos < 0 || xPos > GRID_XMAXLONG ||
|
|
yPos < 0 || yPos > GRID_YMAX)
|
|
break;
|
|
|
|
/*********** Y/64 * 64 Fixed point and /64 ******/
|
|
MapPosn = (yPos & 0xFFC0) + (xPos >> (FP_SHIFT+6));
|
|
|
|
/** Check for a wall being struck **/
|
|
if ((Color = yGridGlobal[MapPosn]) & WALL_TYPE_MULTI)
|
|
{
|
|
if ((Color & 0xFF) > MinHeight)
|
|
{
|
|
xd = yPos - yPglobal;
|
|
yd = InvCosTable[ViewAngle] >> 4;
|
|
if (MinDist < ((xd * yd) >> 10))
|
|
{
|
|
yMapPosn = MapPosn; /* Hold onto the map location */
|
|
LastX1 = xPos;
|
|
iLastY = yPos;
|
|
return(Color);
|
|
}
|
|
}
|
|
}
|
|
|
|
xPos += xNext; /* Next calculated X value for delta Y */
|
|
yPos += yNext; /* Next fixed value of 64 or -64 */
|
|
|
|
}
|
|
|
|
return(0); /* Return here if no Y wall is found */
|
|
}
|
|
|