2204 lines
44 KiB
C
2204 lines
44 KiB
C
// Quick demo of walking around in a Mall using ACK-3D Kit
|
|
// Started: 06/25/94
|
|
// Author: Lary Myers
|
|
// Module: MALL.C
|
|
// (c) CopyRight 1994 All Rights Reserved
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <malloc.h>
|
|
#include <mem.h>
|
|
#include <string.h>
|
|
#include <dos.h>
|
|
#include <time.h>
|
|
#include <io.h>
|
|
#include <fcntl.h>
|
|
#include <sys\stat.h>
|
|
#include "ack3d.h"
|
|
#include "ackeng.h"
|
|
#include "ackext.h"
|
|
#include "kit.h"
|
|
#include "modplay.h"
|
|
|
|
#define DEMO_RESOURCE 69
|
|
#define HAND1_RESOURCE 135
|
|
#define HAND2_RESOURCE 136
|
|
|
|
#define KEYBD 0x9 /* INTERRUPT 9 */
|
|
#define RIGHT_ARROW_KEY 77
|
|
#define UP_ARROW_KEY 72
|
|
#define LEFT_ARROW_KEY 75
|
|
#define DOWN_ARROW_KEY 80
|
|
#define MINUS_KEY 74
|
|
#define PLUS_KEY 78
|
|
#define NUMBER_5_KEY 76
|
|
#define ESCAPE_KEY 1
|
|
#define PGUP_KEY 73
|
|
#define PGDN_KEY 81
|
|
#define B_KEY 48
|
|
#define C_KEY 46
|
|
#define F_KEY 33
|
|
#define I_KEY 23
|
|
#define R_KEY 19
|
|
#define S_KEY 31
|
|
#define W_KEY 17
|
|
#define NUM_1_KEY 2
|
|
#define NUM_2_KEY 3
|
|
#define NUM_3_KEY 4
|
|
#define NUM_4_KEY 5
|
|
#define NUM_5_KEY 6
|
|
#define NUM_6_KEY 7
|
|
#define NUM_7_KEY 8
|
|
#define NUM_8_KEY 9
|
|
#define NUM_9_KEY 10
|
|
|
|
typedef struct {
|
|
int mdx;
|
|
int mdy;
|
|
int mButtons;
|
|
} MOUSE;
|
|
|
|
#define MAX_AMOUNT 64
|
|
#define MAX_MAG_AMOUNT 64
|
|
#define MAX_STR_AMOUNT 128
|
|
#define MAX_STR_HALF_AMOUNT 64
|
|
|
|
extern long mFactor;
|
|
extern long dFactor;
|
|
|
|
extern UCHAR colordat[];
|
|
|
|
ACKENG *ae;
|
|
|
|
// These are the ranges used for distance shading. Will need to be modified
|
|
// for the new color palette used.
|
|
ColorRange ranges[64] = {
|
|
16,15,
|
|
32,16,
|
|
48,16,
|
|
64,16,
|
|
80,16,
|
|
96,8,
|
|
104,8,
|
|
112,8,
|
|
120,8,
|
|
128,8,
|
|
136,8,
|
|
144,8,
|
|
152,8,
|
|
160,8,
|
|
168,8,
|
|
176,8,
|
|
184,16,
|
|
200,16,
|
|
216,16,
|
|
232,16,
|
|
248,16,
|
|
0,0
|
|
};
|
|
|
|
|
|
|
|
int HaveMouse;
|
|
short FlashIndex;
|
|
short FlashCount;
|
|
UCHAR *bmFlash[2];
|
|
UCHAR *bmFlash1[2];
|
|
char LineBuffer[200];
|
|
char *smFont;
|
|
UCHAR FontTransparent;
|
|
UCHAR FontColor;
|
|
UCHAR TextBGcolor;
|
|
int Throwing;
|
|
int Shooting;
|
|
int ShutDownFlag;
|
|
short MagAmount;
|
|
short StrAmount;
|
|
int ShowHitFlag;
|
|
int MapResource;
|
|
int PalResource;
|
|
int ResScreenBack;
|
|
int ResScrollBack;
|
|
void *BGmusic;
|
|
|
|
UCHAR *DemoPtr;
|
|
short Demoht;
|
|
short Demowt;
|
|
UCHAR *pHand1;
|
|
short Handw1;
|
|
short Handh1;
|
|
UCHAR *pHand2;
|
|
short Handw2;
|
|
short Handh2;
|
|
|
|
long ObjCounter[64];
|
|
|
|
short LastObjectIndex;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Globals used by the frame counting routines
|
|
//-----------------------------------------------------------------------------
|
|
volatile short framespersec = 0;
|
|
volatile short cframes=0, count=0, ticks=0;
|
|
|
|
char *ErrorMsgs[] = {
|
|
"ERR_BADFILE ",
|
|
"ERR_BADCOMMAND ",
|
|
"ERR_BADOBJNUMBER ",
|
|
"ERR_BADSYNTAX ",
|
|
"ERR_LOADINGBITMAP",
|
|
"ERR_BADDIRECTION ",
|
|
"ERR_BADSTARTX ",
|
|
"ERR_BADSTARTY ",
|
|
"ERR_BADANGLE ",
|
|
"ERR_BADMAPFILE ",
|
|
"ERR_READINGMAP ",
|
|
"ERR_BADPICNAME ",
|
|
"ERR_INVALIDFORM ",
|
|
"ERR_NOPBM ",
|
|
"ERR_BADPICFILE ",
|
|
"ERR_NOMEMORY ",
|
|
"ERR_BADPALFILE ",
|
|
"ERR_BADWINDOWSIZE",
|
|
"ERR_TOMANYVIEWS ",
|
|
"ERR_BADOBJECTNUM ",
|
|
"ERR_BADOBJTYPE "
|
|
};
|
|
|
|
|
|
|
|
short ModSound; // 0 = Off, 1 = On
|
|
short ModPort; // Port of SB card
|
|
short ModIRQ; // IRQ number of SB card
|
|
short ModDMA; // DMA channel of SB card
|
|
char ModName[128]; // Filename of MOD file to read
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
char *StripEndOfLine(char *s)
|
|
{
|
|
int len;
|
|
char ch;
|
|
|
|
len = strlen(s);
|
|
|
|
while (--len >= 0)
|
|
{
|
|
ch = s[len];
|
|
if (ch != ' ' && ch != ';' && ch != '\t' && ch != 13 && ch != 10)
|
|
break;
|
|
|
|
s[len] = '\0';
|
|
}
|
|
|
|
return(s);
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
short atoHex(char *s)
|
|
{
|
|
short value;
|
|
char ch;
|
|
|
|
value = 0;
|
|
|
|
while (*s)
|
|
{
|
|
ch = toupper(*s++);
|
|
if (ch == ' ' || ch == '\t' || ch == ',')
|
|
continue;
|
|
|
|
if (ch < '0') break;
|
|
if (ch > 'F') break;
|
|
if (ch > '9' && ch < 'A')
|
|
break;
|
|
|
|
value <<= 4;
|
|
if (ch >= 'A') ch -= 7;
|
|
ch -= '0';
|
|
value |= ch;
|
|
}
|
|
|
|
|
|
return(value);
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
void ReadConfigFile(void)
|
|
{
|
|
FILE *fp;
|
|
char *s;
|
|
char rBuf[128];
|
|
|
|
ModSound = 0;
|
|
ModPort = 0x220;
|
|
ModIRQ = 5;
|
|
ModDMA = 1;
|
|
strcpy(ModName,"MALL.MOD");
|
|
|
|
fp = fopen("ack3d.cfg","rt");
|
|
if (fp == NULL)
|
|
return;
|
|
|
|
while (1)
|
|
{
|
|
if (feof(fp))
|
|
break;
|
|
|
|
*rBuf = '\0';
|
|
fgets(rBuf,125,fp);
|
|
if (*rBuf == ';')
|
|
continue;
|
|
|
|
if (!strnicmp(rBuf,"SOUND:",6))
|
|
{
|
|
s = SkipSpaces(&rBuf[6]);
|
|
if (!strnicmp(s,"ON",2))
|
|
ModSound = 1;
|
|
else
|
|
ModSound = 0;
|
|
|
|
continue;
|
|
}
|
|
|
|
if (!strnicmp(rBuf,"SBPORT:",7))
|
|
{
|
|
ModPort = atoHex(&rBuf[7]);
|
|
continue;
|
|
}
|
|
|
|
if (!strnicmp(rBuf,"SBIRQ:",6))
|
|
{
|
|
ModIRQ = atoi(&rBuf[6]);
|
|
continue;
|
|
}
|
|
|
|
if (!strnicmp(rBuf,"SBDMA:",6))
|
|
{
|
|
ModDMA = atoi(&rBuf[6]);
|
|
continue;
|
|
}
|
|
|
|
if (!strnicmp(rBuf,"SOUNDFILE:",10))
|
|
{
|
|
s = SkipSpaces(&rBuf[10]);
|
|
strcpy(ModName,s);
|
|
StripEndOfLine(ModName);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
/* MOD loading routines */
|
|
void *MODLoadModule(char *Path)
|
|
{
|
|
int handle;
|
|
unsigned modsize;
|
|
void *modfile = NULL;
|
|
if ((handle = open(Path,O_RDONLY | O_BINARY)) != -1) {
|
|
modsize = lseek(handle,0L,SEEK_END);
|
|
lseek(handle,0L,SEEK_SET);
|
|
if ((modfile=(void*)AckMalloc(modsize)) != NULL) {
|
|
if (read(handle,modfile,modsize) != modsize) {
|
|
AckFree(modfile);
|
|
modfile = NULL;
|
|
}
|
|
}
|
|
close(handle);
|
|
}
|
|
return modfile;
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
void MODFreeModule(void *Module)
|
|
{
|
|
if (Module) AckFree(Module);
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
short StartBGmusic(void)
|
|
{
|
|
if (!ModSound)
|
|
return(1);
|
|
|
|
if ((BGmusic = MODLoadModule(ModName)) == NULL)
|
|
return(-1);
|
|
|
|
//if (MODPlayModule(BGmusic,5,22000,0x220,7,1))
|
|
if (MODPlayModule(BGmusic,5,22000,ModPort,ModIRQ,ModDMA))
|
|
return(-2);
|
|
|
|
return(0);
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
void EndBGmusic(void)
|
|
{
|
|
|
|
if (!ModSound)
|
|
return;
|
|
|
|
if (BGmusic == NULL)
|
|
return;
|
|
|
|
MODStopModule();
|
|
MODFreeModule(BGmusic);
|
|
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
short LoadSmallFont(void)
|
|
{
|
|
short ht,wt;
|
|
int len;
|
|
|
|
ht = 2;
|
|
smFont = AckReadiff((UCHAR *)ht);
|
|
if (smFont == NULL)
|
|
return(-1);
|
|
|
|
ht = (*(short *)smFont);
|
|
wt = (*(short *)&smFont[2]);
|
|
len = ht * wt;
|
|
memmove(smFont,&smFont[4],len);
|
|
|
|
return(0);
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
void smWriteChar(short x,short y,unsigned char ch)
|
|
{
|
|
int FontOffset,VidOffset;
|
|
int row,col;
|
|
UCHAR *Video;
|
|
|
|
VidOffset = (y * 320) + x;
|
|
Video = (UCHAR *)0xA0000;
|
|
Video += VidOffset;
|
|
FontOffset = ((ch-32) * 5);
|
|
|
|
if (FontTransparent)
|
|
Video = ae->ScreenBuffer + VidOffset;
|
|
|
|
for (row = 0; row < 5; row++)
|
|
{
|
|
if (!FontTransparent)
|
|
{
|
|
Video[0] = TextBGcolor;
|
|
Video[1] = TextBGcolor;
|
|
Video[2] = TextBGcolor;
|
|
Video[3] = TextBGcolor;
|
|
}
|
|
|
|
if (smFont[FontOffset])
|
|
Video[0] = FontColor;
|
|
if (smFont[FontOffset+1])
|
|
Video[1] = FontColor;
|
|
if (smFont[FontOffset+2])
|
|
Video[2] = FontColor;
|
|
if (smFont[FontOffset+3])
|
|
Video[3] = FontColor;
|
|
|
|
Video += 320;
|
|
FontOffset += 294;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
short smWriteString(short x,short y,char *s)
|
|
{
|
|
short OrgX;
|
|
char ch;
|
|
|
|
OrgX = x;
|
|
|
|
while (*s)
|
|
{
|
|
ch = *s++;
|
|
|
|
if (ch == 10)
|
|
{
|
|
x = OrgX;
|
|
y += 8;
|
|
continue;
|
|
}
|
|
|
|
if (ch < ' ')
|
|
continue;
|
|
|
|
ch = toupper(ch);
|
|
smWriteChar(x,y,ch);
|
|
x += 5;
|
|
}
|
|
|
|
return(y);
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
void smWriteHUD(short x,short y,UCHAR color,char *s)
|
|
{
|
|
FontTransparent = 1;
|
|
FontColor = color;
|
|
smWriteString(x,y,s);
|
|
FontTransparent = 0;
|
|
FontColor = 15;
|
|
}
|
|
|
|
//=============================================================================
|
|
// Checks mouse movement and calculates delta movement in X and Y directions
|
|
//=============================================================================
|
|
void CheckMouse(MOUSE *m)
|
|
{
|
|
int dx,dy;
|
|
short x,y,buttons;
|
|
|
|
|
|
buttons = ReadMouseCursor(&y,&x);
|
|
dx = x - 160;
|
|
dy = y - 120;
|
|
m->mButtons = buttons;
|
|
SetMouseCursor(120,160);
|
|
|
|
if (abs(dy) > 10 && abs(dx) < 32)
|
|
dx >>= 2;
|
|
|
|
m->mdx = dx;
|
|
m->mdy = dy;
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
// Reads a text line from the resource file
|
|
//=============================================================================
|
|
int ReadLine(void)
|
|
{
|
|
int len;
|
|
char ch;
|
|
|
|
len = 0;
|
|
while (len < 200)
|
|
{
|
|
if (read(rsHandle,&LineBuffer[len],1) != 1)
|
|
break;
|
|
|
|
ch = LineBuffer[len];
|
|
if (ch == 10)
|
|
continue;
|
|
|
|
if (ch == 13)
|
|
break;
|
|
|
|
len++;
|
|
}
|
|
|
|
LineBuffer[len] = '\0';
|
|
|
|
return(len);
|
|
}
|
|
|
|
//=============================================================================
|
|
// Skips to the next parameter in a text line
|
|
//=============================================================================
|
|
char *GetNextParm(char *s)
|
|
{
|
|
char ch;
|
|
|
|
while (*s)
|
|
{
|
|
ch = *s++;
|
|
if (ch == ',')
|
|
{
|
|
while (*s)
|
|
{
|
|
ch = *s;
|
|
if (ch != ',' && ch != ' ' && ch != '\t')
|
|
return(s);
|
|
s++;
|
|
}
|
|
return(NULL);
|
|
}
|
|
|
|
}
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
//=============================================================================
|
|
// Loads a wall bitmap specified in info file
|
|
//=============================================================================
|
|
int LoadWall(void)
|
|
{
|
|
int wnum,rnum,result;
|
|
long pos;
|
|
char *lb;
|
|
|
|
|
|
lb = LineBuffer; // Info file buffer
|
|
wnum = atoi(lb); // Wall number to load into
|
|
|
|
lb = GetNextParm(lb);
|
|
|
|
if (lb == NULL)
|
|
return(-1);
|
|
|
|
rnum = atoi(lb); // Resource number
|
|
|
|
pos = lseek(rsHandle,0L,SEEK_CUR);
|
|
result = AckLoadWall(ae,wnum,(char *)rnum);
|
|
lseek(rsHandle,pos,SEEK_SET);
|
|
|
|
return(result);
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
// Loads an object bitmap specified in info file
|
|
//=============================================================================
|
|
int LoadObject(void)
|
|
{
|
|
int onum,rnum,result;
|
|
long pos;
|
|
char *lb;
|
|
|
|
lb = LineBuffer;
|
|
onum = atoi(lb); // Object bitmap number
|
|
|
|
lb = GetNextParm(lb);
|
|
|
|
if (lb == NULL)
|
|
return(-2);
|
|
|
|
rnum = atoi(lb); // Resource number
|
|
pos = lseek(rsHandle,0L,SEEK_CUR);
|
|
result = AckLoadObject(ae,onum,(char *)rnum);
|
|
lseek(rsHandle,pos,SEEK_SET);
|
|
|
|
return(result);
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
// Skip any leading spaces in the string
|
|
// NOTE: Actually modifies the string passed!
|
|
//=============================================================================
|
|
char *SkipSpaces(char *s)
|
|
{
|
|
|
|
while (*s == ' ' || *s == '\t' || *s == ',')
|
|
strcpy(s,&s[1]);
|
|
|
|
return(s);
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
// Creates and object of the desired style
|
|
//=============================================================================
|
|
int CreateObject(void)
|
|
{
|
|
int onum,vnum,speed;
|
|
short result,oType;
|
|
short NumViews,bmPerView;
|
|
UINT flags;
|
|
char *lb;
|
|
OBJSEQ os;
|
|
|
|
lb = LineBuffer;
|
|
|
|
if (!strnicmp(lb,"NUMBER:",7))
|
|
{
|
|
lb = &lb[7];
|
|
onum = atoi(lb);
|
|
if (onum < 1 || onum > MAX_OBJECTS)
|
|
return(-3);
|
|
|
|
result = AckCreateObject(ae,onum);
|
|
if (result)
|
|
return(result);
|
|
|
|
LastObjectIndex = onum;
|
|
lb = GetNextParm(lb);
|
|
if (lb == NULL)
|
|
return(-4);
|
|
|
|
ae->ObjList[onum]->Speed = atoi(lb);
|
|
return(0);
|
|
}
|
|
|
|
onum = LastObjectIndex; // Object number
|
|
|
|
oType = 0;
|
|
|
|
if (!strnicmp(lb,"CREATE:",7))
|
|
{
|
|
oType = NO_CREATE;
|
|
lb = &lb[7];
|
|
}
|
|
|
|
if (!strnicmp(lb,"DESTROY:",8))
|
|
{
|
|
oType = NO_DESTROY;
|
|
lb = &lb[8];
|
|
}
|
|
|
|
if (!strnicmp(lb,"WALK:",5))
|
|
{
|
|
oType = NO_WALK;
|
|
lb = &lb[5];
|
|
}
|
|
|
|
if (!strnicmp(lb,"ATTACK:",7))
|
|
{
|
|
oType = NO_ATTACK;
|
|
lb = &lb[7];
|
|
}
|
|
|
|
if (!strnicmp(lb,"INTERACT:",9))
|
|
{
|
|
oType = NO_INTERACT;
|
|
lb = &lb[9];
|
|
}
|
|
|
|
|
|
if (!oType)
|
|
return(-5);
|
|
|
|
|
|
|
|
lb = SkipSpaces(lb);
|
|
if (lb == NULL)
|
|
return(-6);
|
|
|
|
flags = 0;
|
|
strupr(lb);
|
|
|
|
if (strstr(lb,"ANIMATE") != NULL)
|
|
flags |= OF_ANIMATE;
|
|
|
|
if (strstr(lb,"MOVEABLE") != NULL)
|
|
flags |= OF_MOVEABLE;
|
|
|
|
if (strstr(lb,"PASSABLE") != NULL)
|
|
flags |= OF_PASSABLE;
|
|
|
|
if (strstr(lb,"MULTIVIEW") != NULL)
|
|
flags |= OF_MULTIVIEW;
|
|
|
|
if (strstr(lb,"SHOWONCE") != NULL)
|
|
flags |= OF_ANIMONCE;
|
|
|
|
lb = GetNextParm(lb);
|
|
if (lb == NULL)
|
|
return(-5);
|
|
|
|
NumViews = atoi(lb);
|
|
if (NumViews < 1)
|
|
return(-6);
|
|
|
|
lb = GetNextParm(lb);
|
|
if (lb == NULL)
|
|
return(-7);
|
|
|
|
bmPerView = atoi(lb);
|
|
if (bmPerView < 1)
|
|
return(-7);
|
|
|
|
vnum = NumViews * bmPerView;
|
|
if (vnum > MAX_OBJ_BITMAPS)
|
|
return(-8);
|
|
|
|
lb = GetNextParm(lb);
|
|
if (lb == NULL)
|
|
return(-9);
|
|
|
|
vnum = 0;
|
|
|
|
while (lb != NULL && vnum < MAX_OBJ_BITMAPS)
|
|
{
|
|
os.bitmaps[vnum++] = atoi(lb);
|
|
lb = GetNextParm(lb);
|
|
}
|
|
|
|
os.bmBitmapsPerView = bmPerView;
|
|
os.flags = flags;
|
|
os.MaxBitmaps = bmPerView;
|
|
os.bmSides = NumViews;
|
|
|
|
result = AckSetupObject(ae,onum,oType,&os);
|
|
|
|
return(result);
|
|
}
|
|
|
|
//=============================================================================
|
|
// Reads the ASCII info file and processes the commands.
|
|
//=============================================================================
|
|
int ProcessInfoFile(void)
|
|
{
|
|
int result;
|
|
int mode;
|
|
long pos;
|
|
char *lb;
|
|
|
|
|
|
// Position to start of info file within resource file
|
|
lseek(rsHandle,rbaTable[0],SEEK_SET);
|
|
|
|
mode = result = 0;
|
|
|
|
while (!result)
|
|
{
|
|
if (!ReadLine())
|
|
continue;
|
|
|
|
if (*LineBuffer == ';')
|
|
continue;
|
|
|
|
if (!strnicmp(LineBuffer,"END:",4))
|
|
break;
|
|
|
|
printf(".");
|
|
|
|
switch (mode)
|
|
{
|
|
|
|
case 1: // Read walls
|
|
if (!strnicmp(LineBuffer,"LOADTYPE:",9))
|
|
{
|
|
ae->bmLoadType = atoi(&LineBuffer[9]); // Sets for GIF or BBM
|
|
break;
|
|
}
|
|
|
|
if (!strnicmp(LineBuffer,"ENDBITMAPS:",11))
|
|
mode = 4;
|
|
else
|
|
result = LoadWall();
|
|
break;
|
|
|
|
case 2: // Object bitmaps
|
|
if (!strnicmp(LineBuffer,"LOADTYPE:",9)) // Sets for GIF or BBM
|
|
{
|
|
ae->bmLoadType = atoi(&LineBuffer[9]);
|
|
break;
|
|
}
|
|
if (!strnicmp(LineBuffer,"ENDBITMAPS:",11))
|
|
mode = 5;
|
|
else
|
|
result = LoadObject();
|
|
break;
|
|
|
|
case 3: // Create Object
|
|
if (!strnicmp(LineBuffer,"ENDDESC:",8))
|
|
mode = 5;
|
|
else
|
|
result = CreateObject();
|
|
break;
|
|
|
|
case 4: // Walls topic
|
|
if (!strnicmp(LineBuffer,"BITMAPS:",8))
|
|
mode = 1;
|
|
|
|
if (!strnicmp(LineBuffer,"ENDWALLS:",9))
|
|
mode = 0;
|
|
break;
|
|
|
|
|
|
case 5: // Objects topic
|
|
if (!strnicmp(LineBuffer,"BITMAPS:",8))
|
|
mode = 2;
|
|
|
|
if (!strnicmp(LineBuffer,"OBJDESC:",8))
|
|
mode = 3;
|
|
|
|
if (!strnicmp(LineBuffer,"ENDOBJECTS:",11))
|
|
mode = 0;
|
|
break;
|
|
|
|
|
|
default:
|
|
if (!strnicmp(LineBuffer,"WALLS:",6))
|
|
{
|
|
mode = 4;
|
|
break;
|
|
}
|
|
|
|
if (!strnicmp(LineBuffer,"OBJECTS:",8))
|
|
{
|
|
mode = 5;
|
|
break;
|
|
}
|
|
|
|
if (!strnicmp(LineBuffer,"MAPFILE:",8))
|
|
{
|
|
MapResource = atoi(&LineBuffer[8]);
|
|
pos = lseek(rsHandle,0L,SEEK_CUR);
|
|
result = AckReadMapFile(ae,(char *)MapResource);
|
|
lseek(rsHandle,pos,SEEK_SET);
|
|
break;
|
|
}
|
|
|
|
if (!strnicmp(LineBuffer,"PALFILE:",8))
|
|
{
|
|
PalResource = atoi(&LineBuffer[8]);
|
|
break;
|
|
}
|
|
|
|
if (!strnicmp(LineBuffer,"XPLAYER:",8))
|
|
{
|
|
ae->xPlayer = atoi(&LineBuffer[8]);
|
|
break;
|
|
}
|
|
|
|
if (!strnicmp(LineBuffer,"YPLAYER:",8))
|
|
{
|
|
ae->yPlayer = atoi(&LineBuffer[8]);
|
|
break;
|
|
}
|
|
|
|
if (!strnicmp(LineBuffer,"PLAYERANGLE:",12))
|
|
{
|
|
ae->PlayerAngle = atoi(&LineBuffer[12]);
|
|
break;
|
|
}
|
|
|
|
if (!strnicmp(LineBuffer,"SCREENBACK:",11))
|
|
{
|
|
ResScreenBack = atoi(&LineBuffer[11]);
|
|
break;
|
|
}
|
|
|
|
if (!strnicmp(LineBuffer,"SCROLLBACK:",11))
|
|
{
|
|
ResScrollBack = atoi(&LineBuffer[11]);
|
|
break;
|
|
}
|
|
|
|
if (!strnicmp(LineBuffer,"TOPCOLOR:",9))
|
|
{
|
|
ae->TopColor = atoi(&LineBuffer[9]);
|
|
break;
|
|
}
|
|
|
|
if (!strnicmp(LineBuffer,"BOTTOMCOLOR:",12))
|
|
{
|
|
ae->BottomColor = atoi(&LineBuffer[12]);
|
|
break;
|
|
}
|
|
|
|
if (!strnicmp(LineBuffer,"SHADING:",8))
|
|
{
|
|
strupr(LineBuffer);
|
|
if (strstr(&LineBuffer[8],"OFF") != NULL)
|
|
ae->LightFlag = SHADING_OFF;
|
|
else
|
|
ae->LightFlag = SHADING_ON;
|
|
break;
|
|
}
|
|
|
|
if (!strnicmp(LineBuffer,"FLOORS:",7))
|
|
{
|
|
strupr(LineBuffer);
|
|
if (strstr(&LineBuffer[7],"OFF") != NULL)
|
|
ae->SysFlags |= SYS_SOLID_FLOOR;
|
|
else
|
|
{
|
|
ae->SysFlags &= ~SYS_SOLID_FLOOR;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (!strnicmp(LineBuffer,"RESOLUTION:",11))
|
|
{
|
|
Resolution = atoi(&LineBuffer[11]);
|
|
break;
|
|
}
|
|
|
|
if (!strnicmp(LineBuffer,"LOADTYPE:",9))
|
|
{
|
|
ae->bmLoadType = atoi(&LineBuffer[9]); // Sets for GIF or BBM
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!result)
|
|
{
|
|
result = AckCreateObject(ae,0); // Create a dummy object for later
|
|
if (!result)
|
|
ae->ObjList[0]->Active = 0; // Turn off checking the object
|
|
}
|
|
|
|
printf("done\n");
|
|
return(result);
|
|
}
|
|
|
|
//=============================================================================
|
|
// Quick routine to display a bitmap into the desired buffer. Handles
|
|
// transparent colors. Currently used to display the ACK3D Demo bitmap.
|
|
//=============================================================================
|
|
void ShowBitmap(short x,short y,UCHAR *dst,short ht,short wt,UCHAR *bm)
|
|
{
|
|
int offset,col;
|
|
short endy;
|
|
UCHAR ch;
|
|
|
|
offset = (y*320) + x;
|
|
dst += offset;
|
|
endy = ae->WinEndY + 2;
|
|
|
|
while (ht-- > 0 && y++ <= endy)
|
|
{
|
|
for (col = 0; col < wt; col++)
|
|
{
|
|
ch = *bm++;
|
|
if (ch)
|
|
dst[col] = ch;
|
|
}
|
|
dst += 320;
|
|
}
|
|
|
|
}
|
|
|
|
#define FONT_RESOURCE 52
|
|
|
|
UCHAR *Fonts[256];
|
|
short MaxWt;
|
|
short MaxHt;
|
|
short FontSize;
|
|
UCHAR FontColorTable[16];
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
void LoadFont(void)
|
|
{
|
|
short i;
|
|
char wBuf[30];
|
|
char *w;
|
|
|
|
|
|
lseek(rsHandle,rbaTable[FONT_RESOURCE],SEEK_SET);
|
|
|
|
read(rsHandle,wBuf,7);
|
|
if (strncmp(wBuf,"GKF",3))
|
|
{
|
|
return;
|
|
}
|
|
|
|
w = wBuf + 3;
|
|
MaxHt = (*(short *)w);
|
|
w += 2;
|
|
MaxWt = (*(short *)w);
|
|
FontSize = MaxHt * MaxWt;
|
|
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
Fonts[i] = AckMalloc(FontSize);
|
|
if (Fonts[i] == NULL)
|
|
break;
|
|
|
|
read(rsHandle,Fonts[i],FontSize);
|
|
}
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
void WriteChar(short x,short y,char c)
|
|
{
|
|
UCHAR *fPtr,*Video;
|
|
short offset,row,col;
|
|
|
|
if (c < ' ' || c > 'z')
|
|
return;
|
|
|
|
c = toupper(c);
|
|
fPtr = Fonts[c];
|
|
Video = (UCHAR *)0xA0000;
|
|
offset = (y * 320) + x;
|
|
Video += offset;
|
|
|
|
for (row = 0; row < MaxHt; row++)
|
|
{
|
|
for (col = 0; col < MaxWt; col++)
|
|
Video[col] = FontColorTable[*fPtr++];
|
|
|
|
Video += 320;
|
|
}
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
void WriteString(short x,short y,char *s)
|
|
{
|
|
short cx,cy;
|
|
char ch;
|
|
|
|
cx = x;
|
|
cy = y;
|
|
|
|
while (*s)
|
|
{
|
|
ch = *s++;
|
|
if (ch == 13)
|
|
{
|
|
x = cx;
|
|
cy += MaxHt;
|
|
continue;
|
|
}
|
|
|
|
if (ch < ' ')
|
|
continue;
|
|
|
|
WriteChar(x,y,ch);
|
|
x += MaxWt;
|
|
}
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
UCHAR GetPoint(short x,short y)
|
|
{
|
|
short offset;
|
|
UCHAR *Video;
|
|
|
|
offset = (y * 320) + x;
|
|
Video = (UCHAR *)0xA0000;
|
|
|
|
return(Video[offset]);
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
void CenterString(short y,char *s)
|
|
{
|
|
short x,len;
|
|
|
|
len = strlen(s) * MaxWt;
|
|
|
|
x = (320 - len) / 2;
|
|
WriteString(x,y,s);
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
short Initialize(void)
|
|
{
|
|
short i,bnum;
|
|
|
|
if (MouseInstalled() != -1)
|
|
{
|
|
printf("Mouse is required to run.\n");
|
|
return(1);
|
|
}
|
|
|
|
ae = AckMalloc(sizeof(ACKENG));
|
|
if (ae == NULL)
|
|
{
|
|
printf("Unable to get required memory.\n");
|
|
return(2);
|
|
}
|
|
|
|
memset(ae,0,sizeof(ACKENG));
|
|
|
|
// ae->WinStartX = 0;
|
|
// ae->WinEndX = 319;
|
|
// ae->WinStartY = 0;
|
|
// ae->WinEndY = 158;
|
|
|
|
ae->WinStartX = 20;
|
|
ae->WinEndX = 299;
|
|
ae->WinStartY = 14;
|
|
ae->WinEndY = 156;
|
|
|
|
|
|
ae->LightFlag = SHADING_ON;
|
|
ae->xPlayer = 192;
|
|
ae->yPlayer = 640;
|
|
ae->PlayerAngle = 0;
|
|
ae->TopColor = 0;
|
|
ae->BottomColor = 24;
|
|
ae->DoorSpeed = 6;
|
|
ae->NonSecretCode = 1;
|
|
ae->SysFlags |= SYS_SOLID_BACK;
|
|
|
|
printf("Initializing.\n");
|
|
|
|
i = AckOpenResource("kit.ovl");
|
|
if (i)
|
|
{
|
|
printf("Unable to open resource KIT.OVL\n");
|
|
return(3);
|
|
}
|
|
|
|
i = LoadSmallFont();
|
|
if (i)
|
|
{
|
|
printf("Error loading font BBM.\n");
|
|
return(5);
|
|
}
|
|
|
|
i = AckInitialize(ae);
|
|
|
|
AckCloseResource();
|
|
|
|
if (i)
|
|
{
|
|
printf("Error initializing. Error code: %d\n",i);
|
|
return(3);
|
|
}
|
|
|
|
printf("Processing DTF file ");
|
|
|
|
i = AckOpenResource("pics.dtf");
|
|
if (i)
|
|
{
|
|
printf("Unable to open resource PICS.DTF\n");
|
|
return(3);
|
|
}
|
|
|
|
i = ProcessInfoFile();
|
|
if (i)
|
|
{
|
|
printf("Error reading INF file.\n");
|
|
if (i > 100 && i < 121)
|
|
printf("Last error was %s\n",ErrorMsgs[i-100]);
|
|
else
|
|
printf("Error code: %d\n",i);
|
|
|
|
printf("Line was: \"%s\"\n",LineBuffer);
|
|
|
|
return(4);
|
|
}
|
|
|
|
bmFlash[0] = ae->bMaps[4];
|
|
bmFlash[1] = ae->bMaps[8];
|
|
bmFlash1[0] = ae->bMaps[24];
|
|
bmFlash1[1] = ae->bMaps[2];
|
|
FlashIndex = 0;
|
|
LoadFont();
|
|
|
|
return(0);
|
|
}
|
|
|
|
//=============================================================================
|
|
// Loads and displays the full screen picture and sets the palette to the one
|
|
// loaded with the picture.
|
|
//=============================================================================
|
|
short LoadAndShow(char *fName)
|
|
{
|
|
short i,j;
|
|
UINT pos,begpos;
|
|
UCHAR pMask;
|
|
UCHAR *buf,*bPtr;
|
|
UCHAR *Video;
|
|
|
|
buf = AckReadiff(fName);
|
|
if (buf == NULL)
|
|
return(-1);
|
|
|
|
Video = (char *)0xA0000;
|
|
memmove(Video,&buf[4],64000);
|
|
|
|
AckSetPalette(colordat);
|
|
|
|
AckFree(buf);
|
|
return(0);
|
|
}
|
|
|
|
//=============================================================================
|
|
// Loads a background image (mountains) and processes the image into the
|
|
// separate slices for use at display time. Currently a background image
|
|
// can be 640 columns wide. This number can be made dynamic if needbe and would
|
|
// need to be changed in the routine below and in the DrawBackground routine
|
|
// in the ACK engine.
|
|
//=============================================================================
|
|
int LoadBackDrop(void)
|
|
{
|
|
int result;
|
|
int i,j,pos;
|
|
UCHAR *bPtr;
|
|
UCHAR *aPtr;
|
|
|
|
result = 0;
|
|
|
|
if (ResScrollBack)
|
|
{
|
|
printf("Loading background image....\n");
|
|
bPtr = AckReadiff((char *)ResScrollBack);
|
|
printf("Processing background image.\n");
|
|
if (bPtr != NULL)
|
|
{
|
|
for (i = 0; i < 320; i++)
|
|
{
|
|
pos = i + 4;
|
|
aPtr = BackArray[i];
|
|
for (j = 0; j < 100; j++)
|
|
{
|
|
*aPtr++ = bPtr[pos];
|
|
pos += 320;
|
|
}
|
|
}
|
|
|
|
for (i = 320; i < 640; i++)
|
|
{
|
|
pos = (i - 320) + 32004;
|
|
aPtr = BackArray[i];
|
|
for (j = 0; j < 100; j++)
|
|
{
|
|
*aPtr++ = bPtr[pos];
|
|
pos += 320;
|
|
}
|
|
}
|
|
|
|
AckFree(bPtr);
|
|
}
|
|
else
|
|
{
|
|
printf("Unable to load background image.\n");
|
|
result = 8;
|
|
}
|
|
}
|
|
|
|
return(result);
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
void ShowHit(void)
|
|
{
|
|
int x,y,result,wNum;
|
|
int flag;
|
|
short oNum,mPos;
|
|
|
|
ae->ObjList[0]->x = ae->xPlayer;
|
|
ae->ObjList[0]->y = ae->yPlayer;
|
|
|
|
wNum = 32;
|
|
oNum = 0;
|
|
flag = 0;
|
|
|
|
while (wNum--)
|
|
{
|
|
result = AckMoveObjectPOV(0,ae->PlayerAngle,12);
|
|
|
|
if (result == POV_OBJECT)
|
|
{
|
|
flag = 1;
|
|
oNum = AckGetObjectHit();
|
|
break;
|
|
}
|
|
|
|
if (result == POV_XWALL)
|
|
{
|
|
flag = 2;
|
|
oNum = ae->xGrid[AckGetWallHit()];
|
|
if (oNum & (DOOR_TYPE_SLIDE+DOOR_TYPE_SPLIT))
|
|
flag = 4;
|
|
oNum &= 0xFF;
|
|
break;
|
|
}
|
|
|
|
if (result == POV_YWALL)
|
|
{
|
|
flag = 3;
|
|
oNum = ae->yGrid[AckGetWallHit()];
|
|
if (oNum & (DOOR_TYPE_SLIDE+DOOR_TYPE_SPLIT))
|
|
flag = 4;
|
|
oNum &= 0xFF;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
if (flag)
|
|
{
|
|
mPos = (ae->ObjList[0]->y & 0xFFC0) + (ae->ObjList[0]->x >> 6);
|
|
|
|
switch (flag)
|
|
{
|
|
|
|
case 1:
|
|
sprintf(LineBuffer,"Object %d hit\nat location %d",oNum,mPos);
|
|
break;
|
|
|
|
case 2:
|
|
sprintf(LineBuffer,"Xwall %d hit\nat location %d",oNum,mPos);
|
|
break;
|
|
|
|
case 3:
|
|
sprintf(LineBuffer,"Ywall %d hit\nat location %d",oNum,mPos);
|
|
break;
|
|
|
|
case 4:
|
|
sprintf(LineBuffer,"Door %d hit\nat location %d",oNum,mPos);
|
|
break;
|
|
|
|
default:
|
|
*LineBuffer = '\0';
|
|
break;
|
|
}
|
|
|
|
ShowHitFlag = 1;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
void UpdateBlast(void)
|
|
{
|
|
short j;
|
|
|
|
if (ae->ObjList[99]->Flags & OF_ANIMDONE &&
|
|
ae->ObjList[99]->CurrentType != NO_WALK)
|
|
{
|
|
AckSetObjectType(ae,99,NO_WALK);
|
|
ae->ObjList[99]->Flags &= ~OF_ANIMDONE;
|
|
}
|
|
|
|
j = AckMoveObjectPOV(99,ae->ObjList[99]->Dir,ae->ObjList[99]->Speed);
|
|
|
|
if (j > 0 && j != POV_PLAYER)
|
|
{
|
|
if (j != POV_OBJECT)
|
|
{
|
|
ae->ObjList[99]->Active = 0;
|
|
Shooting = 0;
|
|
return;
|
|
}
|
|
|
|
j = AckGetObjectHit();
|
|
|
|
if (j > 4 && j < 13)
|
|
{
|
|
if (ae->ObjList[j]->CurrentType == NO_WALK)
|
|
{
|
|
AckSetObjectType(ae,j,NO_INTERACT);
|
|
ObjCounter[j] = AckTimerCounter + 18 + (rand() % 120);
|
|
}
|
|
}
|
|
|
|
if (j == 51)
|
|
ae->ObjList[j]->Active = 0;
|
|
|
|
ae->ObjList[99]->Active = 0;
|
|
Shooting = 0;
|
|
}
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
void CheckMonsters(void)
|
|
{
|
|
int i,tFlag,xp,yp;
|
|
int pMap,oMap,oRow,oCol;
|
|
int row,col,offset;
|
|
long dx,dy,dx2,dy2,dist;
|
|
short cType;
|
|
UCHAR oFlags;
|
|
|
|
xp = ae->xPlayer;
|
|
yp = ae->yPlayer;
|
|
|
|
pMap = (yp & 0xFFC0) + (xp >> 6);
|
|
|
|
i = 5;
|
|
//for (i = 5; i < 13; i++)
|
|
while (1)
|
|
{
|
|
if (ae->ObjList[i]->Active)
|
|
{
|
|
oFlags = ae->ObjList[i]->Flags;
|
|
cType = ae->ObjList[i]->CurrentType;
|
|
dx = xp - ae->ObjList[i]->x;
|
|
dy = yp - ae->ObjList[i]->y;
|
|
|
|
dx2 = dx * dx;
|
|
dy2 = dy * dy;
|
|
if ((dx2+dy2) < 128000)
|
|
{
|
|
ae->ObjList[i]->Dir = AckGetObjectAngle(dx,dy);
|
|
if (cType == NO_WALK)
|
|
{
|
|
ae->ObjList[i]->Flags |= OF_ANIMATE;
|
|
oFlags |= OF_ANIMATE;
|
|
}
|
|
|
|
if (cType == NO_CREATE && !(oFlags & OF_ANIMATE))
|
|
{
|
|
if (i < 50)
|
|
{
|
|
ae->ObjList[i]->Flags |= OF_ANIMATE;
|
|
oFlags |= OF_ANIMATE;
|
|
}
|
|
else
|
|
AckSetObjectType(ae,i,NO_WALK);
|
|
}
|
|
|
|
}
|
|
|
|
if (cType == NO_WALK && (oFlags & OF_ANIMATE))
|
|
{
|
|
tFlag = AckMoveObjectPOV(i,ae->ObjList[i]->Dir,8);
|
|
oRow = ae->ObjList[i]->Dir / INT_ANGLE_90;
|
|
switch (tFlag)
|
|
{
|
|
case POV_PLAYER:
|
|
StrAmount--;
|
|
if (StrAmount < 0) StrAmount = 0;
|
|
ShowStatus();
|
|
break;
|
|
|
|
case POV_NOTHING:
|
|
break;
|
|
|
|
case POV_SLIDEX:
|
|
if (oRow > 1) ae->ObjList[i]->Dir = INT_ANGLE_270;
|
|
else ae->ObjList[i]->Dir = INT_ANGLE_90;
|
|
break;
|
|
|
|
case POV_SLIDEY:
|
|
if (oRow > 0 && oRow < 3)
|
|
ae->ObjList[i]->Dir = INT_ANGLE_180;
|
|
else
|
|
ae->ObjList[i]->Dir = 0;
|
|
break;
|
|
|
|
case POV_OBJECT:
|
|
ae->ObjList[i]->Dir = rand() % INT_ANGLE_360;
|
|
break;
|
|
|
|
default:
|
|
if (i < 50)
|
|
ae->ObjList[i]->Flags &= ~OF_ANIMATE;
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
i++;
|
|
if (i == 13) i = 51;
|
|
if (i == 52) break;
|
|
}
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
void ShowStatus(void)
|
|
{
|
|
|
|
#if 0
|
|
UCHAR *Video;
|
|
int row,offset,rlen,glen;
|
|
|
|
|
|
offset = (163 * 320) + 34;
|
|
glen = MagAmount;
|
|
if (glen > MAX_MAG_AMOUNT) glen = MAX_MAG_AMOUNT;
|
|
rlen = MAX_MAG_AMOUNT - glen;
|
|
Video = (UCHAR *)0xA0000;
|
|
Video += offset;
|
|
|
|
for (row = 0; row < 11; row++)
|
|
{
|
|
if (glen)
|
|
memset(Video,105,glen);
|
|
if (rlen)
|
|
memset(&Video[glen],39,rlen);
|
|
|
|
Video += 320;
|
|
}
|
|
|
|
offset = (183 * 320) + 34;
|
|
glen = StrAmount >> 1;
|
|
if (glen > MAX_STR_HALF_AMOUNT) glen = MAX_STR_HALF_AMOUNT;
|
|
rlen = MAX_STR_HALF_AMOUNT - glen;
|
|
Video = (UCHAR *)0xA0000;
|
|
Video += offset;
|
|
|
|
for (row = 0; row < 11; row++)
|
|
{
|
|
if (glen)
|
|
memset(Video,105,glen);
|
|
if (rlen)
|
|
memset(&Video[glen],39,rlen);
|
|
|
|
Video += 320;
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
void DrawBmpBox(int x1,int y1,int x2,int y2,long d1,long d2)
|
|
{
|
|
long NumCols,DeltaDist;
|
|
long htStep,dst;
|
|
long ht1,ht2,bmht;
|
|
long offset,xpos,ypos,bmPos,yposLow;
|
|
long bmCol,bmColStep;
|
|
UCHAR *Video,*bmp,*VidOrg,*VidEnd;
|
|
UCHAR *vPtr;
|
|
|
|
dst = d1;
|
|
if (d1 > d2) dst = d2;
|
|
|
|
bmht = 64 * 256;
|
|
DeltaDist = labs(d2 - d1);
|
|
ht1 = bmht / dst;
|
|
NumCols = ht1;
|
|
if (DeltaDist)
|
|
NumCols = (ht1 * (64 - DeltaDist)) / 64;
|
|
|
|
if (NumCols < 1) NumCols = 1;
|
|
|
|
bmColStep = (64*65536) / NumCols;
|
|
htStep = (DeltaDist<<16) / NumCols;
|
|
if (d2 < d1) htStep = -htStep;
|
|
|
|
bmp = ae->bMaps[1];
|
|
VidOrg = Video = ae->ScreenBuffer;
|
|
VidEnd = VidOrg + 64000;
|
|
offset = (y1 * 320) + x1;
|
|
Video += offset;
|
|
|
|
bmCol = 0;
|
|
d2 = (d1<<16);
|
|
|
|
for (xpos = 0; xpos < NumCols; xpos++)
|
|
{
|
|
vPtr = Video;
|
|
ypos = 0x1FFF;
|
|
yposLow = 0x1F;
|
|
bmPos = (bmCol>>16) * 64;
|
|
d1 = (d2>>16);
|
|
|
|
while (yposLow > 0 && vPtr > VidOrg)
|
|
{
|
|
*vPtr = bmp[bmPos+yposLow];
|
|
vPtr -= 320;
|
|
ypos -= d1;
|
|
yposLow = ypos >> 8;
|
|
}
|
|
|
|
vPtr = Video + 320;
|
|
ypos = 0x2000;
|
|
yposLow = 0x20;
|
|
|
|
while (yposLow < 64 && vPtr < VidEnd)
|
|
{
|
|
*vPtr = bmp[bmPos+yposLow];
|
|
vPtr += 320;
|
|
ypos += d1;
|
|
yposLow = ypos >> 8;
|
|
}
|
|
|
|
d2 += htStep;
|
|
bmCol += bmColStep;
|
|
Video++;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
void ClsBmpBox(int x1,int y1,int x2,int y2)
|
|
{
|
|
int offset,wt;
|
|
UCHAR *Video;
|
|
|
|
Video = (UCHAR *)0xA0000;
|
|
offset = (y1 * 320) + x1;
|
|
wt = (x2 - x1) + 1;
|
|
Video += offset;
|
|
|
|
while (y1++ <= y2)
|
|
{
|
|
memset(Video,0,wt);
|
|
Video += 320;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
short main(void)
|
|
{
|
|
short i,j,done,fpos;
|
|
char ch;
|
|
MOUSE mouse;
|
|
UCHAR *Video;
|
|
int Spin,MoveAmount;
|
|
int SpinAngle,MoveAngle;
|
|
long TimerEnd;
|
|
short DemoFlag;
|
|
short lpx,lpy,lpa;
|
|
int StartTime,EndTime,InfoFlag;
|
|
int CkStart,CkEnd;
|
|
int TurnFactor,MoveFactor,MoveHalfFactor;
|
|
int HandX,HandY,HandDY;
|
|
long x1,y1;
|
|
|
|
if ((done = Initialize()) != 0)
|
|
return(done);
|
|
|
|
if ((done = LoadBackDrop()) != 0)
|
|
return(done);
|
|
|
|
Shooting = 0;
|
|
MagAmount = MAX_MAG_AMOUNT;
|
|
StrAmount = MAX_STR_AMOUNT;
|
|
|
|
// Setup keyboard and timer interrupts
|
|
AckSetupKeyboard();
|
|
AckSetupTimer();
|
|
AckTmDelay = 3;
|
|
AckSpeedUp(AckTmDelay); // Set the timer interrupt at 3 times normal
|
|
|
|
ReadConfigFile();
|
|
StartBGmusic();
|
|
|
|
// Switch to mode 13
|
|
AckSetVGAmode();
|
|
|
|
// Put up the main screen
|
|
LoadAndShow((char *)ResScreenBack);
|
|
|
|
// Set palette for shading if needed
|
|
AckSetupPalRanges(ae,ranges);
|
|
|
|
ShowStatus();
|
|
|
|
done = 0;
|
|
SpinAngle = Spin = MoveAmount = 0;
|
|
MouseReleased();
|
|
SetMouseCursor(120,160);
|
|
fpos = 64;
|
|
DemoFlag = 0;
|
|
//if (DemoPtr != NULL) DemoFlag = 1;
|
|
TimerEnd = AckTimerCounter + 180;
|
|
|
|
|
|
// MUST register each ACKENG structure once before use and after AckInitialize
|
|
AckRegisterStructure(ae);
|
|
|
|
StartTime = AckTimerCounter;
|
|
AckBuildView();
|
|
AckDisplayScreen();
|
|
FontColorTable[0] = GetPoint(100,10);
|
|
CenterString(3,"An ACK-3D Demonstration");
|
|
EndTime = AckTimerCounter - StartTime;
|
|
|
|
if (!EndTime) EndTime = 1;
|
|
|
|
TurnFactor = INT_ANGLE_1 * EndTime;
|
|
MoveFactor = 3 * EndTime;
|
|
MoveHalfFactor = MoveFactor >> 1;
|
|
|
|
StartTime = clock();
|
|
EndTime = StartTime;
|
|
InfoFlag = 0;
|
|
|
|
HandX = 134;
|
|
HandY = 132;
|
|
HandDY = -2;
|
|
Throwing = 0;
|
|
|
|
while (!done)
|
|
{
|
|
|
|
if (SpinAngle)
|
|
{
|
|
ae->PlayerAngle += SpinAngle;
|
|
if (ae->PlayerAngle >= INT_ANGLE_360)
|
|
ae->PlayerAngle -= INT_ANGLE_360;
|
|
if (ae->PlayerAngle < 0)
|
|
ae->PlayerAngle += INT_ANGLE_360;
|
|
|
|
SpinAngle >>= 3;
|
|
if (SpinAngle == -1) SpinAngle = 0;
|
|
}
|
|
|
|
if (MoveAmount)
|
|
{
|
|
|
|
#if 0
|
|
HandY += HandDY;
|
|
if (HandY < 125) HandDY = 2;
|
|
if (HandY > 132) HandDY = -2;
|
|
#endif
|
|
|
|
j = AckMovePOV(MoveAngle,MoveAmount);
|
|
AckCheckDoorOpen(ae->xPlayer,ae->yPlayer,MoveAngle);
|
|
MoveAmount >>= 1;
|
|
|
|
#if 0
|
|
if (j == POV_OBJECT)
|
|
{
|
|
j = AckGetObjectHit();
|
|
|
|
if (j > 4 && j < 13)
|
|
{
|
|
StrAmount--;
|
|
if (StrAmount < 0)
|
|
StrAmount = 0;
|
|
|
|
ShowStatus();
|
|
}
|
|
|
|
if (j >= 36 && j <= 49)
|
|
{
|
|
ae->ObjList[j]->Active = 0;
|
|
MagAmount += 4;
|
|
if (MagAmount > MAX_MAG_AMOUNT)
|
|
MagAmount = MAX_MAG_AMOUNT;
|
|
ShowStatus();
|
|
}
|
|
|
|
if (j == 50 && ae->ObjList[50]->CurrentType == NO_CREATE)
|
|
{
|
|
AckSetObjectType(ae,j,NO_WALK);
|
|
StrAmount = MAX_STR_AMOUNT;
|
|
ShowStatus();
|
|
}
|
|
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
#if 0
|
|
else
|
|
{
|
|
if (HandY < 132)
|
|
HandY++;
|
|
}
|
|
#endif
|
|
|
|
AckCheckObjectMovement(); // Animate objects if needed
|
|
|
|
for (j = 5; j < 13; j++)
|
|
{
|
|
if (ae->ObjList[j]->Flags & OF_ANIMDONE &&
|
|
ae->ObjList[j]->CurrentType == NO_DESTROY)
|
|
{
|
|
AckSetObjectType(ae,j,NO_CREATE);
|
|
ae->ObjList[j]->Flags &= ~OF_ANIMDONE;
|
|
ae->ObjList[j]->Flags &= ~OF_ANIMATE;
|
|
ae->ObjList[j]->Active = 0;
|
|
}
|
|
|
|
if (ae->ObjList[j]->Flags & OF_ANIMDONE &&
|
|
ae->ObjList[j]->CurrentType != NO_WALK)
|
|
{
|
|
AckSetObjectType(ae,j,NO_WALK);
|
|
ae->ObjList[j]->Flags &= ~OF_ANIMDONE;
|
|
ObjCounter[j] = AckTimerCounter + 18 + (rand() % 120);
|
|
}
|
|
|
|
|
|
|
|
if (AckTimerCounter > ObjCounter[j])
|
|
{
|
|
ObjCounter[j] = AckTimerCounter + 180 + (rand() % 180);
|
|
if (ae->ObjList[j]->CurrentType == NO_WALK)
|
|
AckSetObjectType(ae,j,NO_ATTACK);
|
|
else
|
|
{
|
|
if (ae->ObjList[j]->CurrentType == NO_INTERACT)
|
|
AckSetObjectType(ae,j,NO_DESTROY);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Shooting)
|
|
UpdateBlast();
|
|
|
|
CheckMonsters();
|
|
|
|
CkStart = AckTimerCounter;
|
|
AckBuildView(); // Build floor, ceiling, and walls into ScrnBuffer
|
|
|
|
#if 0
|
|
if (DemoFlag)
|
|
{
|
|
switch (DemoFlag)
|
|
{
|
|
case 1:
|
|
if (AckTimerCounter > TimerEnd)
|
|
{
|
|
DemoFlag++;
|
|
TimerEnd = AckTimerCounter + 540;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
ShowBitmap(130,20,ae->ScreenBuffer,Demoht,Demowt,&DemoPtr[4]);
|
|
if (AckTimerCounter > TimerEnd)
|
|
{
|
|
DemoFlag = 1;
|
|
TimerEnd = AckTimerCounter + 2160;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
switch (Throwing)
|
|
{
|
|
case 0:
|
|
ShowBitmap(HandX,HandY,ae->ScreenBuffer,Handh1,Handw1,&pHand1[4]);
|
|
break;
|
|
|
|
case 1:
|
|
HandY -= 20;
|
|
if (HandY < 97)
|
|
{
|
|
HandY = 97;
|
|
Throwing++;
|
|
}
|
|
ShowBitmap(HandX,HandY,ae->ScreenBuffer,Handh1,Handw1,&pHand1[4]);
|
|
break;
|
|
|
|
case 2:
|
|
HandY -= 5;
|
|
Throwing++;
|
|
ShowBitmap(HandX,HandY,ae->ScreenBuffer,Handh2,Handw2,&pHand2[4]);
|
|
break;
|
|
|
|
case 3:
|
|
ae->ObjList[99]->Active = 1;
|
|
ae->ObjList[99]->x = ae->xPlayer;
|
|
ae->ObjList[99]->y = ae->yPlayer;
|
|
ae->ObjList[99]->Dir = ae->PlayerAngle;
|
|
ae->ObjList[99]->mPos = (ae->yPlayer & 0xFFC0) + ae->xPlayer >> 6;
|
|
AckSetObjectType(ae,99,NO_CREATE);
|
|
Shooting = 1;
|
|
MagAmount--;
|
|
ShowStatus();
|
|
Throwing++;
|
|
ShowBitmap(HandX,HandY,ae->ScreenBuffer,Handh2,Handw2,&pHand2[4]);
|
|
break;
|
|
|
|
case 4:
|
|
HandY += 5;
|
|
Throwing++;
|
|
ShowBitmap(HandX,HandY,ae->ScreenBuffer,Handh2,Handw2,&pHand2[4]);
|
|
break;
|
|
|
|
case 5:
|
|
HandY += 20;
|
|
if (HandY > 132)
|
|
Throwing = 0;
|
|
ShowBitmap(HandX,HandY,ae->ScreenBuffer,Handh1,Handw1,&pHand1[4]);
|
|
break;
|
|
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (InfoFlag)
|
|
{
|
|
EndTime = clock();
|
|
if (EndTime > StartTime+100 )
|
|
{
|
|
StartTime = EndTime;
|
|
cframes = framespersec;
|
|
framespersec = 0;
|
|
}
|
|
|
|
sprintf(LineBuffer,"FPS: %6ld,%d,%d,%d",
|
|
(long)cframes,ae->xPlayer,ae->yPlayer,ae->PlayerAngle);
|
|
smWriteHUD(10,20,32,LineBuffer);
|
|
framespersec++;
|
|
}
|
|
|
|
if (ShowHitFlag)
|
|
smWriteHUD(10,10,32,LineBuffer);
|
|
#endif
|
|
|
|
AckDisplayScreen(); // Copy ScrnBuffer to actual video
|
|
CkEnd = AckTimerCounter - CkStart;
|
|
if (!CkEnd) CkEnd = 1;
|
|
|
|
TurnFactor = INT_ANGLE_1 * CkEnd;
|
|
MoveFactor = 3 * CkEnd;
|
|
MoveHalfFactor = MoveFactor >> 1;
|
|
|
|
#if 0
|
|
i = (ae->yPlayer & 0xFFC0) + (ae->xPlayer >> 6);
|
|
|
|
if (FloorMap[i] == 0x28)
|
|
{
|
|
StrAmount--;
|
|
if (StrAmount < 1)
|
|
break;
|
|
ShowStatus();
|
|
}
|
|
#endif
|
|
|
|
CheckMouse(&mouse);
|
|
|
|
#if 0
|
|
if (mouse.mButtons & 1)
|
|
{
|
|
if (!(ae->ObjList[99]->Active) && MagAmount > 0 && !Throwing)
|
|
{
|
|
Throwing = 1;
|
|
#if 0
|
|
ae->ObjList[99]->Active = 1;
|
|
ae->ObjList[99]->x = ae->xPlayer;
|
|
ae->ObjList[99]->y = ae->yPlayer;
|
|
ae->ObjList[99]->Dir = ae->PlayerAngle;
|
|
ae->ObjList[99]->mPos = (ae->yPlayer & 0xFFC0) + ae->xPlayer >> 6;
|
|
AckSetObjectType(ae,99,NO_CREATE);
|
|
Shooting = 1;
|
|
MagAmount--;
|
|
ShowStatus();
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (mouse.mButtons & 2)
|
|
{
|
|
MoveAmount += MoveFactor; // 16;
|
|
if (MoveAmount > MAX_AMOUNT)
|
|
MoveAmount = MAX_AMOUNT;
|
|
MoveAngle = ae->PlayerAngle;
|
|
}
|
|
|
|
if (mouse.mdx < 0)
|
|
{
|
|
Spin = -mouse.mdx;
|
|
Spin >>= 5;
|
|
SpinAngle = -TurnFactor * Spin; // -INT_ANGLE_1 * Spin;
|
|
Spin = 1;
|
|
}
|
|
|
|
if (mouse.mdx > 0)
|
|
{
|
|
Spin = mouse.mdx;
|
|
Spin >>= 5;
|
|
SpinAngle = TurnFactor * Spin; // INT_ANGLE_1 * Spin;
|
|
Spin = 1;
|
|
}
|
|
|
|
if (mouse.mdy < 0)
|
|
{
|
|
i = -mouse.mdy;
|
|
i >>= 2;
|
|
i += MoveHalfFactor;
|
|
MoveAmount += i;
|
|
if (MoveAmount > MAX_AMOUNT)
|
|
MoveAmount = MAX_AMOUNT;
|
|
MoveAngle = ae->PlayerAngle;
|
|
}
|
|
|
|
if (mouse.mdy > 20)
|
|
{
|
|
i = mouse.mdy;
|
|
i >>= 3;
|
|
i += MoveHalfFactor;
|
|
j = ae->PlayerAngle + INT_ANGLE_180;
|
|
if (j >= INT_ANGLE_360)
|
|
j -= INT_ANGLE_360;
|
|
|
|
MoveAmount += i;
|
|
if (MoveAmount > MAX_AMOUNT)
|
|
MoveAmount = MAX_AMOUNT;
|
|
MoveAngle = j;
|
|
}
|
|
|
|
if (AckKeys[ESCAPE_KEY])
|
|
break;
|
|
|
|
if(AckKeys[RIGHT_ARROW_KEY])
|
|
{
|
|
Spin += 1;
|
|
SpinAngle += TurnFactor; // INT_ANGLE_1 * Spin;
|
|
}
|
|
|
|
if(AckKeys[LEFT_ARROW_KEY])
|
|
{
|
|
Spin += 1;
|
|
SpinAngle -= TurnFactor; // -INT_ANGLE_1 * Spin;
|
|
}
|
|
|
|
if(AckKeys[UP_ARROW_KEY])
|
|
{
|
|
MoveAmount += (MoveFactor + MoveHalfFactor); // 12;
|
|
if (MoveAmount > MAX_AMOUNT)
|
|
MoveAmount = MAX_AMOUNT;
|
|
MoveAngle = ae->PlayerAngle;
|
|
}
|
|
|
|
if(AckKeys[DOWN_ARROW_KEY])
|
|
{
|
|
j = ae->PlayerAngle + INT_ANGLE_180;
|
|
if (j >= INT_ANGLE_360)
|
|
j -= INT_ANGLE_360;
|
|
|
|
MoveAmount += (MoveFactor + MoveHalfFactor); // 12;
|
|
if (MoveAmount > MAX_AMOUNT)
|
|
MoveAmount = MAX_AMOUNT;
|
|
MoveAngle = j;
|
|
}
|
|
|
|
|
|
if (AckKeys[C_KEY])
|
|
{
|
|
ae->SysFlags ^= SYS_SOLID_CEIL;
|
|
ae->SysFlags &= ~SYS_SOLID_BACK;
|
|
AckKeys[C_KEY] = 0;
|
|
|
|
if ((ae->SysFlags & SYS_SOLID_CEIL) && (ResScrollBack != 0))
|
|
ae->SysFlags |= SYS_SOLID_BACK;
|
|
AckRegisterStructure(ae);
|
|
}
|
|
|
|
if (AckKeys[R_KEY])
|
|
{
|
|
AckKeys[R_KEY] = 0;
|
|
Resolution++;
|
|
if (Resolution > 2)
|
|
Resolution = 0;
|
|
}
|
|
|
|
if (AckKeys[F_KEY])
|
|
{
|
|
ae->SysFlags ^= SYS_SOLID_FLOOR;
|
|
AckKeys[F_KEY] = 0;
|
|
AckRegisterStructure(ae);
|
|
}
|
|
|
|
|
|
if (AckKeys[PGUP_KEY] && ViewHeight < 60)
|
|
{
|
|
ViewHeight++;
|
|
CeilingHeight++;
|
|
}
|
|
|
|
if (AckKeys[PGDN_KEY] && ViewHeight > 4)
|
|
{
|
|
ViewHeight--;
|
|
CeilingHeight--;
|
|
}
|
|
|
|
if (AckKeys[NUM_1_KEY])
|
|
{
|
|
AckKeys[NUM_1_KEY]=0;
|
|
dFactor--;
|
|
}
|
|
|
|
if (AckKeys[NUM_2_KEY])
|
|
{
|
|
AckKeys[NUM_2_KEY]=0;
|
|
dFactor++;
|
|
}
|
|
|
|
|
|
if (AckKeys[MINUS_KEY])
|
|
{
|
|
AckKeys[MINUS_KEY]=0;
|
|
mFactor--;
|
|
}
|
|
|
|
if (AckKeys[PLUS_KEY])
|
|
{
|
|
AckKeys[PLUS_KEY]=0;
|
|
mFactor++;
|
|
}
|
|
|
|
if (AckKeys[I_KEY])
|
|
{
|
|
AckKeys[I_KEY] = 0;
|
|
InfoFlag ^= 1;
|
|
}
|
|
|
|
if (AckKeys[B_KEY])
|
|
{
|
|
AckKeys[B_KEY]=0;
|
|
mFactor -= 64;
|
|
}
|
|
|
|
if (AckKeys[S_KEY])
|
|
{
|
|
AckKeys[S_KEY] = 0;
|
|
mFactor += 64;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
EndBGmusic();
|
|
ShutDownFlag = 1;
|
|
AckSlowDown(); // Set the timer back to normal speed
|
|
AckWrapUp(ae);
|
|
AckSetTextmode();
|
|
|
|
if (kbhit())
|
|
getch();
|
|
|
|
return(0);
|
|
}
|
|
|