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)
296 lines
7 KiB
C
296 lines
7 KiB
C
#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 ****
|
||
|
||
|