⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cave.c

📁 game duke3d source
💻 C
📖 第 1 页 / 共 4 页
字号:
#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 + -