📄 cave.c
字号:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
This file is NOT part of Duke Nukem 3D version 1.5 - Atomic EditionHowever, it is either an older version of a file that is, or issome test code written during the development of Duke Nukem 3D.This file is provided purely for educational interest.Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
//
// Includes
#include <stdio.h>
#include <dos.h>
#include <fcntl.h>
#include <malloc.h>
#include <sys\stat.h>
// Defines
#define MAXXDIM 320
#define MAXYDIM 400
#define MAXMEMNEEDED (1<<24)
#define MINMEMNEEDED (1<<22)
#define MAXTILES 1024
#define MAXPALOOKUPS 64
#define NUMOPTIONS 8
#define NUMKEYS 9
#define MAXPLAYERS 16
#define MAXOBJECTS 1024
#define MAXVIEWOBJECTS MAXOBJECTS
#define MAXSTATUS 32
#define MAXCHANNELS 8
#define MAXSOUNDS 128
#define sc_Escape 0x01 // Menu
#define sc_P 0x19 // Pause
#define sc_F1 0x3b // Help
#define sc_F2 0x3c // Load
#define sc_F3 0x3d // Save
#define sc_F4 0x3e // initaboard()
#define sc_Tab 0x0f // Topdown view
#define sc_CapsLock 0x3a // Runlock
#define sc_UpArrow 0xc8 // Move Fowards
#define sc_DownArrow 0xd0 // Move Backwards
#define sc_LeftArrow 0xcb // Move Left
#define sc_RightArrow 0xcd // Move Right
#define sc_A 0x1e // Up/Jump
#define sc_Z 0x2c // Down/Duck
#define sc_F 0x21 // Flash ight
#define sc_kpad_1 0x4f // Look Up
#define sc_kpad_0 0x52 // Look Down
#define sc_LeftAlt 0x38 // Strafe
#define sc_Comma 0x33 // Strafe Left
#define sc_Period 0x34 // Strafe Right
#define sc_LeftControl 0x1d // Use Weapon
#define sc_LeftShift 0x2a // Run
#define sc_Space 0x39 // Use
#define IO_LOAD 0
#define IO_SAVE 1
#define IO_NOCLOSE 2
#define CLIP_HITCEILING 1
#define CLIP_HITFLOOR 2
#define CLIP_HALT 4
#define TOPHEIGHT(X,Y,H) map.h1[((Y)<<8)+(X)]=(H)
#define TOPCOLOR(X,Y,C) map.c1[((Y)<<8)+(X)]=(C)
#define TOPSHADE(X,Y,S) map.s1[((Y)<<8)+(X)]=(S)
#define BOTHEIGHT(X,Y,H) map.h2[((Y)<<8)+(X)]=(H)
#define BOTCOLOR(X,Y,C) map.c2[((Y)<<8)+(X)]=(C)
#define BOTSHADE(X,Y,S) map.s2[((Y)<<8)+(X)]=(S)
// Typedefs
typedef struct
{
char **ptr;
long amount;
} chunktype;
typedef struct
{
unsigned char *h1, *h2, *c1, *c2, *s1, *s2;
short headobject[MAXSTATUS+1];
short prevobject[MAXOBJECTS];
short nextobject[MAXOBJECTS];
short objectstat[MAXOBJECTS];
} maptype;
typedef struct
{
short viewobject;
short viewobjectang;
long viewobjectdist;
} viewobjecttype;
typedef struct
{
long sndno,i;
char *ptr;
} soundplayingtype;
typedef struct
{
char *fn, pri;
long len;
} soundtype;
typedef struct
{
long posx, posy, posz, horiz;
long vel, svel, zvel, angvel;
short ang, i;
// Flags
char runmode, topdown, flashlight;
} selftype;
typedef struct
{
long x, y, z, xvel, yvel, zvel, templong;
short picnum, angvel, owner, clipdist, ang;
} objecttype;
typedef struct
{
char manufacturer;
char version;
char encoding;
char bits_per_pixel;
short xmin,ymin;
short xmax,ymax;
short hres;
short vres;
char palette[48];
char reserved;
char colour_planes;
short bytes_per_line;
short palette_type;
char filler[58];
} pcxtype;
// Globals
maptype map;
selftype self[MAXPLAYERS];
objecttype object[MAXOBJECTS];
// Disposible (Non savable) globals
soundplayingtype soundplaying[MAXCHANNELS];
soundtype sounds[MAXSOUNDS];
viewobjecttype scrnobj[MAXVIEWOBJECTS];
short viewobjectcnt;
long frameplace,xdim,ydim;
unsigned char palookup[MAXPALOOKUPS][256],palette[768];
long pixs, vidmode, detmode;
long moustat, mousx, mousy;
long randomseed, screenpeek;
int iofil;
short sintable[2048], tantable[2048];
short radarang[320], muly80[MAXYDIM];
long mul16000[4] = {0,16000,32000,48000};
char *scrbuf;
pcxtype pcxheader;
unsigned int pcxwidth, pcxdepth;
unsigned int pcxbytes, pcxbits;
char atile[] =
{
0,0,
254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
254, 0,254,254, 0,254, 0, 0, 0, 0,254, 0,254,254,254, 0,
254, 0,254,254, 0,254, 0,254,254,254,254, 0,254,254,254, 0,
254, 0,254,254, 0,254, 0,254,254,254,254, 0,254,254,254, 0,
254, 0,254,254, 0,254, 0,254,254,254,254, 0,254,254,254, 0,
254, 0, 0, 0, 0,254, 0, 0, 0,254,254, 0,254,254,254, 0,
254, 0,254,254, 0,254, 0,254,254,254,254, 0,254,254,254, 0,
254, 0,254,254, 0,254, 0,254,254,254,254, 0,254,254,254, 0,
254, 0,254,254, 0,254, 0,254,254,254,254, 0,254,254,254, 0,
254, 0,254,254, 0,254, 0, 0, 0, 0,254, 0, 0, 0,254, 0,
254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254
};
char *mainmem;
long memptr, totalmemory, chunkloc, maxchunks;
chunktype *chunk;
volatile char keystatus[256], readch, oldreadch, extended;
volatile long clockspeed, totalclock, numframes;
void (__interrupt __far *oldtimerhandler)();
void __interrupt __far timerhandler(void);
void (__interrupt __far *oldkeyhandler)();
void __interrupt __far keyhandler(void);
// Pragmas
#pragma aux toutp =\
"out dx, al",\
parm [edx][eax]\
modify exact \
#pragma aux toutpw =\
"out dx, ax",\
parm [edx][eax]\
modify exact \
#pragma aux setvmode =\
"int 0x10",\
parm [eax]\
#pragma aux drawpixel =\
"mov byte ptr [edi], al",\
parm [edi][eax]\
#pragma aux drawpixels =\
"mov word ptr [edi], ax",\
parm [edi][eax]\
#pragma aux drawpixeles =\
"mov dword ptr [edi], eax",\
parm [edi][eax]\
#pragma aux labs =\
"test eax, eax",\
"jns skipnegate",\
"neg eax",\
"skipnegate:",\
parm nomemory [eax]\
#pragma aux scale =\
"imul ebx",\
"idiv ecx",\
parm [eax][ebx][ecx]\
modify [eax edx]\
#pragma aux sqr =\
"imul eax, eax",\
parm nomemory [eax]\
modify exact [eax]\
value [eax]
#pragma aux sgn =\
"add ebx, ebx",\
"sbb eax, eax",\
"cmp eax, ebx",\
"adc al, 0",\
parm nomemory [ebx]\
modify exact [eax ebx]\
#pragma aux mulscale =\
"imul ebx",\
"shrd eax, edx, cl",\
parm [eax][ebx][ecx]\
modify [edx]\
#pragma aux divscale =\
"cdq",\
"shld edx, eax, cl",\
"sal eax, cl",\
"idiv ebx",\
parm [eax][ebx][ecx]\
modify [edx]\
#pragma aux groudiv =\
"shl eax, 12",\
"sub eax, ecx",\
"shld edx, eax, 16",\
"sar ebx, 8",\
"idiv bx",\
parm [eax][ebx][ecx]\
modify [edx]\
#pragma aux drawtopslab =\
"shr ecx, 1",\
"jnc skipdraw1a",\
"mov [edi], al",\
"add edi, 80",\
"skipdraw1a: shr ecx, 1",\
"jnc skipdraw2a",\
"mov [edi], al",\
"mov [edi+80], al",\
"add edi, 160",\
"skipdraw2a: jecxz skipdraw4a",\
"startdrawa: mov [edi], al",\
"mov [edi+80], al",\
"mov [edi+160], al",\
"mov [edi+240], al",\
"add edi, 320",\
"loop startdrawa",\
"skipdraw4a: mov eax, edi",\
parm [edi][ecx][eax]\
modify [edi ecx eax]\
#pragma aux drawbotslab =\
"shr ecx, 1",\
"jnc skipdraw1b",\
"mov [edi], al",\
"sub edi, 80",\
"skipdraw1b: shr ecx, 1",\
"jnc skipdraw2b",\
"mov [edi], al",\
"mov [edi-80], al",\
"sub edi, 160",\
"skipdraw2b: jecxz skipdraw4b",\
"startdrawb: mov [edi], al",\
"mov [edi-80], al",\
"mov [edi-160], al",\
"mov [edi-240], al",\
"sub edi, 320",\
"loop startdrawb",\
"skipdraw4b: mov eax, edi",\
parm [edi][ecx][eax]\
modify [edi ecx eax]\
#pragma aux clearbuf =\
"rep stosd",\
parm [edi][ecx][eax]\
modify exact [edi ecx]\
#pragma aux clearbufbyte =\
"cmp ecx, 4",\
"jae longcopy",\
"test cl, 1",\
"jz preskip",\
"stosb",\
"preskip: shr ecx, 1",\
"rep stosw",\
"jmp endit",\
"longcopy: test edi, 1",\
"jz skip1",\
"stosb",\
"dec ecx",\
"skip1: test edi, 2",\
"jz skip2",\
"stosw",\
"sub ecx, 2",\
"skip2: mov ebx, ecx",\
"shr ecx, 2",\
"rep stosd",\
"test bl, 2",\
"jz skip3",\
"stosw",\
"skip3: test bl, 1",\
"jz endit",\
"stosb",\
"endit:",\
parm [edi][ecx][eax]\
modify [ebx]\
#pragma aux copybuf =\
"rep movsd",\
parm [esi][edi][ecx]\
modify exact [ecx esi edi]\
#pragma aux copybytes =\
"rep movsb",\
parm [esi][edi][ecx]\
modify exact [ecx esi edi]\
#pragma aux copybufbyte =\
"cmp ecx, 4",\
"jae longcopy",\
"test cl, 1",\
"jz preskip",\
"movsb",\
"preskip: shr ecx, 1",\
"rep movsw",\
"jmp endit",\
"longcopy: test edi, 1",\
"jz skip1",\
"movsb",\
"dec ecx",\
"skip1: test edi, 2",\
"jz skip2",\
"movsw",\
"sub ecx, 2",\
"skip2: mov ebx, ecx",\
"shr ecx, 2",\
"rep movsd",\
"test bl, 2",\
"jz skip3",\
"movsw",\
"skip3: test bl, 1",\
"jz endit",\
"movsb",\
"endit:",\
parm [esi][edi][ecx]\
modify [ebx]\
#pragma aux showscreen4pix320200 =\
"mov dx, 0x3c4",\
"mov ax, 0x0f02",\
"out dx, ax",\
"mov ecx, 4000",\
"mov esi, scrbuf",\
"mov edi, frameplace",\
"rep movsd",\
modify [eax ecx edx esi edi]\
#pragma aux showscreen4pix320400 =\
"mov dx, 0x3c4",\
"mov ax, 0x0f02",\
"out dx, ax",\
"mov ecx, 8000",\
"mov esi, scrbuf",\
"mov edi, frameplace",\
"rep movsd",\
modify [eax ecx edx esi edi]\
#pragma aux showscreen2pix320200 =\
"mov dx, 0x3c4",\
"mov ax, 0x0302",\
"out dx, ax",\
"mov ecx, 4000",\
"mov esi, scrbuf",\
"mov edi, frameplace",\
"rep movsd",\
"mov ax, 0x0c02",\
"out dx, ax",\
"mov ecx, 4000",\
"mov edi, frameplace",\
"rep movsd",\
modify [eax ecx edx esi edi]\
#pragma aux showscreen2pix320400 =\
"mov dx, 0x3c4",\
"mov ax, 0x0302",\
"out dx, ax",\
"mov ecx, 8000",\
"mov esi, scrbuf",\
"mov edi, frameplace",\
"rep movsd",\
"mov ax, 0x0c02",\
"out dx, ax",\
"mov ecx, 8000",\
"mov edi, frameplace",\
"rep movsd",\
modify [eax ecx edx esi edi]\
#pragma aux showscreen1pix320200 =\
"mov dx, 0x3c4",\
"mov ax, 0x0102",\
"out dx, ax",\
"mov ecx, 4000",\
"mov esi, scrbuf",\
"mov edi, frameplace",\
"rep movsd",\
"mov ax, 0x0202",\
"out dx, ax",\
"mov ecx, 4000",\
"mov edi, frameplace",\
"rep movsd",\
"mov ax, 0x0402",\
"out dx, ax",\
"mov ecx, 4000",\
"mov edi, frameplace",\
"rep movsd",\
"mov ax, 0x0802",\
"out dx, ax",\
"mov ecx, 4000",\
"mov edi, frameplace",\
"rep movsd",\
modify [eax ecx edx esi edi]\
#pragma aux showscreen1pix320400 =\
"mov dx, 0x3c4",\
"mov ax, 0x0102",\
"out dx, ax",\
"mov ecx, 8000",\
"mov esi, scrbuf",\
"mov edi, frameplace",\
"rep movsd",\
"mov ax, 0x0202",\
"out dx, ax",\
"mov ecx, 8000",\
"mov edi, frameplace",\
"rep movsd",\
"mov ax, 0x0402",\
"out dx, ax",\
"mov ecx, 8000",\
"mov edi, frameplace",\
"rep movsd",\
"mov ax, 0x0802",\
"out dx, ax",\
"mov ecx, 8000",\
"mov edi, frameplace",\
"rep movsd",\
modify [eax ecx edx esi edi]\
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -