c/237: Memory chunks > 64 KB mirrors
tolf@usa.net
tolf@usa.net
Tue May 23 12:56:00 GMT 2000
>Number: 237
>Category: c
>Synopsis: Memory chunks > 64 KB mirrors
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Tue May 23 12:56:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator: Fredrik Tolf
>Release: 2.95.2 19991024
>Organization:
>Environment:
Windows 95, Intel 486-DX 50 MHz, 16 MB RAM
DJGPP is executed over network, mapped path = Z:\DJGPP
>Description:
I allocate two memory chunks, 6.4 MB each, but as I try to write to one of them, I can only write in the first 64 KB area, and the data is mirrored every 65536th byte forward. The program is translated from a real-mode program, so I guess the problem might lie there, but I've been unable to find any bugs myself.
To solve this problem, I downloaded my current version of DJGPP (I think the former version was 2.10). This, however, resulted in complete unability to compile the program. The assembler reports the following line:
z:/djgpp/tmp\cc7Q9EAd.s:4624: Error: Ignoring junk ôF' after expression
>How-To-Repeat:
Start the program.
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="kvidha.c"
Content-Disposition: inline; filename="kvidha.c"
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <memory.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <go32.h>
#include <sys\farptr.h>
#include <pc.h>
#include <dpmi.h>
#define NUM_KEYS 9
#define MAX_STACK 16
#define MAX_LINES 100
#define MAX_PIXELS 5000
#define NUM_COLORS 256
#define NUM_PLANES 2
#define NUM_SCRIPTS 4
#define MAX_SPRITES 1000
#define MAX_PLAYERS 16
#define MAX_OBJECTS 1000
#define NUM_WEAPONS 6
#define MAX_HITTESTS 100
#define SHOW_MAP 0
#define MAP_SHOOTABLE 1
#define MAP_WALKABLE 2
#define MAP_DESTROYABLE 4
typedef struct PixelType
{
float x;
float y;
float xv;
float yv;
unsigned char c;
unsigned char SetColor;
unsigned char Explode;
signed short Damage;
unsigned char Owner;
unsigned char Used;
} Pixel;
typedef struct CacheType
{
unsigned short w;
unsigned short h;
unsigned char NumFrames;
unsigned char **Frames;
signed short *cx;
signed short *cy;
unsigned char AnimDelay;
} Cache;
typedef struct SpriteType
{
signed short x;
signed short y;
signed char xv;
signed char yv;
unsigned char AnimCount;
unsigned char AnimTimer;
unsigned char CurFrame;
unsigned char Template;
unsigned char Used;
} Sprite;
typedef struct WeaponType
{
unsigned short Class;
unsigned short ReloadDelay;
unsigned short FireDelay;
unsigned short Ammo;
unsigned short MaxClips;
unsigned long Name;
unsigned short NameLength;
} Weapon;
typedef struct PWeaponType
{
unsigned short Weapon;
unsigned short ReloadTimer;
unsigned short FireTimer;
unsigned short AmmoLeft;
unsigned short NumClips;
signed short Vars[4];
unsigned char Used;
} PWeapon;
typedef struct PlayerType
{
unsigned char Visual;
unsigned short VPointX1;
unsigned short VPointY1;
unsigned short VPointX2;
unsigned short VPointY2;
unsigned short AMeterX1;
unsigned short AMeterY1;
unsigned short AMeterX2;
unsigned short AMeterY2;
unsigned short LMeterX1;
unsigned short LMeterY1;
unsigned short LMeterX2;
unsigned short LMeterY2;
unsigned short lx, ly;
unsigned short kx, ky;
unsigned short cx, cy;
unsigned short Object;
unsigned short VPObject;
unsigned char Keys[NUM_KEYS];
unsigned short KeyCodes[NUM_KEYS];
unsigned char Left;
unsigned char Right;
unsigned char Up;
unsigned char Down;
unsigned char Change;
unsigned char Shoot;
signed short CurWeapon;
float Angle;
float AngleVel;
unsigned char Dir;
unsigned char CrossColor;
signed short Health;
signed short MaxHealth;
signed char PVars[40];
unsigned char Used;
} Player;
typedef struct ClassType
{
unsigned char *Code;
unsigned short Scripts[NUM_SCRIPTS];
unsigned char TickDelay;
unsigned char Sprite;
unsigned char StartFrame;
unsigned char RunHitTests;
signed short GravityMod;
} Class;
typedef struct ObjectType
{
float x;
float y;
float xv;
float yv;
unsigned short Class;
unsigned char TickTimer;
signed short Variables[4];
unsigned short SpriteLink;
unsigned char Owner;
unsigned char Used;
} Object;
typedef struct LineType
{
signed short x1, y1;
signed short x2, y2;
unsigned char c1, c2;
unsigned char Used;
} Line;
typedef struct PalType
{
unsigned char r;
unsigned char g;
unsigned char b;
} Pal;
void SetMapPixel(unsigned short x, unsigned short y, unsigned char c, unsigned short Handle);
unsigned char GetMapPixel(unsigned short x, unsigned short y, unsigned short Handle);
void ShowMap(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, unsigned short MapX, unsigned short MapY);
void SetMode(unsigned char Mode);
unsigned char SeekData(char *ID);
unsigned char LoadSprite(char *ID, unsigned short CacheNum);
unsigned short SpawnSprite(unsigned char Template, signed short x, signed short y, signed char xv, signed char yv, unsigned short AnimCount, unsigned char StartFrame);
unsigned char Init(unsigned short *Result);
void Terminate(void);
void SpawnPixel(unsigned short x, unsigned short y, float xv, float yv, unsigned char Owner, unsigned char SetColor, unsigned char Explode, signed short Damage, unsigned char c);
void ControlSprites(void);
void ControlPixels(void);
unsigned char ArgExist(int argc, char *argv[], char *Match);
int main(int argc, char *argv[]);
void CopyToMap(signed short x, signed short y, char *Buffer, unsigned short w, unsigned short h, unsigned char bgc, unsigned char ColorPattern, unsigned char DestroyAll, unsigned short Attributes);
void SpawnExplosion(signed short x, signed short y, unsigned char StartFrame, unsigned char Smokes);
unsigned short SpawnObject(unsigned short Class, unsigned char Owner, unsigned short x, unsigned short y, float xv, float yv);
void ControlObjects(void);
unsigned short WallAngle(unsigned short x, unsigned short y);
void GetInputs(void);
void DBPrint(unsigned char *Buffer, signed short x, signed short y, unsigned char bgc);
unsigned char CollisionTest(signed short *x1, signed short *y1, signed short *x2, signed short *y2, unsigned char Pattern, unsigned char RunHitTests, unsigned short *ObjNum);
void DrawLine(signed short x1, signed short y1, signed short x2, signed short y2, unsigned char c1, unsigned char c2);
unsigned short CalcAngle(signed short x1, signed short y1, signed short x2, signed short y2);
void AddHitTest(unsigned short ObjNum);
void RemoveHitTest(unsigned short ObjNum);
void HurtRadius(signed short x, signed short y, signed short StartDamage, signed short StopDamage, unsigned short StartDecRadius, unsigned short StopRadius);
void CollVel(signed short x, signed short y, float *xv, float *yv, unsigned char Attributes);
void MessageBox(unsigned char *Buffer);
Pixel *Pixels[MAX_PIXELS];
Cache **Caches;
Sprite *Sprites[MAX_SPRITES];
Object *Objects[MAX_OBJECTS];
Player *Players[MAX_PLAYERS];
PWeapon *PWeapons[MAX_PLAYERS][NUM_WEAPONS];
Class **Classes;
Weapon **Weapons;
Line *Lines[MAX_LINES];
unsigned short HitTests[MAX_HITTESTS];
unsigned char *Strings;
Pal Palette[NUM_COLORS];
unsigned char ColorInfo[NUM_COLORS];
FILE *DataFile;
float Gravity;
unsigned char *VBuffer = (unsigned char *)0x000A0000;
unsigned char *DblBuffer;
unsigned char *MapBuffer[NUM_PLANES];
signed short clip_x1, clip_x2;
signed short clip_y1, clip_y2;
unsigned char *TempMem;
unsigned short PagesFree;
unsigned short BGSprite, BGFrame;
unsigned short LevelWidth, LevelHeight;
unsigned short MaxLW, MaxLH;
unsigned short NumSprites;
unsigned short NumClasses;
unsigned short NumWeapons;
unsigned char DebugMode;
unsigned short FrameRate;
unsigned short FontSprite;
signed short Regs[32];
unsigned char StackPos;
unsigned short Stack[MAX_STACK];
_go32_dpmi_seginfo OldTimerInt;
_go32_dpmi_seginfo NewTimerIntIret;
_go32_dpmi_seginfo OldKeyInt;
_go32_dpmi_seginfo NewKeyIntIret;
unsigned char raw_key;
unsigned char SpecialKey;
unsigned char ReadyToGo;
unsigned short AsciiTable[256];
float Sine[360], Cosine[360];
unsigned char KeyTable[256];
unsigned short LastShot;
unsigned char *TextBuffer;
unsigned char *KeyboardBuffer;
unsigned char KeybWritePos;
#include "dblbuf.c"
#include "executor.c"
void NewKeyInt()
{
raw_key = inp(0x60);
__asm__ (
"sti\n"
"in $61, %al\n"
"or $82, %al\n"
"out %al, $61\n"
"and $7F, %al\n"
"out %al, $61\n"
"mov $20, %al\n"
"out %al, $20\n"
);
if(raw_key < 128)
{
if(SpecialKey == 1)
{
KeyTable[raw_key + 128] = 1;
SpecialKey = 0;
} else {
KeyTable[raw_key] = 1;
}
} else {
if(raw_key == 0xE0)
{
SpecialKey = 1;
} else {
if(SpecialKey == 1)
{
KeyTable[raw_key] = 0;
SpecialKey = 0;
} else {
raw_key -= 128;
KeyTable[raw_key] = 0;
}
}
}
}
void CopyToMap(signed short x, signed short y, char *Buffer, unsigned short w, unsigned short h, unsigned char bgc, unsigned char ColorPattern, unsigned char DestroyAll, unsigned short Attributes)
{
unsigned short offset;
unsigned short cx, cy, i;
unsigned char data;
unsigned char Colors[NUM_COLORS];
unsigned char NumColors;
NumColors = 0;
for(i = 0; i < NUM_COLORS; i++)
{
if(ColorInfo[i] == ColorPattern)
Colors[NumColors++] = i;
}
offset = 0;
for(cy=0;cy<h;cy++)
{
for(cx=0;cx<w;cx++)
{
data = Buffer[offset];
TempMem[offset] = 0;
if((data != bgc) && (x + cx >= 0) && (x + cx < LevelWidth) && (y + cy >= 0) && (y + cy < LevelHeight))
{
if(((GetMapPixel(x + cx, y + cy, 1) & MAP_DESTROYABLE) == MAP_DESTROYABLE) | DestroyAll == 1)
{
if(Attributes != 0xFFFF)
SetMapPixel(x + cx, y + cy, (unsigned char)Attributes, 1);
TempMem[offset] = 1;
}
}
offset++;
}
}
offset = 0;
if(ColorPattern == 0)
{
for(cy=0;cy<h;cy++)
{
for(cx=0;cx<w;cx++)
{
data = Buffer[offset];
if((data != bgc) && (x + cx >= 0) && (x + cx < LevelWidth) && (y + cy >= 0) && (y + cy < LevelHeight))
{
if(TempMem[offset] == 1)
{
SetMapPixel(x + cx, y + cy, data, 0);
}
}
offset++;
}
}
} else {
for(cy=0;cy<h;cy++)
{
for(cx=0;cx<w;cx++)
{
data = Buffer[offset];
if((data != bgc) && (x + cx >= 0) && (x + cx < LevelWidth) && (y + cy >= 0) && (y + cy < LevelHeight))
{
if(TempMem[offset] == 1)
{
SetMapPixel(x + cx, y + cy, Colors[rand() % NumColors], 0);
}
}
offset++;
}
}
}
}
void ChangeTimer(unsigned short Frequency)
{
unsigned short SkipCount;
SkipCount = 1193182 / Frequency;
outp(0x43, 0x3C);
outp(0x40, (unsigned char)(SkipCount & 0xFF));
outp(0x40, (unsigned char)(SkipCount >> 8));
}
void TimerInt(void)
{
ReadyToGo = 1;
}
void SetMapPixel(unsigned short x, unsigned short y, unsigned char c, unsigned short Handle)
{
if((x >= LevelWidth) || (y >= LevelHeight))
return;
MapBuffer[Handle][x + (y * LevelWidth)] = c;
}
unsigned char GetMapPixel(unsigned short x, unsigned short y, unsigned short Handle)
{
if((x >= LevelWidth) || (y >= LevelHeight))
return(0);
return(MapBuffer[Handle][x + (y * LevelWidth)]);
}
void ShowMap(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, unsigned short MapX, unsigned short MapY)
{
unsigned short Window;
unsigned short cwx, cwy;
signed short x, y;
unsigned short i;
unsigned short CurFrame;
unsigned char Template;
if((MapX >= LevelWidth) || (MapY >= LevelHeight)) return;
DBSetClip(x1, y1, x2, y2);
cwx = (MapX / 2) % Caches[BGSprite]->w;
cwy = (MapY / 2) % Caches[BGSprite]->h;
for(y = (signed short)(y1 - Caches[BGSprite]->h); y <= (signed short)y2; y += Caches[BGSprite]->h)
{
for(x = (signed short)(x1 - Caches[BGSprite]->w); x <= (signed short)x2; x += Caches[BGSprite]->w)
{
DBCopyBufferClip((signed short)x - cwx, (signed short)y - cwy, Caches[BGSprite]->Frames[BGFrame], Caches[BGSprite]->w, Caches[BGSprite]->h, -1);
}
}
DBCopyBufferClip((signed short)x1 - (signed short)MapX, (signed short)y1 - (signed short)MapY, MapBuffer[0], LevelWidth, LevelHeight, 0);
for(i = 0; i < MAX_LINES; i++)
{
if(Lines[i]->Used == 1)
DBLine(Lines[i]->x1 - MapX + x1, Lines[i]->y1 - MapY + y1, Lines[i]->x2 - MapX + x1, Lines[i]->y2 - MapY + y1, Lines[i]->c1, Lines[i]->c2);
}
for(i = 0; i < MAX_PIXELS; i++)
{
if(Pixels[i]->Used == 1)
DBPSetC((unsigned short)(Pixels[i]->x - MapX + x1), (unsigned short)(Pixels[i]->y - MapY + y1), Pixels[i]->c);
}
for(i = 0; i < MAX_SPRITES; i++)
{
if(Sprites[i]->Used == 1)
{
CurFrame = Sprites[i]->CurFrame;
Template = Sprites[i]->Template;
DBCopyBufferClip((signed short)(Sprites[i]->x - MapX - Caches[Template]->cx[CurFrame] + x1), (signed short)(Sprites[i]->y - MapY - Caches[Template]->cy[CurFrame] + y1), Caches[Template]->Frames[CurFrame], Caches[Template]->w, Caches[Template]->h, 0);
}
}
DBSetClip(0, 0, 319, 199);
}
void DrawScreen(void)
{
unsigned short i, x, y, x2, y2;
unsigned short cx, cy;
signed short tx, ty, CurWeapon;
float Per;
DBFRect(0, 0, 319, 199, 0);
for(i = 0; i < MAX_PLAYERS; i++)
{
if(Players[i]->Visual == 1)
{
x = Objects[Players[i]->VPObject]->x;
y = Objects[Players[i]->VPObject]->y;
cx = (Players[i]->VPointX2 - Players[i]->VPointX1) >> 1;
cy = (Players[i]->VPointY2 - Players[i]->VPointY1) >> 1;
if(x < cx) x = cx;
if(y < cy) y = cy;
if(x > LevelWidth - cx - 2)
x = LevelWidth - cx - 2;
if(y > LevelHeight - cy - 2)
y = LevelHeight - cy - 2;
ShowMap(Players[i]->VPointX1, Players[i]->VPointY1, Players[i]->VPointX2, Players[i]->VPointY2, x - cx, y - cy);
DBSetClip(Players[i]->VPointX1, Players[i]->VPointY1, Players[i]->VPointX2, Players[i]->VPointY2);
x2 = (unsigned short)((unsigned short)(Objects[Players[i]->Object]->x) + (Cosine[(unsigned short)Players[i]->Angle] * ((Players[i]->Dir == 0)?15:-15)) - x + cx + Players[i]->VPointX1 + ((Players[i]->Dir == 0)?3:-2));
y2 = (unsigned short)((unsigned short)(Objects[Players[i]->Object]->y) - (Sine[(unsigned short)Players[i]->Angle] * 15) - y + cy + Players[i]->VPointY1 - 2);
DBPSetC(x2 - 1, y2, Players[i]->CrossColor);
DBPSetC(x2 + 1, y2, Players[i]->CrossColor);
DBPSetC(x2, y2 - 1, Players[i]->CrossColor);
DBPSetC(x2, y2 + 1, Players[i]->CrossColor);
if(Players[i]->Change)
{
tx = (signed short)(Objects[Players[i]->Object]->x - x + cx + Players[i]->VPointX1 - (Weapons[PWeapons[i][Players[i]->CurWeapon]->Weapon]->NameLength * 2));
ty = (signed short)(Objects[Players[i]->Object]->y - y + cy + Players[i]->VPointY1 - 20);
DBPrint((unsigned char *)&Strings[Weapons[PWeapons[i][Players[i]->CurWeapon]->Weapon]->Name], tx, ty, 0);
}
DBSetClip(0, 0, 319, 199);
CurWeapon = Players[i]->CurWeapon;
if(PWeapons[i][CurWeapon]->ReloadTimer == 0)
{
Per = (float)PWeapons[i][Players[i]->CurWeapon]->AmmoLeft / (float)Weapons[PWeapons[i][Players[i]->CurWeapon]->Weapon]->Ammo;
} else {
Per = (float)PWeapons[i][CurWeapon]->ReloadTimer / (float)Weapons[PWeapons[i][CurWeapon]->Weapon]->ReloadDelay;
}
DBFRect(Players[i]->AMeterX1, Players[i]->AMeterY1, Players[i]->AMeterX1 + (signed short)(Per * (Players[i]->AMeterX2 - Players[i]->AMeterX1)), Players[i]->AMeterY2, 48 + (unsigned char)(Per * 7));
Per = (float)Players[i]->Health / (float)Players[i]->MaxHealth;
DBFRect(Players[i]->LMeterX1, Players[i]->LMeterY1, Players[i]->LMeterX1 + (signed short)(Per * (Players[i]->LMeterX2 - Players[i]->LMeterX1)), Players[i]->LMeterY2, 40 + (unsigned char)(Per * 7));
}
}
if(SHOW_MAP == 1)
{
for(y = 0; y < 40; y++)
{
for(x = 0; x < 64; x++)
{
DBPSetC(128 + x, 160 + y, GetMapPixel(x * (LevelWidth * 5), y * (LevelHeight * 5), 0));
}
}
for(i = 0; i < MAX_PLAYERS; i++)
{
if(Players[i]->Used == 1)
{
DBPSetC(128 + (unsigned short)(Objects[Players[i]->Object]->x / (LevelWidth * 5)), 160 + (unsigned short)(Objects[Players[i]->Object]->y / (LevelHeight * 5)), 6);
}
}
}
}
unsigned short CalcAngle(signed short x1, signed short y1, signed short x2, signed short y2)
{
double a;
unsigned char Q;
if(x1 == x2)
{
if(y1 >= y2)
return(90);
if(y1 < y2)
return(270);
}
a = atan((double)(y1 - y2) / (double)(x1 - x2));
if(a < 0)
a = -a;
if((y1 >= y2) && (x1 < x2))
Q = 0;
if((y1 >= y2) && (x1 >= x2))
{
Q = 1;
a = 1.570796 - a;
}
if((y1 < y2) && (x1 >= x2))
Q = 2;
if((y1 < y2) && (x1 < x2))
{
Q = 3;
a = 1.570796 - a;
}
return((unsigned short)(((a + (Q * 1.570796)) / 3.141593) * 180));
}
void GetInputs(void)
{
static Row = 1;
unsigned char i, o;
for(i = 0; i < MAX_PLAYERS; i++)
{
for(o = 0; o < NUM_KEYS; o++)
{
if(((Players[i]->KeyCodes[o] & 0xFF00) == 0)?(KeyTable[Players[i]->KeyCodes[o]] == 1):((KeyTable[(Players[i]->KeyCodes[o] & 0xFF00) >> 8] == 1) && (KeyTable[Players[i]->KeyCodes[o] & 0x00FF] == 1)))
{
if(Players[i]->Keys[o] == 0)
{
Players[i]->Keys[o] = 1;
} else {
Players[i]->Keys[o] = 2;
}
} else {
Players[i]->Keys[o] = 0;
}
}
}
}
void SetMode(unsigned char Mode)
{
union REGS Regs;
Regs.h.ah = 0;
Regs.h.al = Mode;
_int86(0x10, &Regs, &Regs);
}
void MessageBox(unsigned char *Buffer)
{
DBFRect(68, 88, 252, 112, 40);
DBFRect(69, 89, 251, 111, 0);
DBPrint(Buffer, 70, 90, 255);
DisplayDB();
while(KeyTable[57] == 1);
while(KeyTable[57] == 0);
}
unsigned char SeekData(char *ID)
{
unsigned long offset;
unsigned long endoffset;
unsigned long i;
unsigned char BufferOffset;
unsigned short Pointer;
char InpBuffer;
char Buffer[80];
fseek(DataFile, 0, SEEK_SET);
fread((void *)&offset, 4, 1, DataFile);
fread((void *)&endoffset, 4, 1, DataFile);
fseek(DataFile, offset, SEEK_SET);
BufferOffset = 0;
Pointer = 0;
for(i = 0; i < endoffset - offset; i++)
{
fread((void *)&InpBuffer, 1, 1, DataFile);
Buffer[BufferOffset++] = InpBuffer;
if(InpBuffer == 0)
{
Pointer++;
BufferOffset = 0;
if(strcmp(ID, (char *)Buffer) == 0)
{
fseek(DataFile, Pointer * 4, SEEK_SET);
fread((void *)&offset, 4, 1, DataFile);
fseek(DataFile, offset, SEEK_SET);
return(1);
}
}
}
return(0);
}
unsigned char LoadSprite(char *ID, unsigned short CacheNum)
{
unsigned short i, o, Found;
if(SeekData(ID) == 0)
return(1);
fread((void *)&Caches[CacheNum]->w, 2, 1, DataFile);
fread((void *)&Caches[CacheNum]->h, 2, 1, DataFile);
fread((void *)&Caches[CacheNum]->NumFrames, 1, 1, DataFile);
fread((void *)&Caches[CacheNum]->AnimDelay, 1, 1, DataFile);
if((Caches[CacheNum]->cx = (signed short *)malloc(Caches[CacheNum]->NumFrames * 2)) == NULL)
return(2);
if((Caches[CacheNum]->cy = (signed short *)malloc(Caches[CacheNum]->NumFrames * 2)) == NULL)
return(2);
if((Caches[CacheNum]->Frames = (unsigned char **)malloc(Caches[CacheNum]->NumFrames * 4)) == NULL)
return(2);
for(o = 0; o < Caches[CacheNum]->NumFrames; o++)
{
fread((void *)&Caches[CacheNum]->cx[o], 2, 1, DataFile);
fread((void *)&Caches[CacheNum]->cy[o], 2, 1, DataFile);
if((Caches[CacheNum]->Frames[o] = (unsigned char *)malloc(Caches[CacheNum]->w * Caches[CacheNum]->h)) == NULL)
return(2);
fread((void *)Caches[CacheNum]->Frames[o], Caches[CacheNum]->w * Caches[CacheNum]->h, 1, DataFile);
}
return(0);
}
unsigned short SpawnSprite(unsigned char Template, signed short x, signed short y, signed char xv, signed char yv, unsigned short AnimCount, unsigned char StartFrame)
{
unsigned short i, o, Found;
Found = 0;
for(i = 0; i < MAX_SPRITES; i++)
{
if(Sprites[i]->Used == 0)
{
Found = 1;
Sprites[i]->x = x;
Sprites[i]->y = y;
Sprites[i]->xv = xv;
Sprites[i]->yv = yv;
Sprites[i]->AnimTimer = 0;
Sprites[i]->AnimCount = AnimCount;
Sprites[i]->CurFrame = StartFrame;
Sprites[i]->Template = Template;
Sprites[i]->Used = 1;
break;
}
}
return((Found == 0)?0xFFFF:i);
}
unsigned long GetString(unsigned short StringNum, unsigned short *Length)
{
unsigned long Offset, Offset2;
unsigned short Count;
Offset = 0;
Count = 0;
while(Count < StringNum)
{
if(Strings[Offset++] == 0)
Count++;
}
Offset2 = Offset;
while(Strings[Offset2++] != 0);
if(Length != NULL)
*Length = Offset2 - Offset;
return(Offset);
}
void LoadLayout(unsigned char NumPlayers)
{
unsigned char i;
unsigned short Buffer[18];
SeekData("Layouts");
for(i = 0; i < NumPlayers - 1; i++)
{
fseek(DataFile, 36 * (i + 1), SEEK_CUR);
}
for(i = 0; i < NumPlayers; i++)
{
fread((void *)&Buffer, 2, 18, DataFile);
Players[i]->VPointX1 = Buffer[0];
Players[i]->VPointY1 = Buffer[1];
Players[i]->VPointX2 = Buffer[2];
Players[i]->VPointY2 = Buffer[3];
Players[i]->AMeterX1 = Buffer[4];
Players[i]->AMeterY1 = Buffer[5];
Players[i]->AMeterX2 = Buffer[6];
Players[i]->AMeterY2 = Buffer[7];
Players[i]->LMeterX1 = Buffer[8];
Players[i]->LMeterY1 = Buffer[9];
Players[i]->LMeterX2 = Buffer[10];
Players[i]->LMeterY2 = Buffer[11];
Players[i]->lx = Buffer[12];
Players[i]->ly = Buffer[13];
Players[i]->kx = Buffer[14];
Players[i]->ky = Buffer[15];
Players[i]->cx = Buffer[16];
Players[i]->cy = Buffer[17];
}
}
void InitVar(void)
{
unsigned short i, o;
Players[0]->KeyCodes[0] = 203; //Left: Left Arrow
Players[0]->KeyCodes[1] = 205; //Right: Right Arrow
Players[0]->KeyCodes[2] = 200; //Up: Up Arrow
Players[0]->KeyCodes[3] = 208; //Down: Down Arrow
Players[0]->KeyCodes[4] = 157; //Shoot: Right Ctrl
Players[0]->KeyCodes[5] = 54; //Change: Right Shift
Players[0]->KeyCodes[6] = 28; //Jump: Enter
Players[0]->KeyCodes[7] = (54 << 8) + 28; //Ninja Rope: Right Shift + Enter
Players[0]->KeyCodes[8] = (54 << 8) + 157; //Trigger: Right Shift + Right Ctrl
Players[1]->KeyCodes[0] = 33; //Left: F
Players[1]->KeyCodes[1] = 35; //Right: H
Players[1]->KeyCodes[2] = 20; //Up: T
Players[1]->KeyCodes[3] = 34; //Down: G
Players[1]->KeyCodes[4] = 4; //Shoot: 3
Players[1]->KeyCodes[5] = 3; //Change: 2
Players[1]->KeyCodes[6] = 2; //Jump: 1
Players[1]->KeyCodes[7] = (3 << 8) + 2; //Ninja Rope: 2 + 1
Players[1]->KeyCodes[8] = (3 << 8) + 4; //Trigger: 2 + 3
Players[0]->Visual = 1;
Players[1]->Visual = 1;
Players[0]->Angle = 0;
Players[0]->AngleVel = 0;
Players[0]->Dir = 0;
Players[0]->MaxHealth = 100;
Players[0]->Health = Players[0]->MaxHealth;
Players[1]->Angle = 0;
Players[1]->AngleVel = 0;
Players[1]->Dir = 0;
Players[1]->MaxHealth = 100;
Players[1]->Health = Players[1]->MaxHealth;
LoadLayout(2);
for(i = 0; i < 2; i++)
{
for(o = 0; o < 6; o++)
{
PWeapons[i][o]->Weapon = o;
PWeapons[i][o]->Used = 1;
}
}
Players[0]->CurWeapon = 4;
Players[1]->CurWeapon = 1;
for(i = 0; i < MAX_PLAYERS; i++)
{
for(o = 0; o < NUM_WEAPONS; o++)
{
if((Players[i]->Used == 1) && (PWeapons[i][o]->Used == 1))
{
PWeapons[i][o]->AmmoLeft = Weapons[PWeapons[i][o]->Weapon]->Ammo;
PWeapons[i][o]->FireTimer = 0;
PWeapons[i][o]->ReloadTimer = 0;
PWeapons[i][o]->NumClips = Weapons[PWeapons[i][o]->Weapon]->MaxClips;
}
}
}
BGSprite = 10;
BGFrame = 0;
}
unsigned char Init(unsigned short *Result)
{
unsigned short Segment, Total;
unsigned short i, o;
unsigned char Buffer[80], InpBuffer, BufferPos, Finished;
unsigned long LastPos, Offset;
unsigned short DataLength, Count;
printf("Initializing...\n");
if((DataFile = fopen("KVID.DAT", "rb")) == NULL)
return(3);
if(DebugMode != 0)
printf("Initializing double buffer...\n");
if((DblBuffer = (unsigned char *)malloc(64000)) == NULL)
return(2);
if((TempMem = (unsigned char *)malloc(64000)) == NULL)
return(2);
for(i=0;i<64000;i++)
{
DblBuffer[i] = 0;
}
DBSetClip(0, 0, 319, 199);
if(DebugMode != 0)
printf("Initializing level...\n");
MaxLW = 10;
MaxLH = 10;
for(i = 0; i < NUM_PLANES; i++)
{
if((MapBuffer[i] = (unsigned char *)malloc(MaxLW * MaxLH * 64000)) == NULL)
return(5);
}
if(DebugMode != 0)
printf("Initializing variables...\n");
for(i = 0; i < MAX_HITTESTS; i++)
{
HitTests[i] = 0xFFFF;
}
for(i = 0; i < MAX_PIXELS; i++)
{
if((Pixels[i] = (Pixel *)malloc(sizeof(Pixel))) == NULL)
return(2);
Pixels[i]->Used = 0;
}
for(i = 0; i < MAX_SPRITES; i++)
{
if((Sprites[i] = (Sprite *)malloc(sizeof(Sprite))) == NULL)
return(2);
Sprites[i]->Used = 0;
}
for(i = 0; i < MAX_OBJECTS; i++)
{
if((Objects[i] = (Object *)malloc(sizeof(Object))) == NULL)
return(2);
Objects[i]->Used = 0;
}
for(i = 0; i < MAX_PLAYERS; i++)
{
if((Players[i] = (Player *)malloc(sizeof(Player))) == NULL)
return(2);
Players[i]->Used = 0;
Players[i]->Visual = 0;
}
for(i = 0; i < MAX_PLAYERS; i++)
{
for(o = 0; o < NUM_WEAPONS; o++)
{
if((PWeapons[i][o] = (PWeapon *)malloc(sizeof(PWeapon))) == NULL)
return(2);
PWeapons[i][o]->Used = 0;
}
}
for(i = 0; i < MAX_LINES; i++)
{
if((Lines[i] = (Line *)malloc(sizeof(Line))) == NULL)
return(2);
Lines[i]->Used = 0;
}
if((TextBuffer = (unsigned char *)malloc(500)) == NULL)
return(2);
if((KeyboardBuffer = (unsigned char *)malloc(500)) == NULL)
return(2);
Gravity = 0.02;
LevelWidth = 320 * 2;
LevelHeight = 200 * 2;
FrameRate = 500;
srand((unsigned int)time(NULL));
for(i = 0; i < 360; i++)
{
Sine[i] = sin(((float)i / 180) * 3.141593);
Cosine[i] = cos(((float)i / 180) * 3.141593);
}
if(DebugMode != 0)
printf("Loading data...\n");
if(SeekData("Layouts") == 0)
return(4);
if(SeekData("DefaultPalette") == 0)
return(4);
fread((void *)Palette, sizeof(Pal), NUM_COLORS, DataFile);
if(SeekData("ColorInfo") == 0)
return(4);
fread((void *)ColorInfo, 1, NUM_COLORS, DataFile);
if(SeekData("AsciiConv") == 0)
return(4);
fread((void *)AsciiTable, 2, 256, DataFile);
if(SeekData("Strings") == 0)
return(4);
fread((void *)&LastPos, 4, 1, DataFile);
if((Strings = (unsigned char *)malloc((unsigned short)LastPos)) == NULL)
return(2);
for(Offset = 0; Offset < LastPos; Offset++)
{
fread((void *)&InpBuffer, 1, 1, DataFile);
Strings[Offset] = InpBuffer;
}
if(SeekData("SpriteCache") == 0)
return(4);
fread((void *)&NumSprites, 2, 1, DataFile);
if((Caches = (Cache **)malloc(4 * NumSprites)) == NULL)
return(2);
for(i = 0; i < NumSprites; i++)
{
if((Caches[i] = (Cache *)malloc(sizeof(Cache))) == NULL)
return(2);
BufferPos = 0;
Finished = 0;
while(Finished == 0)
{
fread((void *)&InpBuffer, 1, 1, DataFile);
if(InpBuffer == 0)
{
Buffer[BufferPos] = 0;
LastPos = ftell(DataFile);
switch(LoadSprite((char *)Buffer, i))
{
case 1:
return(4);
case 2:
return(2);
}
if(strcmp((char *)Buffer, (char *)"Spr_Font") == 0)
FontSprite = i;
fseek(DataFile, LastPos, SEEK_SET);
Finished = 1;
} else
{
Buffer[BufferPos++] = InpBuffer;
}
}
}
if(SeekData("Classes") == 0)
return(4);
fread((void *)&NumClasses, 2, 1, DataFile);
if((Classes = (Class **)malloc(4 * NumClasses)) == NULL)
return(2);
for(i = 0; i < NumClasses; i++)
{
if((Classes[i] = (Class *)malloc(sizeof(Class))) == NULL)
return(2);
fread((void *)&Classes[i]->Scripts, 2, NUM_SCRIPTS, DataFile);
fread((void *)&Classes[i]->TickDelay, 1, 1, DataFile);
fread((void *)&Classes[i]->GravityMod, 2, 1, DataFile);
fread((void *)&Classes[i]->Sprite, 1, 1, DataFile);
fread((void *)&Classes[i]->StartFrame, 1, 1, DataFile);
fread((void *)&Classes[i]->RunHitTests, 1, 1, DataFile);
fread((void *)&DataLength, 2, 1, DataFile);
if((Classes[i]->Code = (unsigned char *)malloc(DataLength)) == NULL)
return(2);
fread((void *)Classes[i]->Code, 1, DataLength, DataFile);
}
if(SeekData("WeaponInfo") == 0)
return(4);
fread((void *)&NumWeapons, 2, 1, DataFile);
if((Weapons = (Weapon **)malloc(4 * NumWeapons)) == NULL)
return(2);
for(i = 0; i < NumWeapons; i++)
{
if((Weapons[i] = (Weapon *)malloc(sizeof(Weapon))) == NULL)
return(2);
fread((void *)&Weapons[i]->Class, 2, 1, DataFile);
fread((void *)&Weapons[i]->ReloadDelay, 2, 1, DataFile);
fread((void *)&Weapons[i]->FireDelay, 2, 1, DataFile);
fread((void *)&Weapons[i]->Ammo, 2, 1, DataFile);
Weapons[i]->Name = 0;
fread((void *)&Weapons[i]->MaxClips, 2, 1, DataFile);
fread((void *)&Weapons[i]->Name, 2, 1, DataFile);
Weapons[i]->Name = GetString((unsigned short)Weapons[i]->Name, (unsigned short *)&Weapons[i]->NameLength);
}
if(DebugMode != 0)
printf("Initializing hardware...\n");
ChangeTimer(FrameRate);
printf("Done!\n");
getch();
_go32_dpmi_get_protected_mode_interrupt_vector(0x1C, &OldTimerInt);
_go32_dpmi_get_protected_mode_interrupt_vector(0x09, &OldKeyInt);
SetMode(0x13);
NewTimerIntIret.pm_offset = (unsigned long)TimerInt;
NewTimerIntIret.pm_selector = _go32_my_cs();
_go32_dpmi_allocate_iret_wrapper(&NewTimerIntIret);
_go32_dpmi_set_protected_mode_interrupt_vector(0x1C, &NewTimerIntIret);
NewKeyIntIret.pm_offset = (unsigned long)NewKeyInt;
NewKeyIntIret.pm_selector = _go32_my_cs();
_go32_dpmi_allocate_iret_wrapper(&NewKeyIntIret);
_go32_dpmi_set_protected_mode_interrupt_vector(0x09, &NewKeyIntIret);
for(i = 0; i < NUM_COLORS; i++)
{
outp(0x3c8, i);
outp(0x3c9, Palette[i].r);
outp(0x3c9, Palette[i].g);
outp(0x3c9, Palette[i].b);
}
return(0xFF);
}
void Terminate(void)
{
unsigned short i, o;
SetMode(0x03);
free(DblBuffer);
free(TempMem);
fclose(DataFile);
for(i = 0; i < NUM_PLANES; i++)
{
if(MapBuffer[i] != NULL)
free(MapBuffer[i]);
}
_go32_dpmi_set_protected_mode_interrupt_vector(0x09, &OldKeyInt);
_go32_dpmi_set_protected_mode_interrupt_vector(0x1C, &OldTimerInt);
_go32_dpmi_free_iret_wrapper(&NewKeyIntIret);
_go32_dpmi_free_iret_wrapper(&NewTimerIntIret);
outp(0x43, 0x3C);
outp(0x40, 0xFF);
outp(0x40, 0xFF);
for(i = 0; i < MAX_PIXELS; i++)
{
if(Pixels[i] != NULL)
free(Pixels[i]);
}
for(i = 0; i < NumSprites; i++)
{
if(Caches[i] != NULL)
{
if(Caches[i]->cx != NULL)
free(Caches[i]->cx);
if(Caches[i]->cy != NULL)
free(Caches[i]->cy);
if(Caches[i]->Frames != NULL)
{
for(o = 0; o < Caches[i]->NumFrames; o++)
{
if(Caches[i]->Frames[o] != NULL)
free(Caches[i]->Frames[o]);
}
free(Caches[i]->Frames);
}
free(Caches[i]);
}
}
if(Caches != NULL)
free(Caches);
for(i = 0; i < MAX_SPRITES; i++)
{
if(Sprites[i] != NULL)
free(Sprites[i]);
}
for(i = 0; i < MAX_PLAYERS; i++)
{
if(Players[i] != NULL)
free(Players[i]);
}
for(i = 0; i < MAX_OBJECTS; i++)
{
if(Objects[i] != NULL)
free(Objects[i]);
}
for(i = 0; i < NumClasses; i++)
{
if(Classes[i]->Code != NULL)
free(Classes[i]->Code);
if(Classes[i] != NULL)
free(Classes[i]);
}
if(Classes != NULL)
free(Classes);
for(i = 0; i < NumWeapons; i++)
{
if(Weapons[i] != NULL)
free(Weapons[i]);
}
if(Weapons != NULL)
free(Weapons);
for(i = 0; i < MAX_PLAYERS; i++)
{
for(o = 0; o < NUM_WEAPONS; o++)
{
if(PWeapons[i][o] != NULL)
free(PWeapons[i][o]);
}
}
for(i = 0; i < MAX_LINES; i++)
{
if(Lines[i] != NULL)
free(Lines[i]);
}
if(Strings != NULL)
free(Strings);
if(TextBuffer != NULL)
free(TextBuffer);
if(KeyboardBuffer != NULL)
free(KeyboardBuffer);
}
void HurtRadius(signed short x, signed short y, signed short StartDamage, signed short StopDamage, unsigned short StartDecRadius, unsigned short StopRadius)
{
unsigned short i;
signed long square, xdist, ydist;
unsigned short Radius;
signed short Damage;
for(i = 0; i < MAX_OBJECTS; i++)
{
if(Objects[i]->Used == 1)
{
xdist = (unsigned long)(x - (signed short)Objects[i]->x);
ydist = (unsigned long)(y - (signed short)Objects[i]->y);
square = (xdist * xdist) + (ydist * ydist);
Radius = (unsigned short)sqrt((double)square);
if(Radius < StopRadius)
{
if(Radius < StartDecRadius)
{
Damage = StartDamage;
} else {
Damage = (unsigned short)(((float)((StopRadius - StartDecRadius) - (Radius - StartDecRadius)) / (float)(StopRadius - StartDecRadius)) * (float)Damage);
}
Regs[16] = (signed short)i;
Regs[17] = (signed short)Damage;
Execute(Classes[Objects[i]->Class]->Code, (signed short *)&Objects[i]->Variables[0], Classes[Objects[i]->Class]->Scripts[3]); //TakeDamage
}
}
}
}
unsigned char CollisionTest(signed short *x1, signed short *y1, signed short *x2, signed short *y2, unsigned char Pattern, unsigned char RunHitTests, unsigned short *ObjNum)
{
signed short dx, dy, x, y, fx, fy;
signed short xi, yi, d;
unsigned short i, o, SpriteLink, Template;
unsigned long Offset;
unsigned char Data;
unsigned char *FrameBuffer;
dx = *x2 - *x1;
dy = *y2 - *y1;
if(dx >= 0)
{
xi = 1;
} else {
xi = -1;
dx = -dx;
}
if(dy >= 0)
{
yi = 1;
} else {
yi = -1;
dy = -dy;
}
d = 0;
x = *x1;
y = *y1;
if(dx > dy)
{
for(i = 0; i <= dx; i++)
{
if(i > 0)
{
Data = GetMapPixel((unsigned short)x, (unsigned short)y, 1);
if((Data & Pattern) == 0)
{
*x1 = fx;
*y1 = fy;
*x2 = x;
*y2 = y;
return(1);
}
if(RunHitTests == 1)
{
for(o = 0; o < MAX_HITTESTS; o++)
{
if(HitTests[o] == 0xFFFF)
break;
SpriteLink = Objects[HitTests[o]]->SpriteLink;
if(SpriteLink != 0xFFFF)
{
Template = Sprites[SpriteLink]->Template;
if((x >= Sprites[SpriteLink]->x - Caches[Template]->cx[Sprites[SpriteLink]->CurFrame]) && (y >= Sprites[SpriteLink]->y - Caches[Template]->cy[Sprites[SpriteLink]->CurFrame]) && (x < Sprites[SpriteLink]->x - Caches[Template]->cx[Sprites[SpriteLink]->CurFrame] + Caches[Template]->w) && (y < Sprites[SpriteLink]->y - Caches[Template]->cy[Sprites[SpriteLink]->CurFrame] + Caches[Template]->h))
{
Offset = x - Sprites[SpriteLink]->x + Caches[Template]->cx[Sprites[SpriteLink]->CurFrame];
Offset += (y - Sprites[SpriteLink]->y + Caches[Template]->cy[Sprites[SpriteLink]->CurFrame]) * Caches[Template]->w;
FrameBuffer = Caches[Template]->Frames[Sprites[SpriteLink]->CurFrame];
if(FrameBuffer[Offset] != 0)
{
*x1 = fx;
*y1 = fy;
*x2 = x;
*y2 = y;
*ObjNum = HitTests[o];
return(2);
}
}
}
}
}
}
fx = x;
fy = y;
d += dy;
if(d > dx)
{
d -= dx;
y += yi;
}
x += xi;
}
} else {
for(i = 0; i <= dy; i++)
{
if(i > 0)
{
Data = GetMapPixel((unsigned short)x, (unsigned short)y, 1);
if((Data & Pattern) == 0)
{
*x1 = fx;
*y1 = fy;
*x2 = x;
*y2 = y;
return(1);
}
if(RunHitTests == 1)
{
for(o = 0; o < MAX_HITTESTS; o++)
{
if(HitTests[o] == 0xFFFF)
break;
SpriteLink = Objects[HitTests[o]]->SpriteLink;
if(SpriteLink != 0xFFFF)
{
Template = Sprites[SpriteLink]->Template;
if((x >= Sprites[SpriteLink]->x - Caches[Template]->cx[Sprites[SpriteLink]->CurFrame]) && (y >= Sprites[SpriteLink]->y - Caches[Template]->cy[Sprites[SpriteLink]->CurFrame]) && (x < Sprites[SpriteLink]->x - Caches[Template]->cx[Sprites[SpriteLink]->CurFrame] + Caches[Template]->w) && (y < Sprites[SpriteLink]->y - Caches[Template]->cy[Sprites[SpriteLink]->CurFrame] + Caches[Template]->h))
{
Offset = x - Sprites[SpriteLink]->x + Caches[Template]->cx[Sprites[SpriteLink]->CurFrame];
Offset += (y - Sprites[SpriteLink]->y + Caches[Template]->cy[Sprites[SpriteLink]->CurFrame]) * Caches[Template]->w;
FrameBuffer = Caches[Template]->Frames[Sprites[SpriteLink]->CurFrame];
if(FrameBuffer[Offset] != 0)
{
*x1 = fx;
*y1 = fy;
*x2 = x;
*y2 = y;
*ObjNum = HitTests[o];
return(2);
}
}
}
}
}
}
fx = x;
fy = y;
d += dx;
if(d > 0)
{
d -= dy;
x += xi;
}
y += yi;
}
}
return(0);
}
void AddHitTest(unsigned short ObjNum)
{
unsigned short i;
for(i = 0; i < MAX_HITTESTS; i++)
{
if(HitTests[i] == 0xFFFF)
{
HitTests[i] = ObjNum;
return;
}
}
}
void RemoveHitTest(unsigned short ObjNum)
{
unsigned short i;
for(i = 0; i < MAX_HITTESTS; i++)
{
if(HitTests[i] == ObjNum)
{
for(i = i; i < MAX_HITTESTS; i++)
HitTests[i] = HitTests[i + 1];
HitTests[MAX_HITTESTS - 1] = 0xFFFF;
break;
}
}
}
void DBPrint(unsigned char *Buffer, signed short sx, signed short y, unsigned char bgc)
{
unsigned long Offset;
unsigned char CurChar;
signed short x;
Offset = 0;
x = sx;
while((CurChar = Buffer[Offset++]) != 0)
{
switch(CurChar)
{
case 10:
y += 5;
break;
case 13:
x = sx;
break;
default:
if(AsciiTable[CurChar] != 65535)
{
DBCopyBufferClip(x, y, Caches[FontSprite]->Frames[AsciiTable[CurChar]], Caches[FontSprite]->w, Caches[FontSprite]->h, bgc);
} else {
if(bgc != 0)
DBFRect(x, y, x + 2, y + 3, 0);
}
x += Caches[FontSprite]->w + 1;
break;
}
}
}
unsigned short WallAngle(unsigned short x, unsigned short y)
{
return(0);
}
void SpawnPixel(unsigned short x, unsigned short y, float xv, float yv, unsigned char Owner, unsigned char SetColor, unsigned char Explode, signed short Damage, unsigned char c)
{
unsigned short i;
for(i = 0; i < MAX_PIXELS; i++)
{
if(Pixels[i]->Used == 0)
{
Pixels[i]->x = x;
Pixels[i]->y = y;
Pixels[i]->xv = xv;
Pixels[i]->yv = yv;
Pixels[i]->c = c;
Pixels[i]->SetColor = SetColor;
Pixels[i]->Explode = Explode;
Pixels[i]->Damage = Damage;
Pixels[i]->Owner = Owner;
Pixels[i]->Used = 1;
return;
}
}
}
void DrawLine(signed short x1, signed short y1, signed short x2, signed short y2, unsigned char c1, unsigned char c2)
{
unsigned short i;
for(i = 0; i < MAX_LINES; i++)
{
if(Lines[i]->Used == 0)
{
Lines[i]->x1 = x1;
Lines[i]->y1 = y1;
Lines[i]->x2 = x2;
Lines[i]->y2 = y2;
Lines[i]->c1 = c1;
Lines[i]->c2 = c2;
Lines[i]->Used = 1;
return;
}
}
}
unsigned short SpawnObject(unsigned short Class, unsigned char Owner, unsigned short x, unsigned short y, float xv, float yv)
{
unsigned short i, o;
for(i = 0; i < MAX_OBJECTS; i++)
{
if(Objects[i]->Used == 0)
{
Objects[i]->x = (float)x;
Objects[i]->y = (float)y;
Objects[i]->xv = xv;
Objects[i]->yv = yv;
Objects[i]->Class = Class;
Objects[i]->Owner = Owner;
Objects[i]->TickTimer = 0;
Objects[i]->SpriteLink = (Classes[Class]->Sprite != 0xFF)?(SpawnSprite(Classes[Class]->Sprite, (signed short)x, (signed short)y, 0, 0, 0, Classes[Class]->StartFrame)):0xFFFF;
Objects[i]->Used = 1;
Regs[16] = i;
Regs[17] = (signed short)Objects[i]->x;
Regs[18] = (signed short)Objects[i]->y;
Execute(Classes[Objects[i]->Class]->Code, (signed short *)&Objects[i]->Variables[0], Classes[Class]->Scripts[2]); //Init
return(i);
}
}
return(0xFFFF);
}
void ControlObjects(void)
{
unsigned short i, o;
unsigned short Class;
signed short fx, fy, nx, ny, dx, dy, x, y;
unsigned char PixelInfo, Collided;
unsigned short ObjNum, SpriteLink, Template, Offset;
unsigned char *FrameBuffer;
for(i = 0; i < MAX_OBJECTS; i++)
{
if(Objects[i]->Used == 1)
{
Class = Objects[i]->Class;
fx = (signed short)Objects[i]->x;
fy = (signed short)Objects[i]->y;
Objects[i]->x += Objects[i]->xv;
Objects[i]->y += Objects[i]->yv;
nx = (signed short)Objects[i]->x;
ny = (signed short)Objects[i]->y;
dx = nx - fx;
dy = ny - fy;
if(dx < 0)
dx = -dx;
if(dy < 0)
dy = -dy;
if((dx > 1) || (dy > 1))
{
Collided = CollisionTest((signed short *)&fx, (signed short *)&fy, (signed short *)&nx, (signed short *)&ny, MAP_SHOOTABLE, Classes[Class]->RunHitTests, (unsigned short *)&ObjNum);
} else {
Collided = (GetMapPixel((unsigned short)nx, (unsigned short)ny, 1) & MAP_SHOOTABLE) == 0;
if(Classes[Class]->RunHitTests == 1)
{
x = nx;
y = nx;
for(o = 0; o < MAX_HITTESTS; o++)
{
if(HitTests[o] == 0xFFFF)
break;
SpriteLink = Objects[HitTests[o]]->SpriteLink;
if(SpriteLink != 0xFFFF)
{
Template = Sprites[SpriteLink]->Template;
if((x >= Sprites[SpriteLink]->x - Caches[Template]->cx[Sprites[SpriteLink]->CurFrame]) && (y >= Sprites[SpriteLink]->y - Caches[Template]->cy[Sprites[SpriteLink]->CurFrame]) && (x < Sprites[SpriteLink]->x - Caches[Template]->cx[Sprites[SpriteLink]->CurFrame] + Caches[Template]->w) && (y < Sprites[SpriteLink]->y - Caches[Template]->cy[Sprites[SpriteLink]->CurFrame] + Caches[Template]->h))
{
Offset = x - Sprites[SpriteLink]->x + Caches[Template]->cx[Sprites[SpriteLink]->CurFrame];
Offset += (y - Sprites[SpriteLink]->y + Caches[Template]->cy[Sprites[SpriteLink]->CurFrame]) * Caches[Template]->w;
FrameBuffer = Caches[Template]->Frames[Sprites[SpriteLink]->CurFrame];
if(FrameBuffer[Offset] != 0)
{
ObjNum = HitTests[o];
Collided = 2;
}
}
}
}
}
}
Objects[i]->yv += Gravity * ((float)Classes[Class]->GravityMod / 10000);
if(Collided != 0)
{
PixelInfo = GetMapPixel((unsigned short)nx, (unsigned short)ny, 1);
Regs[16] = i;
Regs[17] = fx;
Regs[18] = fy;
Regs[19] = ((PixelInfo & MAP_SHOOTABLE) == 0)?0:1;
Regs[20] = ((PixelInfo & MAP_WALKABLE) == 0)?0:1;
Regs[21] = ((PixelInfo & MAP_DESTROYABLE) == 0)?0:1;
Regs[22] = nx;
Regs[23] = ny;
Regs[24] = Collided;
Execute(Classes[Objects[i]->Class]->Code, (signed short *)&Objects[i]->Variables[0], Classes[Class]->Scripts[1]); //Touch
}
if(Classes[Class]->TickDelay != 0)
{
if(++Objects[i]->TickTimer >= Classes[Class]->TickDelay)
{
PixelInfo = GetMapPixel((unsigned short)Objects[i]->x, (unsigned short)Objects[i]->y, 1);
Objects[i]->TickTimer = 0;
Regs[16] = i;
Regs[17] = (signed short)Objects[i]->x;
Regs[18] = (signed short)Objects[i]->y;
Regs[19] = ((PixelInfo & MAP_SHOOTABLE) == 0)?0:1;
Regs[20] = ((PixelInfo & MAP_WALKABLE) == 0)?0:1;
Regs[21] = ((PixelInfo & MAP_DESTROYABLE) == 0)?0:1;
Execute(Classes[Objects[i]->Class]->Code, (signed short *)&Objects[i]->Variables[0], Classes[Class]->Scripts[0]); //Tick
}
}
if(Objects[i]->SpriteLink != 0xFFFF)
{
Sprites[Objects[i]->SpriteLink]->x = (signed short)Objects[i]->x;
Sprites[Objects[i]->SpriteLink]->y = (signed short)Objects[i]->y;
}
}
}
}
void ControlSprites(void)
{
unsigned short i;
unsigned char Template;
for(i = 0; i < MAX_SPRITES; i++)
{
if(Sprites[i]->Used == 1)
{
Template = Sprites[i]->Template;
Sprites[i]->x += Sprites[i]->xv;
Sprites[i]->y += Sprites[i]->yv;
if(Caches[Template]->AnimDelay != 0xFF)
{
if(++Sprites[i]->AnimTimer >= Caches[Template]->AnimDelay)
{
Sprites[i]->AnimTimer = 0;
if(++Sprites[i]->CurFrame >= Caches[Template]->NumFrames)
{
Sprites[i]->CurFrame = 0;
if(Sprites[i]->AnimCount > 0)
{
if(--Sprites[i]->AnimCount == 0)
{
Sprites[i]->Used = 0;
}
}
}
}
}
}
}
}
void ControlPixels(void)
{
unsigned short i, o;
signed short fx, fy, nx, ny, dx, dy, x, y;
unsigned char Collided;
unsigned short ObjNum, SpriteLink, Template, Offset;
unsigned char *FrameBuffer;
for(i = 0; i < MAX_PIXELS; i++)
{
if(Pixels[i]->Used == 1)
{
fx = (signed short)Pixels[i]->x;
fy = (signed short)Pixels[i]->y;
Pixels[i]->x += Pixels[i]->xv;
Pixels[i]->y += Pixels[i]->yv;
nx = (signed short)Pixels[i]->x;
ny = (signed short)Pixels[i]->y;
dx = nx - fx;
dy = ny - fy;
if(dx < 0)
dx = -dx;
if(dy < 0)
dy = -dy;
if((dx > 1) || (dy > 1))
{
Collided = CollisionTest((signed short *)&fx, (signed short *)&fy, (signed short *)&nx, (signed short *)&ny, MAP_SHOOTABLE, Pixels[i]->Explode, (unsigned short *)&ObjNum);
} else {
Collided = (GetMapPixel((unsigned short)Pixels[i]->x, (unsigned short)Pixels[i]->y, 1) & MAP_SHOOTABLE) == 0;
if(Pixels[i]->Explode == 1)
{
x = (signed short)Pixels[i]->x;
y = (signed short)Pixels[i]->y;
for(o = 0; o < MAX_HITTESTS; o++)
{
if(HitTests[o] == 0xFFFF)
break;
SpriteLink = Objects[HitTests[o]]->SpriteLink;
if(SpriteLink != 0xFFFF)
{
Template = Sprites[SpriteLink]->Template;
if((x >= Sprites[SpriteLink]->x - Caches[Template]->cx[Sprites[SpriteLink]->CurFrame]) && (y >= Sprites[SpriteLink]->y - Caches[Template]->cy[Sprites[SpriteLink]->CurFrame]) && (x < Sprites[SpriteLink]->x - Caches[Template]->cx[Sprites[SpriteLink]->CurFrame] + Caches[Template]->w) && (y < Sprites[SpriteLink]->y - Caches[Template]->cy[Sprites[SpriteLink]->CurFrame] + Caches[Template]->h))
{
Offset = x - Sprites[SpriteLink]->x + Caches[Template]->cx[Sprites[SpriteLink]->CurFrame];
Offset += (y - Sprites[SpriteLink]->y + Caches[Template]->cy[Sprites[SpriteLink]->CurFrame]) * Caches[Template]->w;
FrameBuffer = Caches[Template]->Frames[Sprites[SpriteLink]->CurFrame];
if(FrameBuffer[Offset] != 0)
{
ObjNum = HitTests[o];
Collided = 2;
}
}
}
}
}
}
Pixels[i]->yv += Gravity;
if(Collided != 0)
{
if(Pixels[i]->SetColor == 1)
{
SetMapPixel((unsigned short)nx, (unsigned short)ny, Pixels[i]->c, 0);
}
if(Pixels[i]->SetColor == 2)
{
SetMapPixel((unsigned short)fx, (unsigned short)fy, Pixels[i]->c, 0);
SetMapPixel((unsigned short)fx, (unsigned short)fy, MAP_DESTROYABLE, 1);
}
if(Pixels[i]->Explode == 1)
{
if(Collided == 1)
SpawnExplosion((signed short)nx, (signed short)ny, 6, 0);
if(Collided == 2)
{
Regs[16] = (signed short)ObjNum;
Regs[17] = Pixels[i]->Damage;
Execute(Classes[Objects[ObjNum]->Class]->Code, (signed short *)&Objects[ObjNum]->Variables[0], Classes[Objects[ObjNum]->Class]->Scripts[3]); //TakeDamage
}
}
Pixels[i]->Used = 0;
}
}
}
}
void CollVel(signed short x, signed short y, float *xv, float *yv, unsigned char Attributes)
{
float Temp;
signed char xa, ya;
unsigned char a1, a2;
if(*xv == 0)
{
*yv = -*yv;
return;
}
if(*yv == 0)
{
*xv = -*xv;
return;
}
if(*xv < 0)
xa = -1;
else
xa = 1;
if(*yv < 0)
ya = -1;
else
ya = 1;
a1 = GetMapPixel(x, y + ya, 1) & Attributes;
a2 = GetMapPixel(x + xa, y, 1) & Attributes;
if(((a1 == 0) && (a2 == 0)) || ((a1 != 0) && (a2 != 0)))
{
Temp = *yv;
*yv = *xv * xa * ya;
*xv = Temp * ya * xa;
}
if(a1 == 0)
*yv = -*yv;
if(a2 == 0)
*xv = -*xv;
}
void ControlPlayers(void)
{
unsigned short i, o;
unsigned short ObjNum;
signed short PlayerAngle, CurWeapon;
for(i = 0; i < MAX_PLAYERS; i++)
{
if(Players[i]->Used == 1)
{
for(o = 0; o < NUM_WEAPONS; o++)
{
if(PWeapons[i][o]->FireTimer > 0)
{
if(++PWeapons[i][o]->FireTimer > Weapons[PWeapons[i][o]->Weapon]->FireDelay)
PWeapons[i][o]->FireTimer = 0;
}
if((PWeapons[i][o]->ReloadTimer > 0) && (Players[i]->CurWeapon == o))
{
if(++PWeapons[i][o]->ReloadTimer > Weapons[PWeapons[i][o]->Weapon]->ReloadDelay)
{
PWeapons[i][o]->ReloadTimer = 0;
PWeapons[i][o]->AmmoLeft = Weapons[PWeapons[i][o]->Weapon]->Ammo;
}
}
}
ObjNum = Players[i]->Object;
Players[i]->Angle += Players[i]->AngleVel;
if(Players[i]->Angle >= 360)
Players[i]->Angle -= 360;
if(Players[i]->Angle < 0)
Players[i]->Angle += 360;
if((Players[i]->Angle < 300) && (Players[i]->Angle > 180))
{
Players[i]->Angle = 300;
Players[i]->AngleVel = 0;
}
if((Players[i]->Angle > 90) && (Players[i]->Angle <= 180))
{
Players[i]->Angle = 90;
Players[i]->AngleVel = 0;
}
if(((Players[i]->Left != 0) ^ (Players[i]->Right != 0)) & (Players[i]->Change == 0))
{
if((Players[i]->Left != 0) && (Objects[ObjNum]->xv > -1))
{
if((GetMapPixel((unsigned short)(Objects[ObjNum]->x) - 1, (unsigned short)(Objects[ObjNum]->y) - 1, 1) & MAP_WALKABLE) == MAP_WALKABLE)
Objects[ObjNum]->xv -= 0.1;
Players[i]->Dir = 1;
}
if((Players[i]->Right != 0) && (Objects[ObjNum]->xv < 1))
{
if((GetMapPixel((unsigned short)(Objects[ObjNum]->x) + 1, (unsigned short)(Objects[ObjNum]->y) - 1, 1) & MAP_WALKABLE) == MAP_WALKABLE)
Objects[ObjNum]->xv += 0.1;
Players[i]->Dir = 0;
}
} else {
if((GetMapPixel((unsigned short)Objects[ObjNum]->x, (unsigned short)Objects[ObjNum]->y, 1) & MAP_WALKABLE) == 0)
Objects[ObjNum]->xv *= 0.9;
}
if((Players[i]->Change != 0) && (Players[i]->Left == 1))
{
Players[i]->CurWeapon -= 1;
if(Players[i]->CurWeapon < 0)
Players[i]->CurWeapon += NUM_WEAPONS;
while(PWeapons[i][Players[i]->CurWeapon]->Used == 0)
{
Players[i]->CurWeapon -= 1;
if(Players[i]->CurWeapon < 0)
Players[i]->CurWeapon += NUM_WEAPONS;
}
}
if((Players[i]->Change != 0) && (Players[i]->Right == 1))
{
Players[i]->CurWeapon += 1;
if(Players[i]->CurWeapon >= NUM_WEAPONS)
Players[i]->CurWeapon -= NUM_WEAPONS;
while(PWeapons[i][Players[i]->CurWeapon]->Used == 0)
{
Players[i]->CurWeapon += 1;
if(Players[i]->CurWeapon >= NUM_WEAPONS)
Players[i]->CurWeapon -= NUM_WEAPONS;
}
}
if((Players[i]->Up != 0) ^ (Players[i]->Down != 0))
{
if((Players[i]->Up != 0) && (Players[i]->AngleVel < 3))
Players[i]->AngleVel += .5;
if((Players[i]->Down != 0) && (Players[i]->AngleVel > -3))
Players[i]->AngleVel -= .5;
} else {
Players[i]->AngleVel *= .75;
}
PlayerAngle = Players[i]->Angle;
if(PlayerAngle > 90)
PlayerAngle -= 360;
if(Players[i]->Dir == 1)
PlayerAngle = 180 - PlayerAngle;
if(PlayerAngle < 0)
PlayerAngle += 360;
CurWeapon = Players[i]->CurWeapon;
if((Players[i]->Shoot != 0) && (PWeapons[i][CurWeapon]->FireTimer == 0) && (PWeapons[i][CurWeapon]->ReloadTimer == 0))
{
PWeapons[i][Players[i]->CurWeapon]->FireTimer = 1;
if(Players[i]->Dir == 0)
{
Regs[16] = (signed short)Objects[ObjNum]->x + 3 + Cosine[PlayerAngle] * 7;
} else {
Regs[16] = (signed short)Objects[ObjNum]->x - 1 + Cosine[PlayerAngle] * 7;
}
Regs[17] = (signed short)Objects[ObjNum]->y - 2 - Sine[PlayerAngle] * 7;
Regs[18] = (signed short)PlayerAngle;
Regs[19] = (signed short)(Objects[ObjNum]->xv * 100);
Regs[20] = (signed short)(Objects[ObjNum]->yv * 100);
Regs[21] = (signed short)i;
Execute(Classes[Weapons[PWeapons[i][Players[i]->CurWeapon]->Weapon]->Class]->Code, (signed short *)&PWeapons[i][Players[i]->CurWeapon]->Vars[0], Classes[Weapons[PWeapons[i][Players[i]->CurWeapon]->Weapon]->Class]->Scripts[0]); //Fire
LastShot = Regs[16];
if(--PWeapons[i][CurWeapon]->AmmoLeft <= 0)
PWeapons[i][CurWeapon]->ReloadTimer = 1;
}
}
}
}
void SpawnExplosion(signed short x, signed short y, unsigned char StartFrame, unsigned char Smokes)
{
unsigned short i, Result;
Result = SpawnSprite(0, x, y, 0, 0, 1, StartFrame);
CopyToMap(x - Caches[0]->cx[StartFrame], y - Caches[0]->cy[StartFrame], Caches[0]->Frames[StartFrame], Caches[0]->w, Caches[0]->h, 0, 1, 0, MAP_WALKABLE | MAP_SHOOTABLE | MAP_DESTROYABLE);
if(Smokes > 0)
{
for(i = 0; i < Smokes; i++)
{
SpawnSprite(1, x + ((signed short)(rand() % 10) - 5), y + ((signed short)(rand() % 10) - 5), 0, -1, 1, 0);
}
}
}
unsigned char ArgExist(int argc, char *argv[], char *Match)
{
int i;
for(i = 0; i < argc; i++)
{
if(strcmp(strupr((char *)argv[i]), strupr((char *)Match)) == 0)
return(1);
}
return(0);
}
int main(int argc, char *argv[])
{
unsigned short Result, x, y, i;
unsigned short Attributes, Size;
unsigned long Cycles;
unsigned char Finished;
unsigned short CoreObject;
unsigned char c0, c1, c2, c3, c4;
unsigned char MFR;
unsigned long Start;
DebugMode = 0;
MFR = 0;
if(argc > 1)
{
if(ArgExist(argc, argv, "/Debug") == 1)
DebugMode = 1;
if(ArgExist(argc, argv, "/FR") == 1)
MFR = 1;
}
switch(Init(&Result))
{
case 0:
if(Result == 0x40) printf("EMS not installed!\nQuitting...\n"); else printf("EMS failure!\nError code: %u\nQuitting...\n", (unsigned short)Result);
getch();
Terminate();
return;
case 1:
printf("Internal EMS failure!\nQuitting...\n");
getch();
Terminate();
return;
case 2:
printf("Not enough memory!\n");
getch();
Terminate();
return;
case 3:
printf("Couldn't find the file KVID.DAT!\n");
getch();
Terminate();
return;
case 4:
printf("Datafile corrupted!\n");
getch();
Terminate();
return;
case 5:
printf("Not enough EMS memory available\nAt least %lu KB needed!\n", MaxLW * MaxLH * 64 * NUM_PLANES);
getch();
Terminate();
return;
}
for(y = 0; y < LevelHeight; y++)
{
for(x = 0; x < LevelWidth; x++)
{
SetMapPixel(x, y, (x + y) & 0xFF, 0);
}
ShowMap(0, 0, 319, 199, 0, 0);
DisplayDB();
}
Terminate();
return(0);
Players[0]->Used = 1;
Players[1]->Used = 1;
for(y=0;y<LevelHeight;y++)
{
for(x=0;x<LevelWidth;x++)
{
SetMapPixel(x, y, (unsigned char)((rand() % 4) + 44), 0);
}
}
for(y = 0; y < LevelHeight; y++)
{
for(x = 0; x < LevelWidth; x++)
{
c0 = GetMapPixel(x, y, 0);
c1 = GetMapPixel(x - 1, y, 0);
c2 = GetMapPixel(x + 1, y, 0);
c3 = GetMapPixel(x, y - 1, 0);
c4 = GetMapPixel(x, y + 1, 0);
c1 = (c1 == 0)?c0:c1;
c2 = (c2 == 0)?c0:c2;
c3 = (c3 == 0)?c0:c3;
c4 = (c4 == 0)?c0:c4;
SetMapPixel(x, y, (unsigned char)((c1 + c2 + c3 + c4) >> 2), 0);
}
}
for(y=0;y<LevelHeight;y++)
{
for(x=0;x<LevelWidth;x++)
{
SetMapPixel(x, y, MAP_DESTROYABLE, 1);
}
}
for(x = 320; x < LevelWidth; x += 320)
{
for(y = 0; y < LevelHeight; y++)
{
SetMapPixel(x, y, 40, 0);
SetMapPixel(x, y, MAP_WALKABLE | MAP_SHOOTABLE, 1);
}
}
for(y = 200; y < LevelHeight; y += 200)
{
for(x = 0; x < LevelWidth; x++)
{
SetMapPixel(x, y, 40, 0);
SetMapPixel(x, y, MAP_WALKABLE | MAP_SHOOTABLE, 1);
}
}
for(i = 0; i < 200; i++)
{
x = rand() % LevelWidth;
y = rand() % LevelHeight;
CopyToMap(x - 15, y - 11, Caches[11]->Frames[rand() % 8], Caches[11]->w, Caches[11]->h, 0, 0, 0, 0);
}
for(i = 0; i < 300; i++)
{
x = rand() % LevelWidth;
y = rand() % LevelHeight;
CopyToMap(x - Caches[0]->cx[0], y - Caches[0]->cy[0], Caches[0]->Frames[0], Caches[0]->w, Caches[0]->h, 0, 1, 0, MAP_SHOOTABLE | MAP_WALKABLE | MAP_DESTROYABLE);
}
CoreObject = SpawnObject(0, 0, 0, 0, 0, 0);
Cycles = 0;
Finished = 0;
InitVar();
if(MFR == 1)
{
Start = (unsigned long)time(NULL);
while((unsigned long)time(NULL) == Start);
Start = (unsigned long)time(NULL);
}
while(Finished == 0)
{
if((ReadyToGo == 1) || (MFR == 1))
{
if(KeyTable[67])
DebugMode = 1;
if(KeyTable[68])
DebugMode = 0;
for(i = 0; i < MAX_PLAYERS; i++)
{
Players[i]->Left = 0;
Players[i]->Right = 0;
Players[i]->Up = 0;
Players[i]->Down = 0;
Players[i]->Shoot = 0;
Players[i]->Change = 0;
}
GetInputs();
ControlPixels();
ControlSprites();
ControlObjects();
ControlPlayers();
Cycles++;
if(KeyTable[1] == 1) Finished = 1;
if(MFR == 1)
if((unsigned long)time(NULL) - Start > 10)
Finished = 1;
c0 = KeyTable[63] * 4;
if(KeyTable[64] == 1) c0 += 8;
if(KeyTable[59] == 1) BGFrame = c0;
if(KeyTable[60] == 1) BGFrame = c0 + 1;
if(KeyTable[61] == 1) BGFrame = c0 + 2;
if(KeyTable[62] == 1) BGFrame = c0 + 3;
DrawScreen();
for(i = 0; i < MAX_LINES; i++)
{
Lines[i]->Used = 0;
}
DBPSet(0, 199, Cycles & 0xFF);
DisplayDB();
ReadyToGo = 0;
}
}
Terminate();
printf("%lu", Cycles);
return(0);
}
More information about the Gcc-prs
mailing list