home *** CD-ROM | disk | FTP | other *** search
- /******************* ( Animation Construction Kit 3D ) ***********************/
- /* Initialization 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"
- #include "xtypes.h"
- #include "xmslib.h"
-
- int BuildAckTables(ACKENG *ae);
- int ReadAckMapFile(char *fName);
- void AckBuildHeightTables(ACKENG *ae);
- void BuildAckGrid(ACKENG *ae);
-
- /****************************************************************************
- ** This **MUST** be the first routine called by the application to setup **
- ** the ACK engine. See the file ACK3D.DOC for what fields need to be **
- ** setup by the application prior to making this call. **
- ** **
- ****************************************************************************/
- int AckInitialize(ACKENG *ae)
- {
- int i,result = 0;
-
- if (!ae->WinEndY ||
- !ae->WinEndX ||
- (ae->WinEndY - ae->WinStartY) < 10 ||
- (ae->WinEndX - ae->WinStartX) < 10)
- {
- return(ERR_BADWINDOWSIZE);
- }
-
-
- result = BuildAckTables(ae); /* Read in TRIG.DAT and allocate tables */
- if (result)
- return(result);
-
- ae->CenterRow = ae->WinStartY + ((ae->WinEndY - ae->WinStartY) / 2);
- ae->WinStartOffset = ae->WinStartY * BYTES_PER_ROW;
- ae->WinLength = ((ae->WinEndY - ae->WinStartY)+1) * DWORDS_PER_ROW;
- ae->WinWidth = (ae->WinEndX - ae->WinStartX) + 1;
- ae->WinHeight = (ae->WinEndY - ae->WinStartY) + 1;
-
- AckBuildHeightTables(ae); /* Build height and adjustment tables */
-
- UseXMS = 0;
-
- #if USE_XMS
- if (XMSinstalled() != FALSE)
- {
- if (XMSopen(1600) != FALSE)
- UseXMS = 1;
- else
- if (XMSopen(0) != FALSE)
- UseXMS = 1;
-
- if (UseXMS)
- {
- for (i = 0; i < MAX_XARRAY; i++)
- {
- xArray[i].Bmp = (UCHAR far *)malloc(BITMAP_SIZE);
- if (xArray[i].Bmp == NULL)
- {
- XMSclose();
- return(ERR_NOMEMORY);
- }
- xArray[i].count = 0;
- }
- }
- }
- #endif
-
- return(result);
- }
-
- /****************************************************************************
- ** Internal call to read in the TRIG.DAT file. **
- ** **
- ****************************************************************************/
- int BuildAckTables(ACKENG *ae)
- {
- int handle,len,ca,na;
- long fAng;
-
- handle = open("trig.dat",O_RDWR|O_BINARY); /* Does file exist */
- if (handle < 1)
- return(ERR_BADFILE);
-
- LongTanTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
- LongInvTanTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
- CosTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
- SinTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
- InvSinTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
- InvCosTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
- LongCosTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
- xNextTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
- yNextTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
- ViewCosTable = (long far *)malloc(sizeof(long) * VIEW_WIDTH);
-
- Grid = (unsigned int far *)malloc((GRID_MAX * 2)+1);
- ObjGrid = (unsigned int far *)malloc((GRID_MAX * 2)+1);
-
- AdjustTable = (long far *)malloc((MAX_DISTANCE+1) * sizeof(long));
-
- len = ((ae->WinEndY - ae->WinStartY) + 1) * BYTES_PER_ROW;
- ae->BkgdBuffer = (UCHAR far *)malloc(len);
- ae->ScreenBuffer = (UCHAR far *)malloc(SCREEN_SIZE);
-
- BitmapXferPtr = (UCHAR far *)malloc(BITMAP_SIZE+1);
-
- if (LongTanTable == NULL ||
- LongInvTanTable == NULL ||
- CosTable == NULL ||
- SinTable == NULL ||
- InvSinTable == NULL ||
- InvCosTable == NULL ||
- LongCosTable == NULL ||
- xNextTable == NULL ||
- yNextTable == NULL ||
- Grid == NULL ||
- ObjGrid == NULL ||
- AdjustTable == NULL ||
- ae->BkgdBuffer == NULL ||
- ae->ScreenBuffer == NULL ||
- BitmapXferPtr == NULL ||
- ViewCosTable == NULL)
- {
- close(handle);
- return(ERR_NOMEMORY);
- }
-
- memset(ae->BkgdBuffer,0,len);
- memset(ae->ScreenBuffer,0,SCREEN_SIZE);
-
- len = sizeof(long) * INT_ANGLE_360;
-
- read(handle,SinTable,len);
- read(handle,CosTable,len);
- read(handle,LongTanTable,len);
- read(handle,LongInvTanTable,len);
- read(handle,InvCosTable,len);
- read(handle,InvSinTable,len);
- read(handle,LongCosTable,len);
-
- close(handle);
-
- ca = INT_ANGLE_30;
- na = -1;
-
- for (len = 0; len < VIEW_WIDTH; len++)
- {
- ViewCosTable[len] = LongCosTable[ca];
- ca += na;
- if (ca <= 0)
- {
- ca = -ca;
- na = -na;
- }
- }
-
- for (len = 0; len < INT_ANGLE_360; len++)
- {
- yNextTable[len] = (long)GRID_SIZE * LongTanTable[len];
- xNextTable[len] = (long)GRID_SIZE * LongInvTanTable[len];
- }
-
- return(0);
- }
-
- /****************************************************************************
- ** This routine is called by the application to read in an ACK map file. **
- ** The map file consist of 4096 integers for the walls followed by 4096 **
- ** integers for the objects. **
- ** **
- ****************************************************************************/
- int AckReadMapFile(ACKENG *ae,char *fName)
- {
- int len,handle,rdlen;
-
-
- handle = open(fName,O_RDWR|O_BINARY);
- if (handle < 1)
- return(ERR_BADMAPFILE);
-
- rdlen = GRID_MAX * 2;
-
- len = read(handle,Grid,rdlen);
-
- if (len == rdlen)
- len = read(handle,ObjGrid,rdlen);
-
- close(handle);
-
- if (len != rdlen)
- return(ERR_READINGMAP);
-
- BuildAckGrid(ae); /* Build wall and object XY grids */
-
- return(0);
- }
-
- /****************************************************************************
- ** Internal call used to create the distance tables. Currently the distance**
- ** table is only used for the widths of objects. **
- ** **
- ****************************************************************************/
- void AckBuildHeightTables(ACKENG *ae)
- {
- int i,x;
- int result;
- long height;
-
- height = 18000 - ((ae->WinEndY - ae->WinStartY) * 70);
-
- DistanceTable[0] = MAX_HEIGHT;
-
- /************** 64 * 65536 ************/
- AdjustTable[0] = 4194304L / height;
-
- for (i = 1; i < MAX_DISTANCE; i++)
- {
- DistanceTable[i] = height / i;
- if (height - (DistanceTable[i] * i) > (i / 2))
- DistanceTable[i]++;
-
- if (DistanceTable[i] < MIN_HEIGHT)
- DistanceTable[i] = MIN_HEIGHT;
-
- if (DistanceTable[i] > MAX_HEIGHT)
- DistanceTable[i] = MAX_HEIGHT;
-
- #if 0
- AdjustTable[i] = 4194304L / DistanceTable[i];
- #endif
- AdjustTable[i] = 2097152L / DistanceTable[i];
-
-
- }
-
-
- for (i = ae->WinStartX; i < ae->WinEndX; i++)
- Walls[i].LightAdj = 0;
-
- }
-
- UCHAR LightArray[] = {255,64,128,192,0,64,128,192,0,64,128,192,0,64,128};
-
-
- /****************************************************************************
- ** Internal call used to process the map file into the wall and object **
- ** arrays. The application can use the map file for initial placement of **
- ** objects if desired or can setup objects itself once the map file is **
- ** processed. **
- ** **
- ****************************************************************************/
- void BuildAckGrid(ACKENG *ae)
- {
- int i,j,CurIndex,pos,x1,y1;
- UINT MapCode;
-
- for (i = 0; i < MAX_DOORS; i++)
- {
- ae->Door[i].ColOffset = 0;
- ae->Door[i].mPos = ae->Door[i].mPos1 = -1;
- }
-
- i = (GRID_WIDTH+1) * (GRID_HEIGHT+1);
- memset(ae->xGrid,0,i);
- memset(ae->yGrid,0,i);
-
- CurIndex = 1;
- TotalSpecial = 0;
- TotalSecret = 0;
-
- for (i = 0; i < GRID_HEIGHT; i++)
- {
- for (j = 0; j < GRID_WIDTH; j++)
- {
- pos = (i * GRID_WIDTH) + j;
- MapCode = Grid[pos];
-
- if (MapCode == MAP_STARTCODE)
- {
- ae->yPlayer = pos & 0xFFC0;
- ae->xPlayer = (pos - ae->yPlayer) << 6;
- ae->yPlayer += 32;
- ae->xPlayer += 32;
- continue;
- }
-
- if (MapCode == MAP_UPCODE ||
- MapCode == MAP_DOWNCODE ||
- MapCode == MAP_GOALCODE)
- {
- SpecialCodes[TotalSpecial].mPos = pos;
- SpecialCodes[TotalSpecial++].mCode = MapCode;
- continue;
- }
-
- if (MapCode) /* Something is in map */
- {
-
- if ((MapCode & 0xFF) != DOOR_YCODE)
- {
- if (ae->xGrid[pos] != DOOR_SIDECODE)
- ae->xGrid[pos] = MapCode;
-
- ae->xGrid[pos+1] = MapCode;
- }
- else
- {
- ae->xGrid[pos] = DOOR_SIDECODE;
- ae->xGrid[pos+1] = DOOR_SIDECODE;
- }
-
- if ((MapCode & 0xFF) != DOOR_XCODE)
- {
- if (ae->yGrid[pos] != DOOR_SIDECODE)
- ae->yGrid[pos] = MapCode;
- ae->yGrid[pos+GRID_WIDTH] = MapCode;
- }
- else
- {
- ae->yGrid[pos] = DOOR_SIDECODE;
- ae->yGrid[pos+GRID_WIDTH] = DOOR_SIDECODE;
- }
- }
-
- MapCode = ObjGrid[pos];
- if (MapCode)
- {
- CurIndex = MapCode & 0x7F;
- if (CurIndex < MAX_OBJECTS)
- {
- x1 = (j << 6) + 32; /* Place object in center of */
- y1 = (i << 6) + 32; /* the current map square */
- ae->ObjList[CurIndex].x = x1;
- ae->ObjList[CurIndex].y = y1;
- ae->ObjList[CurIndex].mPos = pos;
- ae->ObjList[CurIndex].VidRow = ae->CenterRow;
- ae->ObjList[CurIndex].Active = 1;
- }
- }
- }
- }
-
- j = 0;
- for (i = 0; i < GRID_MAX; i++)
- {
- LightMap[i] = LightArray[j];
- }
-
- }
-
-
-