home *** CD-ROM | disk | FTP | other *** search
- /******************* ( Animation Construction Kit 3D ) ***********************/
- /* Utility 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 "xmslib.h"
-
- #define XMS_LOWVALUE 0x0280
- #define XMS_HIVALUE 0xA000
-
- /****************************************************************************
- ** Return the square root of a long value **
- ****************************************************************************/
- long long_sqrt(long v)
- {
- int i;
- unsigned long result,tmp;
- unsigned long low,high;
-
- if (v <= 1L) return((unsigned)v);
-
- low = v;
- high = 0L;
- result = 0;
-
- for (i = 0; i < 16; i++)
- {
- result += result;
- high = (high << 2) | ((low >>30) & 0x3);
- low <<= 2;
-
- tmp = result + result + 1;
- if (high >= tmp)
- {
- result++;
- high -= tmp;
- }
- }
-
- if (v - (result * result) >= (result - 1))
- result++;
-
- return(result);
- }
-
-
- /****************************************************************************
- ** The application can use this routine to read in a 768 byte palette **
- ** file and immediately set it in the video. PalName is the name of the **
- ** palette file to load. **
- ** **
- ****************************************************************************/
- int AckLoadAndSetPalette(char *PalName)
- {
- int handle,ErrCode;
- char *buf;
-
- buf = malloc(800);
- if (buf == NULL)
- return(ERR_NOMEMORY);
-
- ErrCode = 0;
- handle = open(PalName,O_RDWR|O_BINARY);
- if (handle > 0)
- {
- read(handle,buf,768);
- close(handle);
- AckSetPalette(buf);
- }
- else
- ErrCode = ERR_BADFILE;
-
- free(buf);
- return(ErrCode);
- }
-
- /****************************************************************************
- ** The application calls this routine to get the last object hit (from the **
- ** AckMovePOV() or AckMoveObjectPOV() routines. **
- ** **
- ****************************************************************************/
- int AckGetObjectHit(void)
- {
-
- return(LastObjectHit);
- }
-
- /****************************************************************************
- ** The application calls this routine to get the last wall hit (from the **
- ** AckMovePOV() or AckMoveObjectPOV() routines. **
- ** **
- ****************************************************************************/
- int AckGetWallHit(void)
- {
-
- return(LastMapPosn);
- }
-
-
- /****************************************************************************
- ** The application calls this routine to make an object invisible. The **
- ** object and object bitmaps are NOT deleted. Currently the active flag **
- ** is set to zero however, future versions may do more in the routine so **
- ** it would be a good idea for the application to call here instead of **
- ** setting the active flag to zero on its own. **
- ** **
- ****************************************************************************/
- int AckDeleteObject(ACKENG *ae,int ObjIndex)
- {
- int MapPosn;
-
-
- if (!ae->ObjList[ObjIndex].Active)
- return(-1);
-
- ae->ObjList[ObjIndex].Active = 0;
-
- return(0);
- }
-
- /****************************************************************************
- ** The purpose of this routine is to replace an existing bitmap with a **
- ** new one. The old bitmap is freed and the new one is put into place in **
- ** the specified bitmap array. **
- ** **
- ** index is the number of the bitmap array to replace **
- ** Maps is the bitmap array **
- ** NewBitmap is a pointer to the new bitmap to use **
- ** **
- ****************************************************************************/
- int AckSetNewBitmap(int index,UCHAR far **Maps,UCHAR far *NewBitmap)
- {
- int i;
- UCHAR far *bPtr;
-
- bPtr = Maps[index];
- if (FP_SEG(bPtr) < XMS_HIVALUE && FP_SEG(bPtr) > XMS_LOWVALUE)
- {
- if (bPtr == NewBitmap)
- return(0);
-
- free(bPtr);
- Maps[index] = NewBitmap;
- return(0);
- }
-
- #if USE_XMS
- XMSput((XMSHANDLE)bPtr,NewBitmap,BITMAP_SIZE);
-
- for (i = 0; i < MAX_XARRAY; i++)
- {
- if (bPtr == (UCHAR far *)xArray[i].xHandle)
- {
- memmove(xArray[i].Bmp,NewBitmap,BITMAP_SIZE);
- }
- }
- #endif
-
- return(0);
- }
-
-
- /****************************************************************************
- ** This routine should be called for all wall and object bitmaps when using**
- ** XMS memory. It will copy the bitmap from XMS to a real memory array **
- ** buffer which is then passed back to the caller. It checks for a buffer **
- ** that has the smallest usage count (an empty one would have zero), to **
- ** copy the XMS memory into. XMS handles have been observed to have a seg **
- ** value of > A000H or < 100H (which hopefully will be true all the time!) **
- ****************************************************************************/
- UCHAR far *AckGetBitmapPtr(int index,UCHAR far **Maps)
- {
- int i,min,Lasti;
- UCHAR far *bPtr;
-
- bPtr = Maps[index];
-
- #if USE_XMS
- if (FP_SEG(bPtr) < XMS_HIVALUE && FP_SEG(bPtr) > XMS_LOWVALUE)
- return(bPtr);
-
- min = 32000;
- Lasti = -1;
-
- for (i = 0; i < MAX_XARRAY; i++)
- {
- if (bPtr == (UCHAR far *)xArray[i].xHandle)
- {
- xArray[i].count++;
- return(xArray[i].Bmp);
- }
-
- if (xArray[i].count < min)
- {
- min = xArray[i].count;
- Lasti = i;
- }
- }
-
- if (Lasti == -1)
- {
- XMSget(BitmapXferPtr,(XMSHANDLE)bPtr);
- return(BitmapXferPtr);
- }
-
- XMSget(xArray[Lasti].Bmp,(XMSHANDLE)bPtr);
- xArray[Lasti].count = 1;
- xArray[Lasti].xHandle = (ULONG)bPtr;
-
- return(xArray[Lasti].Bmp);
- #else
- return(bPtr);
- #endif
- }
-
-
- #define LOCK_MAX 20
-
- typedef struct {
- XMSHANDLE xHandle;
- UCHAR far *Bmp;
- } LOCKLIST;
-
-
- LOCKLIST LockTable[LOCK_MAX+1];
-
-
- /****************************************************************************
- ** This routine loads an XMS bitmap into memory for use by the app. If the **
- ** bitmap is not in XMS then the bitmap pointer itself is returned. **
- ** **
- ****************************************************************************/
- UCHAR far *AckLockPtr(UCHAR far *bPtr)
- {
- int i,uFlag;
- UCHAR far *bmp;
-
-
- #if USE_XMS
- uFlag = 0;
-
- if (FP_SEG(bPtr) < XMS_HIVALUE && FP_SEG(bPtr) > XMS_LOWVALUE)
- return(bPtr);
-
- bmp = malloc(BITMAP_SIZE);
- if (bmp == NULL)
- return(bmp);
-
- XMSget(bmp,(XMSHANDLE)bPtr);
-
- for (i = 0; i < LOCK_MAX; i++)
- {
- if (LockTable[i].Bmp == NULL)
- {
- LockTable[i].Bmp = bmp;
- LockTable[i].xHandle = (XMSHANDLE)bPtr;
- uFlag = 1;
- break;
- }
- }
-
- if (!uFlag)
- {
- LockTable[0].Bmp = bmp;
- LockTable[0].xHandle = (XMSHANDLE)bPtr;
- }
- return(bmp);
- #else
- return(bPtr);
- #endif
-
- }
-
-
- /****************************************************************************
- ** This routine frees up a previously locked pointer. If the pointer is **
- ** not in XMS then no action is taken. **
- ** **
- ****************************************************************************/
- int AckUnlockPtr(UCHAR far *bPtr)
- {
- int i,j;
-
-
- #if USE_XMS
-
- for (i = 0; i < LOCK_MAX; i++)
- {
- if (LockTable[i].Bmp == bPtr)
- {
- XMSput(LockTable[i].xHandle,bPtr,BITMAP_SIZE);
-
- for (j = 0; j < MAX_XARRAY; j++)
- {
- if (xArray[j].xHandle == LockTable[i].xHandle)
- {
- memmove(xArray[j].Bmp,bPtr,BITMAP_SIZE);
- break;
- }
- }
-
- free(LockTable[i].Bmp);
- LockTable[i].Bmp = NULL;
- return(0);
- }
- }
-
- return(-1);
- #else
- return(0);
- #endif
- }
-
-
- /****************************************************************************
- ** This routine creates a new bitmap buffer (in real or XMS memory) and **
- ** copies the supplied bitmap into it. The return pointer is either an **
- ** XMS handle or a pointer to the real memory. **
- ** **
- ****************************************************************************/
- UCHAR far *AckCopyNewBitmap(UCHAR far *bPtr)
- {
- UCHAR far *bmp;
- #if USE_XMS
- XMSHANDLE xPtr;
-
- if (UseXMS > 0)
- {
- xPtr = XMSalloc(BITMAP_SIZE);
- if (xPtr != XMSHNULL)
- {
- if (FP_SEG(bPtr) > XMS_HIVALUE || FP_SEG(bPtr) < XMS_LOWVALUE)
- XMSget(BitmapXferPtr,(XMSHANDLE)bPtr);
- else
- memmove(BitmapXferPtr,bPtr,BITMAP_SIZE);
-
- XMSput(xPtr,BitmapXferPtr,BITMAP_SIZE);
- return((UCHAR far *)xPtr);
- }
- else
- {
- bmp = malloc(BITMAP_SIZE);
- if (bmp)
- memmove(bmp,bPtr,BITMAP_SIZE);
- return(bmp);
- }
-
- }
- else
- {
- bmp = malloc(BITMAP_SIZE);
- if (bmp)
- memmove(bmp,bPtr,BITMAP_SIZE);
- return(bmp);
- }
- #else
- bmp = malloc(BITMAP_SIZE);
- if (bmp)
- memmove(bmp,bPtr,BITMAP_SIZE);
- return(bmp);
- #endif
-
- }
-
- /****************************************************************************
- ** This routine frees the memory used by a bitmap in either real or XMS **
- ** memory. **
- ** **
- ****************************************************************************/
- int AckFreeBitmap(UCHAR far *Bmp)
- {
- int i;
-
- #if USE_XMS
-
- if (FP_SEG(Bmp) > XMS_HIVALUE || FP_SEG(Bmp) < XMS_LOWVALUE)
- {
- for (i = 0; i < MAX_XARRAY; i++)
- {
- if (xArray[i].xHandle == (XMSHANDLE)Bmp)
- {
- xArray[i].count = 0;
- xArray[i].Bmp = XMSHNULL;
- break;
- }
-
- }
-
- XMSfree((XMSHANDLE)Bmp);
-
- }
- else
- free(Bmp);
-
- #else
- free(Bmp);
- #endif
-
- return(0);
- }
-