home *** CD-ROM | disk | FTP | other *** search
- /******************* ( Animation Construction Kit 3D ) ***********************/
- /* Door Routines */
- /* CopyRight (c) 1993 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 "ackeng.h"
- #include "ackext.h"
-
- /****************************************************************************
- ** Check all the doors to see what state they are in. If a door's column **
- ** offset is non-zero then it is either opening or closing, so add in the **
- ** speed of the door and check for fully open and fully closed conditions. **
- ** **
- ** **
- ****************************************************************************/
- void CheckDoors(ACKENG *ae)
- {
- int i,MapPosn,mPos,mPos1;
- int column,mx,my,DeltaGrid;
- int xPlayer,yPlayer;
- unsigned char mCode,mCode1;
-
- xPlayer = ae->xPlayer;
- yPlayer = ae->yPlayer;
-
- for (i = 0; i < MAX_DOORS; i++)
- {
- if (ae->Door[i].ColOffset)
- {
- ae->Door[i].ColOffset += ae->Door[i].Speed;
- mPos = ae->Door[i].mPos;
- mPos1 = ae->Door[i].mPos1;
-
- /* Door is closing and is visible. Put old codes back to make non-passable */
- if (ae->Door[i].Speed < 0 && ae->Door[i].ColOffset < 65)
- {
- MapPosn = (yPlayer & 0xFFC0) + (xPlayer >> 6);
- if (MapPosn == mPos ||
- MapPosn == mPos1)
- {
- ae->Door[i].ColOffset -= ae->Door[i].Speed;
- continue;
- }
-
- if (ae->Door[i].Type == DOOR_XCODE)
- {
- ae->xGrid[mPos] = ae->Door[i].mCode;
- ae->xGrid[mPos1] = ae->Door[i].mCode1;
- }
- else
- {
- ae->yGrid[mPos] = ae->Door[i].mCode;
- ae->yGrid[mPos1] = ae->Door[i].mCode1;
- }
-
- /* Door is close enough to fully closed to get rid of the door from the array */
- if (ae->Door[i].ColOffset < 3)
- {
- ae->Door[i].ColOffset = 0;
- ae->Door[i].mPos = -1;
- ae->Door[i].mPos1 = -1;
- ae->Door[i].Flags = 0;
- }
-
- }
-
- /* Door is fully open, reverse the speed to begin closing */
- if (ae->Door[i].ColOffset > 0xA0)
- {
- ae->Door[i].Speed = -ae->Door[i].Speed;
- ae->Door[i].Flags &= ~DOOR_OPENING;
- ae->Door[i].Flags |= DOOR_CLOSING;
- }
-
- }
- }
-
-
- /* Now check for any action occuring in a secret door. This is currently */
- /* setup to handle only one door at a time in the X and Y directions, but */
- /* it should be fairly straightforward to use a list of doors, similiar */
- /* to normal doors, to handle more than one. */
- if (xSecretColumn)
- {
- if (xSecretColumn > 0) /* See if the door is to the right of us */
- {
- mPos = xSecretmPos1;
- DeltaGrid = -1;
- xSecretColumn += ae->DoorSpeed;
- }
- else
- {
- mPos = xSecretmPos;
- DeltaGrid = 0;
- xSecretColumn -= ae->DoorSpeed;
- }
-
- my = mPos & 0xFFC0;
- mx = (mPos - my) << 6;
-
- if (abs(xSecretColumn) > GRID_SIZE) /* Beyond one grid square */
- {
- mx += xSecretColumn;
- my = my + (mx >> 6);
- if (ae->xGrid[my]) /* No further, an obstruction */
- {
- ae->xGrid[xSecretmPos] = 0;
- ae->xGrid[xSecretmPos1] = 0;
- my += DeltaGrid;
- ae->xGrid[my] = ae->NonSecretCode;
- ae->xGrid[my+1] = ae->NonSecretCode;
- ae->yGrid[my] = ae->NonSecretCode;
- ae->yGrid[my + GRID_WIDTH] = ae->NonSecretCode;
- xSecretColumn = 0;
- }
- else
- {
- if (my != mPos)
- {
- ae->xGrid[xSecretmPos] = 0;
- ae->xGrid[xSecretmPos1] = 0;
- if (xSecretColumn > 0)
- {
- xSecretColumn -= 63;
- ae->xGrid[my] = DOOR_TYPE_SECRET + 1;
- xSecretmPos1 = my;
- my--;
- ae->xGrid[my] = DOOR_TYPE_SECRET + 1;
- xSecretmPos = my;
- }
- else
- {
- xSecretColumn += 63;
- ae->xGrid[my] = DOOR_TYPE_SECRET + 1;
- ae->xGrid[my+1] = DOOR_TYPE_SECRET + 1;
- xSecretmPos = my;
- xSecretmPos = my+1;
- }
- }
- } /* End if (xGrid[my]) ... else ... */
- } /* End if (abs(xSecretColumn) > GRID_SIZE) */
- } /* End if (xSecretColumn) */
-
- /* Perform same process on a secret door that may be moving in the Y */
- /* direction. The same door can move either way, depending on which */
- /* angle the player struck it at. */
- if (ySecretColumn)
- {
- if (ySecretColumn > 0)
- {
- mPos = ySecretmPos1;
- DeltaGrid = -GRID_WIDTH;
- ySecretColumn += ae->DoorSpeed;
- }
- else
- {
- mPos = ySecretmPos;
- DeltaGrid = 0;
- ySecretColumn -= ae->DoorSpeed;
- }
-
- my = mPos & 0xFFC0;
- mx = (mPos - my) << 6;
-
- if (abs(ySecretColumn) > GRID_SIZE)
- {
- my += ySecretColumn;
- my = (my & 0xFFC0) + (mx >> 6);
- if (ae->yGrid[my])
- {
- ae->yGrid[ySecretmPos] = 0;
- ae->yGrid[ySecretmPos1] = 0;
- my += DeltaGrid;
- ae->xGrid[my] = ae->NonSecretCode;
- ae->xGrid[my+1] = ae->NonSecretCode;
- ae->yGrid[my] = ae->NonSecretCode;
- ae->yGrid[my + GRID_WIDTH] = ae->NonSecretCode;
- ySecretColumn = 0;
- }
- else
- {
- if (my != mPos)
- {
- ae->yGrid[ySecretmPos] = 0;
- ae->yGrid[ySecretmPos1] = 0;
- if (ySecretColumn > 0)
- {
- ySecretColumn -= 63;
- ae->yGrid[my] = DOOR_TYPE_SECRET + 1;
- ySecretmPos1 = my;
- my -= GRID_WIDTH;
- ae->yGrid[my] = DOOR_TYPE_SECRET + 1;
- ySecretmPos = my;
- }
- else
- {
- ySecretColumn += 63;
- ae->yGrid[my] = DOOR_TYPE_SECRET + 1;
- ae->yGrid[my+GRID_WIDTH] = DOOR_TYPE_SECRET + 1;
- ySecretmPos = my;
- ySecretmPos = my+GRID_WIDTH;
- }
- }
- }
- }
- }
-
- }
-
- /****************************************************************************
- ** Locate a door from its Map coordinate and return the index to the **
- ** caller. **
- ** **
- ****************************************************************************/
- int FindDoor(int MapPosn,ACKENG *ae)
- {
- int index;
-
- for (index = 0; index < MAX_DOORS; index++)
- {
- if (MapPosn == ae->Door[index].mPos || MapPosn == ae->Door[index].mPos1)
- return(index);
- }
-
- return(-1);
- }
-
-
- /****************************************************************************
- ** Find an empty slot for a door. If the door already occupies a slot and **
- ** it is in a non-closed state then return error. **
- ** **
- ****************************************************************************/
- int FindDoorSlot(int MapPosn,ACKENG *ae)
- {
- int index;
-
- index = FindDoor(MapPosn,ae);
- if (index >= 0 && ae->Door[index].ColOffset)
- return(-1);
-
- for (index = 0; index < MAX_DOORS; index++)
- {
- if (ae->Door[index].mPos == -1)
- return(index);
-
- }
-
- return(-1);
- }
-
- /****************************************************************************
- ** The application performs this call to see if the POV is close enough to **
- ** a door to begin opening it. (A good time to make this call would be **
- ** when the POV moves). If a door is activated a return code tells the **
- ** application what kind of door it was (for purposes of sound, etc.) **
- ** **
- ****************************************************************************/
- int AckCheckDoorOpen(int xPlayer,int yPlayer,int PlayerAngle,ACKENG *ae)
- {
- int i,j,DoorCode;
-
- DoorCode = POV_NODOOR; /* Default - assumes no doors found */
-
- i = AckCheckHit(xPlayer,yPlayer,PlayerAngle,ae);
-
- /* Check secret doors along the X walls */
- if (i == 1 && ae->xGrid[xMapPosn] & DOOR_TYPE_SECRET)
- {
- if (xSecretColumn == 0)
- {
- DoorCode = POV_XSECRETDOOR;
-
- if (ae->xGrid[xMapPosn] & DOOR_LOCKED)
- return(DoorCode | POV_DOORLOCKED);
-
- xSecretmPos = xMapPosn;
- if (iLastX > xPlayer)
- {
- xSecretmPos1 = xMapPosn + 1;
- LastMapPosn = xMapPosn;
- xSecretColumn = 1;
- ae->yGrid[xMapPosn] = ae->yGrid[xMapPosn - GRID_WIDTH];
- }
- else
- {
- LastMapPosn = xSecretmPos1 = xMapPosn - 1;
- xSecretColumn = -1;
- ae->yGrid[xSecretmPos1] = ae->yGrid[xSecretmPos1 - GRID_WIDTH];
- }
- }
-
- }
-
- /* Check secret doors along the Y walls */
- if (i == 2 && ae->yGrid[yMapPosn] & DOOR_TYPE_SECRET)
- {
- if (ySecretColumn == 0)
- {
- DoorCode = POV_YSECRETDOOR;
-
- if (ae->yGrid[yMapPosn] & DOOR_LOCKED)
- return(DoorCode | POV_DOORLOCKED);
-
- ySecretmPos = yMapPosn;
- if (iLastY > yPlayer)
- {
- LastMapPosn = yMapPosn;
- ySecretmPos1 = yMapPosn + GRID_WIDTH;
- ae->xGrid[yMapPosn] = ae->xGrid[yMapPosn-1];
- ySecretColumn = 1;
- }
- else
- {
- LastMapPosn = ySecretmPos1 = yMapPosn - GRID_WIDTH;
- ae->xGrid[ySecretmPos1] = ae->xGrid[ySecretmPos1 - 1];
- ySecretColumn = -1;
- }
- }
- }
-
- /* Check doors along the X walls */
- if (i == 1 && (ae->xGrid[xMapPosn] & 0xFF) == DOOR_XCODE)
- {
- j = FindDoorSlot(xMapPosn,ae);
- if (j >= 0)
- {
- DoorCode = POV_XDOOR;
-
- LastMapPosn = ae->Door[j].mPos = xMapPosn;
- if ((int)iLastX > xPlayer)
- i = xMapPosn + 1;
- else
- LastMapPosn = i = xMapPosn - 1;
-
- if (ae->xGrid[xMapPosn] & DOOR_LOCKED)
- {
- ae->Door[j].mPos = -1;
- return(DoorCode | POV_DOORLOCKED);
- }
-
- ae->Door[j].mCode = ae->xGrid[xMapPosn];
- ae->Door[j].mCode1 = ae->xGrid[i];
- ae->Door[j].mPos1 = i;
- ae->Door[j].ColOffset = 1;
- ae->Door[j].Speed = ae->DoorSpeed;
- ae->Door[j].Type = DOOR_XCODE;
- ae->Door[j].Flags = DOOR_OPENING;
- }
- }
-
- /* Check doors along the Y walls */
- if (i == 2 && (ae->yGrid[yMapPosn] & 0xFF) == DOOR_YCODE)
- {
- j = FindDoorSlot(yMapPosn,ae);
- if (j >= 0)
- {
- DoorCode = POV_YDOOR;
- LastMapPosn = ae->Door[j].mPos = yMapPosn;
- if ((int)iLastY > yPlayer)
- i = yMapPosn + GRID_WIDTH;
- else
- LastMapPosn = i = yMapPosn - GRID_WIDTH;
-
- if (ae->yGrid[yMapPosn] & DOOR_LOCKED)
- {
- ae->Door[j].mPos = -1;
- return(DoorCode | POV_DOORLOCKED);
- }
-
- ae->Door[j].mCode = ae->yGrid[yMapPosn];
- ae->Door[j].mCode1 = ae->yGrid[i];
- ae->Door[j].mPos1 = i;
- ae->Door[j].ColOffset = 1;
- ae->Door[j].Speed = ae->DoorSpeed;
- ae->Door[j].Type = DOOR_YCODE;
- ae->Door[j].Flags = DOOR_OPENING;
- }
- }
-
- return(DoorCode);
- }
-
-