ack3d/ack_lib/ACKRAY.C
Gered 83aaf0d5b9 update acklib to build under watcom
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
2019-11-02 13:56:52 -04:00

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 */
}