home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / progmisc / acksrc.zip / ACKENG.C < prev    next >
Text File  |  1993-06-18  |  21KB  |  700 lines

  1. /****************  ACK-3D ( Animation Construction Kit 3D ) *******************/
  2. /* Engine Code          */
  3. /* Author: Lary Myers */
  4.  
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <dos.h>
  8. #include <mem.h>
  9. #include <alloc.h>
  10. #include <io.h>
  11. #include <fcntl.h>
  12. #include <time.h>
  13. #include <string.h>
  14. #include <sys\stat.h>
  15. #include "ack3d.h"
  16. #include "ackext.h"
  17.  
  18. /****************************************************************************
  19. **                                       **
  20. ****************************************************************************/
  21. char xRay(int x,int y,int angle)
  22. {
  23.     char    Color;
  24.     int        i,j,mx,my;
  25.     int        TablePosn;
  26.     int        MapPosn,CurPosn;
  27.     int        xBeg;
  28.     long    xPos,xNext;
  29.     int        BitmapColumn;
  30.     int        xCenter,yCenter,xAdj;
  31.     int        ObjPosn;
  32.     int        oBegX,oBegY;
  33.     long    yPos;
  34.     long    yNext;
  35.     long    xd,yd,sy;
  36.     long    ObjDist;
  37.  
  38. xBeg  = x & 0xFFC0;        /* Get upper left corner of square    */
  39. yNext = yNextTable[angle];    /* PreCalc'd value of 64 * Tan(angle) */
  40.  
  41. if (angle > INT_ANGLE_270 || angle < INT_ANGLE_90)
  42.     {
  43.     xPos  = xBeg + GRID_SIZE;    /* Looking to the right */
  44.     xNext = GRID_SIZE;        /* Positive direction    */
  45.     }
  46. else
  47.     {
  48.     xPos  = xBeg;        /* Looking to the left    */
  49.     xNext = -GRID_SIZE;        /* Negative direction    */
  50.     yNext = -yNext;
  51.     }
  52.  
  53. /* Calculate the Y coordinate for the current square */
  54. yPos = (((long)xPos - (long)x) * LongTanTable[angle]) + ((long)y << FP_SHIFT);
  55.  
  56. while (1)
  57.     {
  58.     if (xPos < 0 || xPos > GRID_XMAX ||
  59.     yPos < 0 || yPos > GRID_YMAXLONG)
  60.     break;
  61.  
  62. /**************      Fixed point      Y/64 * 64    X / 64 ***********/
  63.     MapPosn = ((yPos >> FP_SHIFT) & 0xFFC0) + (xPos >> 6);
  64.  
  65. /* First check for an object that has not been seen yet */
  66.     if ((Color = xObjGrid[MapPosn]) > 0 && !(ObjFlags[Color] & 3))
  67.     {
  68.     ObjFlags[Color] |= 1;            /* Indicate object has been seen */
  69.  
  70.     xd = ObjList[Color].x - x;
  71.     yd = ObjList[Color].y - y;
  72.     ObjDist = (xd * xd) + (yd * yd);    /* Calc relative distance */
  73.  
  74. /* Place the object in the array according to distance, with the ones closer */
  75. /* being drawn last. This will allow closer objects to hide farther objects  */
  76.  
  77.     j = TotalObjects;
  78.     for (i = 0; i < TotalObjects; i++)
  79.         {
  80.         if (ObjDist > ObjRelDist[i])
  81.         {
  82.  
  83.         for (j = TotalObjects; j > i; j--)
  84.             {
  85.             ObjRelDist[j] = ObjRelDist[j-1];
  86.             ObjNumber[j]  = ObjNumber[j-1];
  87.             ObjMapPosn[j] = ObjMapPosn[j-1];
  88.             }
  89.  
  90.         j = i;
  91.         i = TotalObjects;
  92.         }
  93.         }
  94.  
  95. /* Hold onto relavant data for the object found */
  96.     ObjNumber[j]  = Color;
  97.     ObjRelDist[j] = ObjDist;
  98.     ObjMapPosn[j] = MapPosn;
  99.     TotalObjects++;
  100.     ObjRelDist[TotalObjects] = 3200000;
  101.     }
  102.  
  103. /* Now check to see if a wall is being struck by the ray */
  104.     if ((Color = xGrid[MapPosn]) != 0)
  105.     {
  106.     xMapPosn = MapPosn;        /* Hold onto the map location */
  107.     iLastX     = xPos;
  108.     LastY1     = yPos;
  109.     if (Color == DOOR_XCODE)    /* Is this a door? */
  110.         {
  111.         yd = (yPos >> FP_SHIFT) & 0xFFC0;    /* Get the left side */
  112.         xd = yd + GRID_SIZE;        /* And the right side */
  113.         ObjDist = (yPos + (yNext >> 1)) >> FP_SHIFT; /* Calc door distance */
  114.         if (ObjDist < yd || ObjDist > xd)    /* Is door visible? */
  115.         {
  116.         xPos += xNext;            /* Nope, continue casting */
  117.         yPos += yNext;            /* the ray as before      */
  118.         continue;
  119.         }
  120.  
  121.         LastY1 = yPos + (yNext >> 1);    /* Adjust the X,Y values so   */
  122.         iLastX += (xNext >> 1);        /* the door is halfway in sq. */
  123.         }
  124.  
  125.     if (Color == DOOR_SECRETCODE)
  126.         {
  127.         if (xSecretColumn != 0)
  128.         {
  129.         sy = xSecretColumn * LongTanTable[angle];
  130.         ObjDist = (yPos + sy) >> FP_SHIFT;
  131.         yd = (yPos >> FP_SHIFT) & 0xFFC0;   /* Get the left side */
  132.         xd = yd + GRID_SIZE;            /* And the right side */
  133.         if (ObjDist < yd || ObjDist > xd)   /* Is door visible? */
  134.             {
  135.             xPos += xNext;            /* Nope, continue casting */
  136.             yPos += yNext;            /* the ray as before      */
  137.             continue;
  138.             }
  139.         LastY1 = yPos + sy;
  140.         iLastX += xSecretColumn;
  141.         }
  142.         }
  143.  
  144.     return(Color);
  145.     }
  146.  
  147.     xPos += xNext;    /* Next X coordinate (fixed at 64 or -64)   */
  148.     yPos += yNext;    /* Next calculated Y coord for a delta of X */
  149.     }
  150.  
  151. return(0);        /* Return that no wall was found */
  152. }
  153.  
  154. /****************************************************************************
  155. **                                       **
  156. ****************************************************************************/
  157. char yRay(int x,int y,int angle)
  158. {
  159.     char    Color;
  160.     int        i,j,mx,my;
  161.     int        MapPosn;
  162.     int        yBeg;
  163.     long    yPos,yNext;
  164.     int        BitmapColumn;
  165.     int        xCenter,yCenter,yAdj;
  166.     int        ObjPosn;
  167.     int        oBegX;
  168.     long    xPos;
  169.     long    xNext;
  170.     long    xd,yd,ObjDist,sx;
  171.  
  172. yBeg  = y & 0xFFC0;        /* Same as div 64 then mul 64           */
  173. xNext = xNextTable[angle];    /* Pre-calc'd value of 64 / tan(angle) */
  174.  
  175. if (angle < INT_ANGLE_180)
  176.     {
  177.     yPos  = yBeg + GRID_SIZE;    /* Looking down          */
  178.     yNext = GRID_SIZE;        /* Positive direction */
  179.     }
  180. else
  181.     {
  182.     yPos  = yBeg;        /* Looking up          */
  183.     yNext = -GRID_SIZE;        /* Negative direction */
  184.     xNext = -xNext;
  185.     }
  186.  
  187. /* Calculate the X coordinate for the current square */
  188. xPos = (((long)yPos - (long)y) * LongInvTanTable[angle]) + ((long)x << FP_SHIFT);
  189.  
  190. oBegX = 0;
  191.  
  192. while (1)
  193.     {
  194.     if (xPos < 0 || xPos > GRID_XMAXLONG ||
  195.     yPos < 0 || yPos > GRID_YMAX)
  196.     break;
  197.  
  198. /***********   Y/64 * 64     Fixed point and /64 ******/
  199.     MapPosn = (yPos & 0xFFC0) + (xPos >> (FP_SHIFT+6));
  200.  
  201. /* Check for unseen objects first */
  202.     if ((Color = yObjGrid[MapPosn]) > 0 && !(ObjFlags[Color] & 3))
  203.     {
  204.     ObjFlags[Color] |= 2;        /* Signal object seen on Y cast */
  205.  
  206.     xd = ObjList[Color].x - x;
  207.     yd = ObjList[Color].y - y;
  208.     yd = (xd * xd) + (yd * yd);    /* Calc relative distance to object */
  209.  
  210. /* Place the object in the array according to distance, with the ones closer */
  211. /* being drawn last. This will allow closer objects to hide farther objects  */
  212.     j = TotalObjects;
  213.     for (i = 0; i < TotalObjects; i++)
  214.         {
  215.         if (yd > ObjRelDist[i])
  216.         {
  217.         for (j = TotalObjects; j > i; j--)
  218.             {
  219.             ObjRelDist[j] = ObjRelDist[j-1];
  220.             ObjNumber[j]  = ObjNumber[j-1];
  221.             ObjMapPosn[j] = ObjMapPosn[j-1];
  222.             }
  223.  
  224.         j = i;
  225.         i = TotalObjects;
  226.         }
  227.         }
  228.  
  229.     ObjNumber[j]  = Color;        /* Hold onto object data for later */
  230.     ObjRelDist[j] = yd;
  231.     ObjMapPosn[j] = MapPosn;
  232.     TotalObjects++;
  233.     ObjRelDist[TotalObjects] = 3200000;
  234.     }
  235.  
  236. /** Check for a wall being struck **/
  237.     if ((Color = yGrid[MapPosn]) != 0)
  238.     {
  239.     yMapPosn = MapPosn;        /* Hold onto map position */
  240.     LastX1     = xPos;
  241.     iLastY     = yPos;
  242.  
  243.     if (Color == DOOR_YCODE)    /* Is this a door? */
  244.         {
  245.         yd = (xPos >> FP_SHIFT) & 0xFFC0;    /* Calc top side of square   */
  246.         xd = yd + GRID_SIZE;        /* And bottom side of square */
  247.         ObjDist = (xPos + (xNext >> 1)) >> FP_SHIFT;
  248.         if (ObjDist < yd || ObjDist > xd)    /* Is door visible? */
  249.         {
  250.         xPos += xNext;        /* No, continue on with ray cast */
  251.         yPos += yNext;
  252.         continue;
  253.         }
  254.  
  255.         LastX1 = xPos + (xNext >> 1);   /* Adjust coordinates so door is */
  256.         iLastY += (yNext >> 1);        /* Halfway into wall         */
  257.         }
  258.  
  259.     if (Color == DOOR_SECRETCODE)
  260.         {
  261.         if (ySecretColumn != 0)
  262.         {
  263.         sx = ySecretColumn * LongInvTanTable[angle];
  264.         ObjDist = (xPos + sx) >> FP_SHIFT;
  265.         yd = (xPos >> FP_SHIFT) & 0xFFC0;   /* Get the top side       */
  266.         xd = yd + GRID_SIZE;            /* And the bottom side */
  267.         if (ObjDist < yd || ObjDist > xd)   /* Is door visible? */
  268.             {
  269.             xPos += xNext;            /* Nope, continue casting */
  270.             yPos += yNext;            /* the ray as before      */
  271.             continue;
  272.             }
  273.         LastX1 = xPos + sx;
  274.         iLastY += ySecretColumn;
  275.         }
  276.  
  277.         }
  278.  
  279.     return(Color);
  280.     }
  281.  
  282.     xPos += xNext;        /* Next calculated X value for delta Y */
  283.     yPos += yNext;        /* Next fixed value of 64 or -64       */
  284.  
  285.     if (++oBegX > 64)        /* Check a maximum number of squares   */
  286.     break;
  287.     }
  288.  
  289. return(0);        /* Return here if no Y wall is found */
  290. }
  291.  
  292.  
  293. /****************************************************************************
  294. ** This is the heart of the engine. This routine will cast two rays for       **
  295. ** each column of the screen. The first ray will look for any walls that   **
  296. ** fall on the X boundaries (vertical walls). The second ray will look for **
  297. ** walls on the Y boundaries (horizontal walls). The wall with the shorter **
  298. ** distance will be used to draw a sliver of the bitmap at the current       **
  299. ** screen column (0-319). A 60 degree field of view was selected to give   **
  300. ** a realistic perspective to the walls.                   **
  301. **                                       **
  302. ****************************************************************************/
  303. void DrawView(int xPlayer,int yPlayer,int PlayerAngle)
  304. {
  305.         int        i,j,index;
  306. unsigned    char    xBitmap,yBitmap,BitmapNumber;
  307.         int        ViewAngle;
  308.         long    xDistance,yDistance;
  309.         long    WallDistance;
  310.         int        distance;
  311. unsigned    int        BitmapColumn,yBitmapColumn;
  312.         int        WallCode,OldMapPosn,OldMapPosn1;
  313.         long    xd,yd;
  314. unsigned    char    *Video;
  315. unsigned    int        offset;
  316.  
  317. /* Clear out the object seen flags so objects can be found */
  318. memset(ObjFlags,0,MaxObjects);
  319.  
  320.  
  321. /* Begin looking 30 degrees to the left of our current angle */
  322. ViewAngle = PlayerAngle - INT_ANGLE_30;
  323.  
  324. if (ViewAngle < 0)
  325.     ViewAngle += INT_ANGLE_360;
  326.  
  327. /* Reset total objects found on last DrawView pass */
  328. TotalObjects = 0;
  329.  
  330. MaxDistance = 0;
  331.  
  332.  
  333. /* Cast two rays for each column of the video display */
  334.  
  335. for (i = 0; i < VIEW_WIDTH; i++)
  336.     {
  337.     WallDistance = 3000000;    /* Set to a ridiculous distance */
  338.     BitmapColumn = -1;        /* Set to no walls found    */
  339.     WallCode     = 0;        /* Set to no shadowing        */
  340.  
  341. /* Don't even cast an X ray if impossible to intersect the X walls */
  342.     if (ViewAngle != INT_ANGLE_90 && ViewAngle != INT_ANGLE_270)
  343.     {
  344.     yd = CLOCK_PTR;
  345.     BitmapNumber = xRay(xPlayer,yPlayer,ViewAngle);
  346.  
  347.     if (BitmapNumber)    /* A wall was found */
  348.         {
  349.         /* Use the Y intercept to determine the wall column */
  350.         BitmapColumn = (LastY1 >> FP_SHIFT) & 0x3F;
  351.  
  352.         /* Keep the orientation the same no matter which side we're on */
  353.         if ((int)iLastX < xPlayer)
  354.         BitmapColumn = 63 - BitmapColumn;
  355.  
  356.         /* Did we strike a door? */
  357.         if (BitmapNumber == DOOR_XCODE)
  358.         {
  359.         index = FindDoor(xMapPosn);
  360.         if (index >= 0)                /* This is a valid door */
  361.             {
  362.             j = Door[index].ColOffset;        /* Get its current pos  */
  363.             if ((int)iLastX > xPlayer)        /* Handle orientation   */
  364.             j = -j;
  365.             BitmapColumn += j;            /* Adjust column to show */
  366.             if (BitmapColumn > 63)        /* Door is opening         */
  367.             {
  368.             /* Get the grid coordinates for this door */
  369.             OldMapPosn = Door[index].mPos;
  370.             OldMapPosn1 = Door[index].mPos1;
  371.  
  372.             /* Fake the engine into thinking no door is there */
  373.             xGrid[OldMapPosn] = 0;
  374.             xGrid[OldMapPosn1] = 0;
  375.  
  376.             /* Cast the ray to get walls beyond the door */
  377.             BitmapNumber = xRay(xPlayer,yPlayer,ViewAngle);
  378.  
  379.             /* Put back the door codes if not fully open */
  380.             if (Door[index].ColOffset < 63)
  381.                 {
  382.                 xGrid[OldMapPosn] = Door[index].mCode;
  383.                 xGrid[OldMapPosn1] = Door[index].mCode1;
  384.                 }
  385.  
  386.             /* Calc the new bitmap column of wall behind door */
  387.             BitmapColumn = (LastY1 >> FP_SHIFT) & 0x3F;
  388.             if ((int)iLastX < xPlayer)
  389.                 BitmapColumn = 63 - BitmapColumn;
  390.             }
  391.             }
  392.         }
  393.  
  394.         /* Calculate the distance to the wall. Since the X position was  */
  395.         /* fixed to move 64 or -64 we can use it to determine the actual */
  396.         /* wall distance. The InvCosTable values were stored with a fixed */
  397.         /* point of 20 decimal places. At this time we'll knock off 14 of */
  398.         /* them so we can later multiple with a fixed point value of 16   */
  399.         xd = iLastX - xPlayer;
  400.         WallDistance = (xd * InvCosTable[ViewAngle]) >> 14;
  401.  
  402.  
  403.         /* Still looking for the reason this may occur. But this check  */
  404.         /* will force the distance to a ridiculous value so no wall is  */
  405.         /* seen later on when the X and Y walls are compared.        */
  406.         if (WallDistance < 0)
  407.         WallDistance = 120000L;
  408.  
  409.         /* Walls that are not doors will have shadowing */
  410.         if (BitmapNumber < DOOR_XCODE)
  411.         WallCode = 1;
  412.         }
  413.  
  414.     txRay += CLOCK_PTR - yd;
  415.     }
  416.  
  417. /* Don't cast a Y ray if its impossible to intercept any Y walls */
  418.     if (ViewAngle != 0 && ViewAngle != INT_ANGLE_180)
  419.     {
  420.     xd = CLOCK_PTR;
  421.     yBitmap = yRay(xPlayer,yPlayer,ViewAngle);
  422.  
  423.     if (yBitmap)        /* A wall was found */
  424.         {
  425.  
  426.         /* Use the X intercept to determine the column of the bitmap */
  427.         yBitmapColumn = (LastX1 >> FP_SHIFT) & 0x3F;
  428.  
  429.         /* Handle orientation from either side of the wall */
  430.         if ((int)iLastY > yPlayer)
  431.         yBitmapColumn = 63 - yBitmapColumn;
  432.  
  433.         /* Did we strike a door? */
  434.         if (yBitmap == DOOR_YCODE)
  435.         {
  436.         index = FindDoor(yMapPosn);
  437.         if (index >= 0)            /* This is a valid door */
  438.             {
  439.             /* Get the current door column offset */
  440.             j = Door[index].ColOffset;
  441.  
  442.             /* Deal with orientation */
  443.             if ((int)iLastY < yPlayer)
  444.             j = -j;
  445.  
  446.             yBitmapColumn += j;
  447.  
  448.             /* If beyond width of bitmap than cast again */
  449.             if (yBitmapColumn > 63)
  450.             {
  451.  
  452.             /* Get the yGrid coordinates for this door */
  453.             OldMapPosn = Door[index].mPos;
  454.             OldMapPosn1 = Door[index].mPos1;
  455.  
  456.             /* Fool the engine into thinking no door is there */
  457.             yGrid[OldMapPosn] = 0;
  458.             yGrid[OldMapPosn1] = 0;
  459.  
  460.             /* Cast again for walls beyond the door */
  461.             yBitmap = yRay(xPlayer,yPlayer,ViewAngle);
  462.  
  463.             /* Put door code back if not fully open */
  464.             if (Door[index].ColOffset < 63)
  465.                 {
  466.                 yGrid[OldMapPosn] = Door[index].mCode;
  467.                 yGrid[OldMapPosn1] = Door[index].mCode1;
  468.                 }
  469.  
  470.             /* Get the bitmap column of wall beyond door */
  471.             yBitmapColumn = (LastX1 >> FP_SHIFT) & 0x3F;
  472.             if ((int)iLastY > yPlayer)
  473.                 yBitmapColumn = 63 - yBitmapColumn;
  474.  
  475.             }
  476.             }
  477.         }
  478.  
  479.  
  480.         /* Calculate the distance to the wall. Since the Y position was  */
  481.         /* fixed to move 64 or -64 we can use it to determine the actual */
  482.         /* wall distance. The InvSinTable values were stored with a fixed */
  483.         /* point of 20 decimal places. At this time we'll knock off 14 of */
  484.         /* them so we can later multiple with a fixed point value of 16   */
  485.         yd = iLastY - yPlayer;
  486.         yDistance = (yd * InvSinTable[ViewAngle]) >> 14;
  487.  
  488.         /* Don't know the reason but change negative value into ridiculous */
  489.         if (yDistance < 0)
  490.         yDistance = 120000L;
  491.  
  492.  
  493.         /* At this point check the distance to the Y wall against the X */
  494.         /* wall to see which one is closer. The closer one is the one   */
  495.         /* we'll draw at this column of the screen.                     */
  496.         if (yDistance < WallDistance)
  497.         {
  498.         WallCode = 0;            /* Turn off shadowing if on */
  499.         WallDistance = yDistance;
  500.         BitmapNumber = yBitmap;
  501.         BitmapColumn = yBitmapColumn;
  502.         }
  503.  
  504.         }
  505.  
  506.     tyRay += CLOCK_PTR - xd;
  507.     }
  508.  
  509.     if (BitmapColumn < 64)    /* A wall was found (either X or Y) */
  510.     {
  511.  
  512.     /* To avoid a fishbowl affect we need to adjust the distance so */
  513.     /* it appears perpendicular to the center point of the display    */
  514.     /* which is relative angle 0 from the players current angle. We */
  515.     /* started at -30 degrees for the first screen column and will    */
  516.     /* cycle from -30 down to 0 then back up to +30 degrees. This    */
  517.     /* cosine value was pre-calculated and placed in ViewCosTable.    */
  518.     WallDistance *= ViewCosTable[i];
  519.  
  520.     /* Now we strip off somemore decimal points and check round-up    */
  521.     xd = WallDistance >> 14;
  522.     if (WallDistance - (xd << 14) >= 8096)
  523.         xd++;
  524.  
  525.     /* The last decimal points from the multiplication after the X and */
  526.     /* Y rays is stripped off and checked for round-up.           */
  527.     WallDistance = xd >> 6;
  528.     if (xd - (WallDistance << 6) >= 32)
  529.         WallDistance++;
  530.  
  531.     /* Don't really need to, but put it into an integer for fast compare */
  532.     distance = WallDistance;
  533.  
  534.     /* This is an arbitrary minimum distance to look for */
  535.     if (distance < 10)
  536.         distance = 10;
  537.  
  538.     /* Don't want it to go outside our table boundaries */
  539.     if (distance >= MAX_DISTANCE)
  540.         distance = MAX_DISTANCE - 1;
  541.  
  542.     /* Save the wall data to display when done with entire screen */
  543.     Walls[i].Distance = distance;
  544.     Walls[i].Number = (BitmapNumber & 0x3F) + WallCode;
  545.     Walls[i].Column = BitmapColumn;
  546.  
  547.     if (distance > MaxDistance)
  548.         MaxDistance = distance;
  549.     }
  550.  
  551.     ViewAngle++;
  552.     if (ViewAngle >= INT_ANGLE_360)
  553.     ViewAngle -= INT_ANGLE_360;
  554.  
  555.     }
  556.  
  557. xd = CLOCK_PTR;
  558. /* This routine gets the Walls structure and draws all of the walls */
  559. DrawWalls();
  560. tDOW += CLOCK_PTR - xd;
  561.  
  562. /* Now we look at any objects that may be closer than the walls */
  563. FindObject(xPlayer,yPlayer,PlayerAngle);
  564.  
  565. xd = CLOCK_PTR;
  566. /* Reset mask to allow all planes then flip to the page we just drew to */
  567. outp(0x3c5,255);
  568. flippage();
  569. PageNum ^= 1;
  570. usepage(PageNum);
  571.  
  572. tFlip += CLOCK_PTR - xd;
  573.  
  574. }
  575.  
  576. /****************************************************************************
  577. ** This routine is used when the player moves location as well as by the   **
  578. ** moveable objects. Its purpose is to determine if a valid obstacle is       **
  579. ** in front of the player or object.                       **
  580. **                                       **
  581. ****************************************************************************/
  582. int CheckHit(int xPlayer,int yPlayer,int ViewAngle)
  583. {
  584.     int        BitmapColumn,BitmapNumber,yBitmap,distance;
  585.     int        i,WallCode;
  586.     long    WallDistance,xd,yd,yDistance;
  587.     long    CheckDist;
  588.  
  589. WallDistance = 3000000;        /* Set to a ridiculous value */
  590. WallCode     = 3;        /* Initialize to strike an object */
  591. CheckDist    = 48L;        /* Initial minimum distance to look for */
  592. BitmapNumber = 0;        /* Initialize to no bitmap found */
  593.  
  594. /* Clear out any objects seen from previous passes */
  595. memset(ObjFlags,0,MaxObjects);
  596.  
  597. /* Set number of objects seen on this pass */
  598. TotalObjects = 0;
  599.  
  600. /* Don't allow one of these angles, causes either the X or Y ray to not be */
  601. /* cast which gives a false reading about an obstacle.               */
  602. if (ViewAngle == INT_ANGLE_45 ||
  603.     ViewAngle == INT_ANGLE_135 ||
  604.     ViewAngle == INT_ANGLE_225 ||
  605.     ViewAngle == INT_ANGLE_315)
  606.     ViewAngle++;
  607.  
  608. /* Don't cast an X ray if no chance of striking a X wall */
  609. if (ViewAngle != INT_ANGLE_90 && ViewAngle != INT_ANGLE_270)
  610.     {
  611.     BitmapNumber = xRay(xPlayer,yPlayer,ViewAngle);
  612.  
  613.     if (BitmapNumber)
  614.     {
  615.     xd = iLastX - xPlayer;
  616.  
  617.     /* Use the delta X to determine the distance to the wall */
  618.     WallDistance = (xd * InvCosTable[ViewAngle]) >> 14;
  619.  
  620.     if (WallDistance < 0)
  621.         WallDistance = 120000L;
  622.  
  623.     /* Set the wall struck code to an X wall */
  624.     WallCode = 1;
  625.     }
  626.     }
  627.  
  628. /* Don't cast a Y ray if impossible to strike a Y wall */
  629. if (ViewAngle != 0 && ViewAngle != INT_ANGLE_180)
  630.     {
  631.     yBitmap = yRay(xPlayer,yPlayer,ViewAngle);
  632.  
  633.     if (yBitmap)
  634.     {
  635.     yd = iLastY - yPlayer;
  636.  
  637.     /* Use the delta Y to determine distance to the wall */
  638.     yDistance = (yd * InvSinTable[ViewAngle]) >> 14;
  639.     if (yDistance < 0)
  640.         yDistance = 120000L;
  641.  
  642.     /* If Y wall closer than X wall then use Y wall data */
  643.     if (yDistance < WallDistance)
  644.         {
  645.         WallDistance = yDistance;
  646.  
  647.         /* Indicate the wall struck was a Y wall */
  648.         WallCode = 2;
  649.         BitmapNumber = yBitmap;
  650.         }
  651.  
  652.     }
  653.  
  654.     }
  655.  
  656. /* Since doors appear in the middle of the wall, adjust the minimum distance */
  657. /* to it. This handles walking up close to a door.                 */
  658. if (BitmapNumber >= DOOR_XCODE)
  659.     CheckDist += 34L;
  660.  
  661. if (WallCode)
  662.     {
  663.     /* Adjust the distance based on the center of the screen */
  664.     WallDistance *= ViewCosTable[160];
  665.  
  666.     /* Remove fixed point and round-up */
  667.     xd = WallDistance >> 14;
  668.     if (WallDistance - (xd << 14) >= 8096)
  669.     xd++;
  670.  
  671.     /* Remove initial fixed point and round-up */
  672.     WallDistance = xd >> 6;
  673.     if (xd - (WallDistance << 6) >= 32)
  674.     WallDistance++;
  675.  
  676.     /* Get minimum distance to any objects between player and wall */
  677.     yDistance = CheckObjects(xPlayer,yPlayer,ViewAngle);
  678.  
  679.     /* An object was found, if closer than use object as obstacle */
  680.     if (yDistance > 0L && yDistance < WallDistance)
  681.     {
  682.     /* Return code for an object struck */
  683.     WallCode = 3;
  684.     /* Adjust minimum distance to keep object from getting too close */
  685.     CheckDist += 32L;
  686.     WallDistance = yDistance;
  687.     }
  688.  
  689.     /* If the wall or object is further than the minimum distance, we can */
  690.     /* continue moving in this direction.                  */
  691.     if (WallDistance > CheckDist)
  692.     WallCode = 0;
  693.     }
  694.  
  695. return(WallCode);
  696. }
  697.  
  698.  
  699.  
  700.