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