ack3d/ack_lib/ACKUTIL.C
Gered 865b466995 initial commit
sources taken from book CD:

ack_lib -> /ACK/WIN/ACK_LIB
fdemo -> /ACK/DOS/FDEMO/SOURCE (and /ACK/DOS/BORLAND as needed)
mall -> /ACK/DOS/MALL/SOURCE (and /ACK/DOS/BORLAND as needed)

some source files were missing for the demo projects and needed to be
copied from /ACK/DOS/BORLAND (as indicated above)
2019-11-02 13:17:24 -04:00

296 lines
7 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
#include <mem.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"
typedef struct {
int sel;
int off;
} SELOFF;
void AckGetIntVector(int VecNum,int *sel,int *off);
void AckSetIntVector(int VecNum,int sel,void *VecOff);
void AckKbdInt(void);
void AckTimerHandler(void);
void AckSetTextMode(void);
long AckMemUsed;
short AckDisplayErrors;
SELOFF OldKeybdInt;
char AckKeyboardSetup;
SELOFF OldTimerInt;
char AckTimerSetup;
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
// Establish a hook into interrupt 9 for keyboard handling
// The application can access which key is pressed by looking at the
// AckKeys global array
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
#ifndef _MSC_VER
void AckSetupKeyboard(void)
{
AckGetIntVector(9,&OldKeybdInt.sel,&OldKeybdInt.off);
AckSetIntVector(9,_CS,AckKbdInt);
AckKeyboardSetup = 1;
}
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
// Establish a hook into the user timer interrupt
// The application can access a counter by looking at the AckTimerCounter
// global variable.
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
void AckSetupTimer(void)
{
AckGetIntVector(0x1C,&OldTimerInt.sel,&OldTimerInt.off);
AckSetIntVector(0x1C,_CS,AckKbdInt);
AckTimerSetup = 1;
}
#endif
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
// Utility routine used to track memory usage by the ACK engine and
// applications.
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
void *AckMalloc(size_t mSize)
{
UCHAR *mBlock;
mSize += sizeof(long);
mSize++;
mBlock = malloc(mSize);
if (mBlock == NULL)
{
if (AckDisplayErrors)
{
AckSetTextMode();
printf("\n\nOut of memory on call to AckMalloc.\n");
printf("Memory used: %ld bytes.\n",AckMemUsed);
}
return(mBlock);
}
(*(UCHAR *)mBlock) = 0xF2;
mBlock += 1;
(*(long *)mBlock) = mSize;
mBlock += sizeof(long);
AckMemUsed += mSize;
return(mBlock);
}
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
// Matching routine for AckMalloc(). This routine MUST be used to free
// memory if AckMalloc() is used to allocate memory.
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
void AckFree(void *m)
{
UCHAR *mBlock;
long mSize;
mBlock = (UCHAR *)m;
mBlock -= sizeof(long);
mBlock -= 1;
if ((*(UCHAR *)mBlock) != 0xF2)
{
if (AckDisplayErrors)
{
AckSetTextMode();
printf("\n\nCorrupt memory block in AckFree.\n");
printf("Mem ptr: %p",mBlock);
return;
}
}
mBlock += 1;
mSize = (*(long *)mBlock);
mBlock -= 1;
AckMemUsed -= mSize;
free(mBlock);
}
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
// Read a palette from a file and immediately set it into the VGA regs.
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
short AckLoadAndSetPalette(char *PalName)
{
short handle,ErrCode;
char *buf;
buf = AckMalloc(800);
if (buf == NULL)
return(ERR_NOMEMORY);
ErrCode = 0;
if (!rsHandle)
handle = _lopen(PalName,O_RDWR|O_BINARY);
else
{
handle = rsHandle;
_llseek(handle,rbaTable[(ULONG)PalName],SEEK_SET);
}
if (handle > 0)
{
read(handle,buf,768);
if (!rsHandle)
_lclose(handle);
memset(buf,0,3); // Make sure color 0 is always black
AckSetPalette(buf);
}
else
ErrCode = ERR_BADFILE;
AckFree(buf);
return(ErrCode);
}
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
// Set up the palette range for light shading. The incoming ranges are in
// a 16 by 256 array where there are 16 different distance levels each
// having a full color tranlation table for light shading.
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
void AckSetupPalRanges(ACKENG *ae,ColorRange *ranges)
{
short i,j,k,found;
short rangenos;
UCHAR plotcolor;
if (ae->LightFlag == SHADING_OFF)
{
for ( i = 0;i<16;i++)
{
for (j=0;j<256;j++)
{
ae->PalTable[j+(i*256)] = j;
}
}
return;
}
for (rangenos = 0; rangenos < 64; rangenos++)
{
if (ranges[rangenos].start == 0)
break;
}
for ( i = 0;i<16;i++)
{
for (j=0;j<256;j++)
{
found = 0;
// find the range the color is in.
for ( k = 0; k < rangenos; k++ )
{
if (j >= ranges[k].start && j < ranges[k].start+ranges[k].length)
{
found = 1;
break;
}
}
if (found)
{
//=============================================================================
// add color + i;
// if color + i > color+range then plot color = 0;
// otherwise plotcolor = color+i
//=============================================================================
if (j+i >= ranges[k].start+ranges[k].length)
plotcolor = 0;
else
plotcolor = j+i;
}
else
{
plotcolor = j;
}
ae->PalTable[j+(i*256)] = plotcolor;
}
}
}
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
// Returns the index of the last object hit by the POV.
// The variable LastObjectHit can also be accessed globally.
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
short AckGetObjectHit(void)
{
return(LastObjectHit);
}
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
// Returns the map location of the last wall hit. LastMapPosn is a global
// variable.
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
short AckGetWallHit(void)
{
return(LastMapPosn);
}
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
// Sets the object to inactive. The memory used by the object is NOT
// freed by this routine.
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
short AckDeleteObject(ACKENG *ae,short ObjIndex)
{
if (ae->ObjList[ObjIndex] == NULL)
return(-1);
if (!ae->ObjList[ObjIndex]->Active)
return(-1);
ae->ObjList[ObjIndex]->Active = 0;
return(0);
}
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
// Sets a new wall or object index into the map array specified.
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
short AckSetNewBitmap(short index,UCHAR **Maps,UCHAR *NewBitmap)
{
UCHAR *bPtr;
bPtr = Maps[index];
Maps[index] = NewBitmap;
if (bPtr != NULL)
AckFree(bPtr);
return(0);
}
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
// Obsolete routine for real mode. Flat model memory can be freed by the
// application. Real mode required XMS memory to be handled. This routine
// is maintained for backward compatability with the older versions.
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
short AckFreeBitmap(UCHAR *bmType)
{
short i;
UCHAR *Bmp;
if (bmType != NULL)
AckFree(bmType);
return(0);
}
// **** End of Source ****