📄 cave.c
字号:
#pragma aux limitrate =\
"mov dx, 0x3da",\
"wait1: in al, dx",\
"test al, 8",\
"jnz wait1",\
"wait2: in al, dx",\
"test al, 8",\
"jz wait2",\
modify exact [eax edx]\
#pragma aux setupmouse =\
"mov eax, 0",\
"int 33h",\
"mov moustat,eax",\
#pragma aux readmouse =\
"mov eax, 11d",\
"int 33h",\
"sar ecx, 1",\
"sar edx, 1",\
"mov mousx, ecx",\
"mov mousy, edx",\
modify [eax ecx edx]\
#pragma aux interruptend =\
"mov al, 20h",\
"out 20h, al",\
modify [eax]\
#pragma aux readkey =\
"in al, 0x60",\
"mov readch, al",\
"in al, 0x61",\
"or al, 0x80",\
"out 0x61, al",\
"and al, 0x7f",\
"out 0x61, al",\
modify [eax]\
// Interrupt Handlers
void __interrupt __far timerhandler()
{
clockspeed++;
interruptend();
}
void __interrupt __far keyhandler()
{
oldreadch = readch;
readkey();
if ((readch|1) == 0xe1)
extended = 128;
else
{
if (oldreadch != readch)
keystatus[(readch&127)+extended] = ((readch>>7)^1);
extended = 0;
}
interruptend();
}
// Fixed math
tsqrt(long num)
{
long root, temp;
root = 128;
do
{
temp = root;
root = ((root+(num/root))>>1);
}
while (labs(temp-root) > 1);
return(root);
}
long trand(void)
{
randomseed = (randomseed*43+1)&(65535|(65535<<16));
return(randomseed);
}
getangle(long xvect, long yvect)
{
if ((xvect|yvect) == 0) return(0);
if (xvect == yvect) return(256+((xvect<0)<<10));
if (xvect == -yvect) return(768+((xvect>0)<<10));
if (labs(xvect) > labs(yvect))
return(radarang[scale(yvect,320>>1,xvect)+(320>>1)]+((xvect<0)<<10));
return(radarang[(320>>1)-scale(xvect,320>>1,yvect)]+512+((yvect<0)<<10));
}
short angdif(short a,short na)
{
a &= 2047;
na &= 2047;
if(labs(a-na) < 1024)
return (na-a);
else
{
if(na > 1024) na -= 2048;
if(a > 1024) a -= 2048;
na -= 2048;
a -= 2048;
return (na-a);
}
}
rotatepoint(long xpivot, long ypivot, long x, long y, short daang, long *x2, long *y2)
{
*x2 = xpivot+mulscale(x-xpivot,sintable[(daang+2560)&2047],14)-mulscale(y-ypivot,sintable[(daang+2048)&2047],14);
*y2 = ypivot+mulscale(y-ypivot,sintable[(daang+2560)&2047],14)+mulscale(x-xpivot,sintable[(daang+2048)&2047],14);
}
// I/O
char loadpcx(char *fname,char *p)
{
FILE *fp;
int c, i, j, n;
/* attempt to open the file */
if((fp=fopen(fname,"rb")) == NULL)
return(1);
/* read in the pcxheader */
if( fread((char *)&pcxheader,1,sizeof(pcxtype),fp) != sizeof(pcxtype) )
return(1);
if(pcxheader.bits_per_pixel == 1)
pcxbits=pcxheader.colour_planes;
else
pcxbits=pcxheader.bits_per_pixel;
/* check to make sure it's a picture */
if(pcxbits !=8 || pcxheader.manufacturer != 0x0a || pcxheader.version != 5 )
{
fclose(fp);
return(1);
}
/* Find the palette */
if( fseek(fp,-769L,SEEK_END) == 0 )
if( fgetc(fp) !=0x0c || fread( palette,1,768,fp) != 768 )
{
fclose(fp);
return(1);
}
for(i=0;i<768;++i)
palette[i]=palette[i] >> 2;
fseek(fp,128L,SEEK_SET);
/* allocate a big buffer */
pcxwidth = (pcxheader.xmax-pcxheader.xmin)+1;
pcxdepth = (pcxheader.ymax-pcxheader.ymin)+1;
pcxbytes=pcxheader.bytes_per_line;
/* unpack the file */
for(j=0;j<pcxdepth;++j)
{
n = pcxbytes;
do
{
c=fgetc(fp) & 0xff; /* get a key byte */
if((c & 0xc0) == 0xc0) /* if it's a run of bytes field */
{
i = c&0x3f; /* and off the high pcxbits */
c=fgetc(fp); /* get the run byte */
while(i--)
*(p++)=c; /* run the byte */
}
else *(p++)=c; /* else just store it */
}
while(n--);
}
fclose(fp);
return(0);
}
iodata(char *fn,char *ptr,long len,char iotype)
{
if(iotype&IO_SAVE)
{
if (iofil != -1 || (iofil = open(fn,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) ) != -1 )
{
write(iofil,ptr,len);
if( (iotype&IO_NOCLOSE) != IO_NOCLOSE)
{
close(iofil);
iofil = -1;
}
return 1;
}
return 0;
}
if (iofil != -1 || (iofil = open(fn,O_BINARY|O_RDWR,S_IREAD)) != -1)
{
read(iofil,ptr,len);
if( (iotype&IO_NOCLOSE) != IO_NOCLOSE)
{
close(iofil);
iofil = -1;
}
return 1;
}
return 0;
}
long spawn(long picnum, long owner)
{
long i;
i = insertobject(0);
object[i].owner = owner;
object[i].picnum = picnum;
object[i].x = self[screenpeek].posx;
object[i].y = self[screenpeek].posy;
object[i].z = self[screenpeek].posz;
// map.h2[((self[screenpeek].posx>>10)<<8) + (self[screenpeek].posy>>10)]<<12;
// self[screenpeek].posz;
object[i].templong = 0;
switch(picnum)
{
case 1:
object[i].ang = self[screenpeek].ang;
object[i].xvel =
sintable[(2560+self[screenpeek].ang)&2047]>>1;
object[i].yvel =
sintable[(2048+self[screenpeek].ang)&2047]>>1;
object[i].zvel = (self[screenpeek].horiz - 200)<<8;
break;
}
return(i);
}
initaboard()
{
long i, j;
randomseed = 17L;
screenpeek = 0;
for(i=0;i<MAXPLAYERS;i++)
{
self[i].posx = 0;
self[i].posy = 0;
self[i].posz = ((128-32)<<12);
self[i].ang = 0;
self[i].horiz = (MAXYDIM>>1);
}
for(i=0;i<256;i++)
for(j=0;j<256;j++)
{
if(j < 2 || j > 253 || i < 2 || i > 253)
{
map.h1[(i<<8)+j] = 0;
map.h2[(i<<8)+j] = 0;
}
else
{
map.h1[(i<<8)+j] = (i>128)<<7;
map.h2[(i<<8)+j] = 128;
}
map.c1[(i<<8)+j] = 0;
map.c2[(i<<8)+j] = 0;
}
// loadpcx("cave.pcx",&map.c1[0]);
self[screenpeek].posx = 128<<10;
self[screenpeek].posy = 128<<10;
self[screenpeek].posz = 128<<12;
initobjectlists();
}
// Memory Management
char freemem(char **addr)
{
long i;
for(i=0;i<maxchunks;i++)
if(*chunk[i].ptr == *addr)
{
chunk[i].amount = 0;
*chunk[i].ptr = (char *) NULL;
if(i == chunkloc)
chunkloc = (chunkloc - 1)%maxchunks;
return 1;
}
return 0;
}
char *getmem(char **addr,long memlen)
{
long i, templong;
// Check to see if the ptr already exists
for(i=0;i<maxchunks;i++)
if( i != chunkloc &&
chunk[i].ptr == addr &&
chunk[i].amount <= memlen )
{
chunk[i].amount = memlen;
return(*addr);
}
// Set the last pointer to NULL
*chunk[chunkloc].ptr = (char *) NULL;
// Set the next chunk to addr
chunk[chunkloc].ptr = addr;
// At end of memory!?
if( (memptr + memlen ) > totalmemory )
memptr = 0;
*addr = mainmem + memptr;
chunk[chunkloc].amount = memlen;
// NULLify all other chunks occupying same location
for(i=0;i<maxchunks;i++)
if( i != chunkloc &&
chunk[i].amount > 0 &&
*chunk[i].ptr >= (mainmem + memptr) &&
*chunk[i].ptr < (mainmem + memptr + memlen) )
{
*chunk[i].ptr = (char *) NULL;
chunk[i].amount = 0;
}
memptr += memlen;
chunkloc = (chunkloc + 1)%maxchunks;
return(mainmem + memptr - memlen);
}
// Inits/Uninits
setscreenmode()
{
long i, j;
// iodata("palette.dat",&palette[0],768L,IO_LOAD|IO_NOCLOSE);
// iodata("palette.dat",&palookup[0][0],MAXPALOOKUPS<<8,IO_LOAD);
setvmode(0x13);
toutp(0x3c4,0x4); toutp(0x3c5,0x6);
toutp(0x3d4,0x14); toutp(0x3d5,0x0);
toutp(0x3d4,0x17); toutp(0x3d5,0xe3);
if (ydim == 400)
{
toutp(0x3d4,0x9);
toutp(0x3d5,inp(0x3d5)&254);
}
for(i=0;i<768;i+=3)
{
palette[i] = i/5;
palette[i+1] = i/5;
palette[i+2] = i/3;
}
for(i=0;i<MAXPALOOKUPS;i++)
for(j=0;j<256;j++)
palookup[i][j] = MAXPALOOKUPS - i - 1;
toutp(0x3c8,0);
for(i=0;i<768;i++)
toutp(0x3c9,palette[i]);
}
void clearmemvars(void)
{
long i;
for(i=0;i<maxchunks;i++)
{
chunk[i].ptr = (char **) NULL;
chunk[i].amount = 0;
}
memptr = 0;
chunkloc = 0;
}
void initmem(void)
{
totalmemory = MAXMEMNEEDED;
do
{
mainmem = (char *) malloc(totalmemory + 1);
if(mainmem == (char *) NULL)
totalmemory -= (1<<16);
} while(mainmem == (char *) NULL && totalmemory >= MINMEMNEEDED);
if( totalmemory < MINMEMNEEDED )
{
puts("Not enough memory.");
exit(-1);
}
chunk = (chunktype *)mainmem;
totalmemory -= totalmemory>>10;
mainmem += totalmemory>>10;
maxchunks
= ( (totalmemory >> 10) / sizeof(chunktype) ) - 1;
printf("Alloc:%ld(%ld chunks) @ 0x%X.\n",totalmemory,maxchunks,mainmem);
clearmemvars();
}
void initgame(void)
{
int i, fil;
pixs = 4;
vidmode = 1;
xdim = MAXXDIM;
ydim = MAXYDIM;
frameplace = 0xa0000;
detmode = 1;
iofil = -1;
for(i=0;i<MAXYDIM;i++)
muly80[i] = i*80;
initmem();
iodata("tables.dat",(char *)&sintable[0],4096L,IO_LOAD|IO_NOCLOSE);
iodata("tables.dat",(char *)&tantable[0],4096L,IO_LOAD|IO_NOCLOSE);
iodata("tables.dat",(char *)&radarang[0],640L,IO_LOAD);
setupmouse();
if(moustat == 1)
puts("Mouse installed.");
else
puts("Mouse not found.");
oldkeyhandler = _dos_getvect(0x9);
_disable(); _dos_setvect(0x9, keyhandler); _enable();
clockspeed = 0L;
totalclock = 0L;
numframes = 0L;
toutp(0x43,54); toutp(0x40,4972&255); toutp(0x40,4972>>8);
oldtimerhandler = _dos_getvect(0x8);
_disable(); _dos_setvect(0x8, timerhandler); _enable();
getmem(&map.h1,65536L*6);
map.h2 = map.h1 + 65536L;
map.c1 = map.h2 + 65536L;
map.c2 = map.c1 + 65536L;
map.s1 = map.c2 + 65536L;
map.s2 = map.s1 + 65536L;
getmem(&scrbuf,128000L);
setscreenmode();
}
void uninitgame(void)
{
int i;
toutp(0x43,54); toutp(0x40,255); toutp(0x40,255);
_dos_setvect(0x8, oldtimerhandler);
_dos_setvect(0x9, oldkeyhandler);
setvmode(0x3);
free(mainmem);
}
void gameexit(char *message)
{
uninitgame();
puts(message);
exit(0);
}
// Sounds
void playsound(long i,long sndnum)
{
long j;
char pri;
pri = sounds[sndnum].pri;
j = 0;
while(soundplaying[j].ptr != NULL && j < MAXCHANNELS)
j++;
if(j == MAXCHANNELS)
for(j=0;j<MAXCHANNELS;j++)
if(sounds[soundplaying[j].sndno].pri <= pri)
break;
if(j == MAXCHANNELS)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -