Annotation of src/game.c, revision 1.1

1.1     ! root        1: #include <fcntl.h>
        !             2: #include <io.h>
        !             3: #include <sys\types.h>
        !             4: #include <sys\stat.h>
        !             5: #include <string.h>
        !             6: #include <stdlib.h>
        !             7: #include <dos.h>
        !             8: #include "build.h"
        !             9: #include "names.h"
        !            10: 
        !            11: #define TICSPERFRAME 3
        !            12: #define MOVEFIFOSIZ 256
        !            13: 
        !            14: /***************************************************************************
        !            15:        KEN'S TAG DEFINITIONS:      (Please define your own tags for your games)
        !            16: 
        !            17:  sector[?].lotag = 0   Normal sector
        !            18:  sector[?].lotag = 1   If you are on a sector with this tag, then all sectors
        !            19:                                                                  with same hi tag as this are operated.  Once.
        !            20:  sector[?].lotag = 2   Same as sector[?].tag = 1 but this is retriggable.
        !            21:  sector[?].lotag = 3   A really stupid sector that really does nothing now.
        !            22:  sector[?].lotag = 4   A sector where you are put closer to the floor
        !            23:                                                                  (such as the slime in DOOM1.DAT)
        !            24:  sector[?].lotag = 5   A really stupid sector that really does nothing now.
        !            25:  sector[?].lotag = 6   A normal door - instead of pressing D, you tag the
        !            26:                                                                  sector with a 6.  The reason I make you edit doors
        !            27:                                                                  this way is so that can program the doors
        !            28:                                                                  yourself.
        !            29:  sector[?].lotag = 7   A door the goes down to open.
        !            30:  sector[?].lotag = 8   A door that opens horizontally in the middle.
        !            31:  sector[?].lotag = 9   A sliding door that opens vertically in the middle.
        !            32:                                                                  -Example of the advantages of not using BSP tree.
        !            33:  sector[?].lotag = 10  A warping sector with floor and walls that shade.
        !            34:  sector[?].lotag = 11  A sector with all walls that do X-panning.
        !            35:  sector[?].lotag = 12  A sector with walls using the dragging function.
        !            36:  sector[?].lotag = 13  A sector with some swinging doors in it.
        !            37:  sector[?].lotag = 14  A revolving door sector.
        !            38:  sector[?].lotag = 15  A subway track.
        !            39:  sector[?].lotag = 16  A true double-sliding door.
        !            40:  sector[?].lotag = 17  A true double-sliding door for subways only.
        !            41: 
        !            42:        wall[?].lotag = 0   Normal wall
        !            43:        wall[?].lotag = 1   Y-panning wall
        !            44:        wall[?].lotag = 2   Switch - If you flip it, then all sectors with same hi
        !            45:                                                                  tag as this are operated.
        !            46:        wall[?].lotag = 3   Marked wall to detemine starting dir. (sector tag 12)
        !            47:        wall[?].lotag = 4   Mark on the shorter wall closest to the pivot point
        !            48:                                                                  of a swinging door. (sector tag 13)
        !            49:        wall[?].lotag = 5   Mark where a subway should stop. (sector tag 15)
        !            50:        wall[?].lotag = 6   Mark for true double-sliding doors (sector tag 16)
        !            51:        wall[?].lotag = 7   Water fountain
        !            52:        wall[?].lotag = 8   Bouncy wall!
        !            53: 
        !            54:  sprite[?].lotag = 0   Normal sprite
        !            55:  sprite[?].lotag = 1   If you press space bar on an AL, and the AL is tagged
        !            56:                                                                  with a 1, he will turn evil.
        !            57:  sprite[?].lotag = 2   When this sprite is operated, a bomb is shot at its
        !            58:                                                                  position.
        !            59:  sprite[?].lotag = 3   Rotating sprite.
        !            60:  sprite[?].lotag = 4   Sprite switch.
        !            61:  sprite[?].lotag = 5   Basketball hoop score.
        !            62: 
        !            63: KEN'S STATUS DEFINITIONS:  (Please define your own statuses for your games)
        !            64:  status = 0            Inactive sprite
        !            65:  status = 1            Active monster sprite
        !            66:  status = 2            Monster that becomes active only when it sees you
        !            67:  status = 3            Smoke on the wall for chainguns
        !            68:  status = 4            Splashing sprites (When you shoot slime)
        !            69:  status = 5            Explosion!
        !            70:  status = 6            Travelling bullet
        !            71:  status = 7            Bomb sprial-out explosion
        !            72:  status = 8            Player!
        !            73:  status = MAXSTATUS    Non-existent sprite (this will be true for your
        !            74:                                                                                                                  code also)
        !            75: **************************************************************************/
        !            76: 
        !            77: typedef struct
        !            78: {
        !            79:        long x, y, z;
        !            80: } point3d;
        !            81: 
        !            82: void (__interrupt __far *oldtimerhandler)();
        !            83: void __interrupt __far timerhandler(void);
        !            84: 
        !            85: #define KEYFIFOSIZ 64
        !            86: void (__interrupt __far *oldkeyhandler)();
        !            87: void __interrupt __far keyhandler(void);
        !            88: volatile char keystatus[256], keyfifo[KEYFIFOSIZ], keyfifoplc, keyfifoend;
        !            89: volatile char readch, oldreadch, extended, keytemp;
        !            90: 
        !            91: static long vel, svel, angvel;
        !            92: static long vel2, svel2, angvel2;
        !            93: 
        !            94: extern volatile long recsnddone, recsndoffs;
        !            95: static long recording = -2;
        !            96: 
        !            97: #define NUMOPTIONS 8
        !            98: #define NUMKEYS 19
        !            99: static long chainxres[4] = {256,320,360,400};
        !           100: static long chainyres[11] = {200,240,256,270,300,350,360,400,480,512,540};
        !           101: static long vesares[7][2] = {320,200,640,400,640,480,800,600,1024,768,
        !           102:                                                                          1280,1024,1600,1200};
        !           103: static char option[NUMOPTIONS] = {0,0,0,0,0,0,1,0};
        !           104: static char keys[NUMKEYS] =
        !           105: {
        !           106:        0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39,
        !           107:        0x1e,0x2c,0xd1,0xc9,0x33,0x34,
        !           108:        0x9c,0x1c,0xd,0xc,0xf,
        !           109: };
        !           110: 
        !           111: static long digihz[7] = {6000,8000,11025,16000,22050,32000,44100};
        !           112: 
        !           113: static char frame2draw[MAXPLAYERS];
        !           114: static long frameskipcnt[MAXPLAYERS];
        !           115: 
        !           116: static char gundmost[320];
        !           117: 
        !           118: #define LAVASIZ 128
        !           119: #define LAVALOGSIZ 7
        !           120: #define LAVAMAXDROPS 32
        !           121: static char lavabakpic[(LAVASIZ+2)*(LAVASIZ+2)], lavainc[LAVASIZ];
        !           122: static long lavanumdrops, lavanumframes;
        !           123: static long lavadropx[LAVAMAXDROPS], lavadropy[LAVAMAXDROPS];
        !           124: static long lavadropsiz[LAVAMAXDROPS], lavadropsizlookup[LAVAMAXDROPS];
        !           125: static long lavaradx[32][128], lavarady[32][128], lavaradcnt[32];
        !           126: 
        !           127:        //Shared player variables
        !           128: static long posx[MAXPLAYERS], posy[MAXPLAYERS], posz[MAXPLAYERS];
        !           129: static long horiz[MAXPLAYERS], zoom[MAXPLAYERS], hvel[MAXPLAYERS];
        !           130: static short ang[MAXPLAYERS], cursectnum[MAXPLAYERS], ocursectnum[MAXPLAYERS];
        !           131: static short playersprite[MAXPLAYERS], deaths[MAXPLAYERS];
        !           132: static long lastchaingun[MAXPLAYERS];
        !           133: static long health[MAXPLAYERS], score[MAXPLAYERS], saywatchit[MAXPLAYERS];
        !           134: static short numbombs[MAXPLAYERS], oflags[MAXPLAYERS];
        !           135: static char dimensionmode[MAXPLAYERS];
        !           136: static char revolvedoorstat[MAXPLAYERS];
        !           137: static short revolvedoorang[MAXPLAYERS], revolvedoorrotang[MAXPLAYERS];
        !           138: static long revolvedoorx[MAXPLAYERS], revolvedoory[MAXPLAYERS];
        !           139: 
        !           140:        //ENGINE CONTROLLED MULTIPLAYER VARIABLES:
        !           141: extern short numplayers, myconnectindex;
        !           142: extern short connecthead, connectpoint2[MAXPLAYERS];   //Player linked list variables (indeces, not connection numbers)
        !           143: 
        !           144:        //Local multiplayer variables
        !           145: static long locselectedgun;
        !           146: static signed char locvel, olocvel;
        !           147: static signed char locsvel, olocsvel;
        !           148: static signed char locangvel, olocangvel;
        !           149: static short locbits, olocbits;
        !           150: 
        !           151:        //Local multiplayer variables for second player
        !           152: static long locselectedgun2;
        !           153: static signed char locvel2, olocvel2;
        !           154: static signed char locsvel2, olocsvel2;
        !           155: static signed char locangvel2, olocangvel2;
        !           156: static short locbits2, olocbits2;
        !           157: 
        !           158:   //Multiplayer syncing variables
        !           159: static signed char fsyncvel[MAXPLAYERS], osyncvel[MAXPLAYERS], syncvel[MAXPLAYERS];
        !           160: static signed char fsyncsvel[MAXPLAYERS], osyncsvel[MAXPLAYERS], syncsvel[MAXPLAYERS];
        !           161: static signed char fsyncangvel[MAXPLAYERS], osyncangvel[MAXPLAYERS], syncangvel[MAXPLAYERS];
        !           162: static short fsyncbits[MAXPLAYERS], osyncbits[MAXPLAYERS], syncbits[MAXPLAYERS];
        !           163: 
        !           164: static char frameinterpolate = 1, detailmode = 0, ready2send = 0;
        !           165: static long ototalclock = 0, gotlastpacketclock = 0, smoothratio;
        !           166: static long oposx[MAXPLAYERS], oposy[MAXPLAYERS], oposz[MAXPLAYERS];
        !           167: static long ohoriz[MAXPLAYERS], ozoom[MAXPLAYERS];
        !           168: static short oang[MAXPLAYERS];
        !           169: 
        !           170: static point3d osprite[MAXSPRITESONSCREEN];
        !           171: 
        !           172: static long movefifoplc, movefifoend;
        !           173: static signed char baksyncvel[MOVEFIFOSIZ][MAXPLAYERS];
        !           174: static signed char baksyncsvel[MOVEFIFOSIZ][MAXPLAYERS];
        !           175: static signed char baksyncangvel[MOVEFIFOSIZ][MAXPLAYERS];
        !           176: static short baksyncbits[MOVEFIFOSIZ][MAXPLAYERS];
        !           177: 
        !           178:        //MULTI.OBJ sync state variables
        !           179: extern char syncstate;
        !           180:        //GAME.C sync state variables
        !           181: static short syncstat = 0;
        !           182: static long syncvalplc, othersyncvalplc;
        !           183: static long syncvalend, othersyncvalend;
        !           184: static long syncvalcnt, othersyncvalcnt;
        !           185: static short syncval[MOVEFIFOSIZ], othersyncval[MOVEFIFOSIZ];
        !           186: 
        !           187: extern long crctable[256];
        !           188: #define updatecrc16(dacrc,dadat) dacrc = (((dacrc<<8)&65535)^crctable[((((unsigned short)dacrc)>>8)&65535)^dadat])
        !           189: static char playerreadyflag[MAXPLAYERS];
        !           190: 
        !           191:        //Game recording variables
        !           192: static long reccnt, recstat = 1;
        !           193: static signed char recsyncvel[16384][2];
        !           194: static signed char recsyncsvel[16384][2];
        !           195: static signed char recsyncangvel[16384][2];
        !           196: static short recsyncbits[16384][2];
        !           197: 
        !           198:        //Miscellaneous variables
        !           199: static char tempbuf[max(576,MAXXDIM)], boardfilename[80];
        !           200: static short screenpeek = 0, oldmousebstatus = 0, brightness = 0;
        !           201: static short screensize, screensizeflag = 0;
        !           202: static short neartagsector, neartagwall, neartagsprite;
        !           203: static long lockclock, neartagdist, neartaghitdist;
        !           204: static long masterslavetexttime;
        !           205: extern long frameplace, pageoffset, ydim16, chainnumpages;
        !           206: static long globhiz, globloz, globhihit, globlohit;
        !           207: extern long stereofps, stereowidth, stereopixelwidth;
        !           208: 
        !           209:        //Board animation variables
        !           210: static short rotatespritelist[16], rotatespritecnt;
        !           211: static short warpsectorlist[64], warpsectorcnt;
        !           212: static short xpanningsectorlist[16], xpanningsectorcnt;
        !           213: static short ypanningwalllist[64], ypanningwallcnt;
        !           214: static short floorpanninglist[64], floorpanningcnt;
        !           215: static short dragsectorlist[16], dragxdir[16], dragydir[16], dragsectorcnt;
        !           216: static long dragx1[16], dragy1[16], dragx2[16], dragy2[16], dragfloorz[16];
        !           217: static short swingcnt, swingwall[32][5], swingsector[32];
        !           218: static short swingangopen[32], swingangclosed[32], swingangopendir[32];
        !           219: static short swingang[32], swinganginc[32];
        !           220: static long swingx[32][8], swingy[32][8];
        !           221: static short revolvesector[4], revolveang[4], revolvecnt;
        !           222: static long revolvex[4][16], revolvey[4][16];
        !           223: static long revolvepivotx[4], revolvepivoty[4];
        !           224: static short subwaytracksector[4][128], subwaynumsectors[4], subwaytrackcnt;
        !           225: static long subwaystop[4][8], subwaystopcnt[4];
        !           226: static long subwaytrackx1[4], subwaytracky1[4];
        !           227: static long subwaytrackx2[4], subwaytracky2[4];
        !           228: static long subwayx[4], subwaygoalstop[4], subwayvel[4], subwaypausetime[4];
        !           229: static short waterfountainwall[MAXPLAYERS], waterfountaincnt[MAXPLAYERS];
        !           230: static short slimesoundcnt[MAXPLAYERS];
        !           231: 
        !           232:        //Variables that let you type messages to other player
        !           233: static char getmessage[162], getmessageleng;
        !           234: static long getmessagetimeoff;
        !           235: static char typemessage[162], typemessageleng = 0, typemode = 0;
        !           236: static char scantoasc[128] =
        !           237: {
        !           238:        0,0,'1','2','3','4','5','6','7','8','9','0','-','=',0,0,
        !           239:        'q','w','e','r','t','y','u','i','o','p','[',']',0,0,'a','s',
        !           240:        'd','f','g','h','j','k','l',';',39,'`',0,92,'z','x','c','v',
        !           241:        'b','n','m',',','.','/',0,'*',0,32,0,0,0,0,0,0,
        !           242:        0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+','1',
        !           243:        '2','3','0','.',0,0,0,0,0,0,0,0,0,0,0,0,
        !           244:        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        !           245:        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        !           246: };
        !           247: static char scantoascwithshift[128] =
        !           248: {
        !           249:        0,0,'!','@','#','$','%','^','&','*','(',')','_','+',0,0,
        !           250:        'Q','W','E','R','T','Y','U','I','O','P','{','}',0,0,'A','S',
        !           251:        'D','F','G','H','J','K','L',':',34,'~',0,'|','Z','X','C','V',
        !           252:        'B','N','M','<','>','?',0,'*',0,32,0,0,0,0,0,0,
        !           253:        0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+','1',
        !           254:        '2','3','0','.',0,0,0,0,0,0,0,0,0,0,0,0,
        !           255:        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        !           256:        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        !           257: };
        !           258: 
        !           259:        //These variables are for animating x, y, or z-coordinates of sectors,
        !           260:        //walls, or sprites (They are NOT to be used for changing the [].picnum's)
        !           261:        //See the setanimation(), and getanimategoal() functions for more details.
        !           262: #define MAXANIMATES 512
        !           263: static long *animateptr[MAXANIMATES], animategoal[MAXANIMATES];
        !           264: static long animatevel[MAXANIMATES], animateacc[MAXANIMATES], animatecnt = 0;
        !           265: 
        !           266:        //Here are some nice in-line assembly pragmas that make life easier.
        !           267:        //(at least for Ken)
        !           268: #pragma aux setvmode =\
        !           269:        "int 0x10",\
        !           270:        parm [eax]\
        !           271: 
        !           272: #pragma aux clearbuf =\
        !           273:        "rep stosd",\
        !           274:        parm [edi][ecx][eax]\
        !           275: 
        !           276: #pragma aux clearbufbyte =\
        !           277:        "shr ecx, 1",\
        !           278:        "jnc skip1",\
        !           279:        "stosb",\
        !           280:        "skip1: shr ecx, 1",\
        !           281:        "jnc skip2",\
        !           282:        "stosw",\
        !           283:        "skip2: test ecx, ecx",\
        !           284:        "jz skip3",\
        !           285:        "rep stosd",\
        !           286:        "skip3:",\
        !           287:        parm [edi][ecx][eax]\
        !           288: 
        !           289: #pragma aux copybuf =\
        !           290:        "rep movsd",\
        !           291:        parm [esi][edi][ecx]\
        !           292: 
        !           293: #pragma aux copybufbyte =\
        !           294:        "shr ecx, 1",\
        !           295:        "jnc skip1",\
        !           296:        "movsb",\
        !           297:        "skip1: shr ecx, 1",\
        !           298:        "jnc skip2",\
        !           299:        "movsw",\
        !           300:        "skip2: test ecx, ecx",\
        !           301:        "jz skip3",\
        !           302:        "rep movsd",\
        !           303:        "skip3:",\
        !           304:        parm [esi][edi][ecx]\
        !           305: 
        !           306: #pragma aux copybufreverse =\
        !           307:        "shr ecx, 1",\
        !           308:        "jnc skipit1",\
        !           309:        "mov al, byte ptr [esi]",\
        !           310:        "dec esi",\
        !           311:        "mov byte ptr [edi], al",\
        !           312:        "inc edi",\
        !           313:        "skipit1: shr ecx, 1",\
        !           314:        "jnc skipit2",\
        !           315:        "mov ax, word ptr [esi-1]",\
        !           316:        "sub esi, 2",\
        !           317:        "ror ax, 8",\
        !           318:        "mov word ptr [edi], ax",\
        !           319:        "add edi, 2",\
        !           320:        "skipit2: test ecx, ecx",\
        !           321:        "jz endloop",\
        !           322:        "begloop: mov eax, dword ptr [esi-3]",\
        !           323:        "sub esi, 4",\
        !           324:        "bswap eax",\
        !           325:        "mov dword ptr [edi], eax",\
        !           326:        "add edi, 4",\
        !           327:        "dec ecx",\
        !           328:        "jnz begloop",\
        !           329:        "endloop:",\
        !           330:        parm [esi][edi][ecx]\
        !           331: 
        !           332: #pragma aux klabs =\
        !           333:        "test eax, eax",\
        !           334:        "jns skipnegate",\
        !           335:        "neg eax",\
        !           336:        "skipnegate:",\
        !           337:        parm [eax]\
        !           338: 
        !           339: #pragma aux ksgn =\
        !           340:        "add ebx, ebx",\
        !           341:        "sbb eax, eax",\
        !           342:        "cmp eax, ebx",\
        !           343:        "adc eax, 0",\
        !           344:        parm [ebx]\
        !           345: 
        !           346: #pragma aux koutp =\
        !           347:        "out dx, al",\
        !           348:        parm [edx][eax]\
        !           349: 
        !           350: #pragma aux koutpw =\
        !           351:        "out dx, ax",\
        !           352:        parm [edx][eax]\
        !           353: 
        !           354: #pragma aux kinp =\
        !           355:        "in al, dx",\
        !           356:        parm [edx]\
        !           357: 
        !           358: #pragma aux mulscale =\
        !           359:        "imul ebx",\
        !           360:        "shrd eax, edx, cl",\
        !           361:        parm [eax][ebx][ecx]\
        !           362:        modify [edx]\
        !           363: 
        !           364: #pragma aux divscale =\
        !           365:        "mov edx, eax",\
        !           366:        "sar edx, 31",\
        !           367:        "shld edx, eax, cl",\
        !           368:        "sal eax, cl",\
        !           369:        "idiv ebx",\
        !           370:        parm [eax][ebx][ecx]\
        !           371:        modify [edx]\
        !           372: 
        !           373: #pragma aux scale =\
        !           374:        "imul ebx",\
        !           375:        "idiv ecx",\
        !           376:        parm [eax][ebx][ecx]\
        !           377:        modify [eax edx]\
        !           378: 
        !           379:        //These parameters are in exact order of sprite structure in BUILD.H
        !           380: #define spawnsprite(newspriteindex2,x2,y2,z2,cstat2,shade2,pal2,       \
        !           381:                clipdist2,xrepeat2,yrepeat2,xoffset2,yoffset2,picnum2,ang2,      \
        !           382:                xvel2,yvel2,zvel2,owner2,sectnum2,statnum2,lotag2,hitag2,extra2) \
        !           383: {                                                                      \
        !           384:        spritetype *spr2;                                                   \
        !           385:        newspriteindex2 = insertsprite(sectnum2,statnum2);                  \
        !           386:        spr2 = &sprite[newspriteindex2];                                    \
        !           387:        spr2->x = x2; spr2->y = y2; spr2->z = z2;                           \
        !           388:        spr2->cstat = cstat2; spr2->shade = shade2;                         \
        !           389:        spr2->pal = pal2; spr2->clipdist = clipdist2;                       \
        !           390:        spr2->xrepeat = xrepeat2; spr2->yrepeat = yrepeat2;                 \
        !           391:        spr2->xoffset = xoffset2; spr2->yoffset = yoffset2;                 \
        !           392:        spr2->picnum = picnum2; spr2->ang = ang2;                           \
        !           393:        spr2->xvel = xvel2; spr2->yvel = yvel2; spr2->zvel = zvel2;         \
        !           394:        spr2->owner = owner2;                                               \
        !           395:        spr2->lotag = lotag2; spr2->hitag = hitag2; spr2->extra = extra2;   \
        !           396:        copybuf(&spr2->x,&osprite[newspriteindex2].x,3);                    \
        !           397: }                                                                      \
        !           398: 
        !           399: main(short int argc,char **argv)
        !           400: {
        !           401:        long i, j, k, l, fil, waitplayers, x1, y1, x2, y2;
        !           402:        short other, tempbufleng;
        !           403:        char *ptr;
        !           404: 
        !           405:        initgroupfile("stuff.dat");
        !           406: 
        !           407:        if ((argc >= 2) && (stricmp("-net",argv[1]) != 0) && (stricmp("/net",argv[1]) != 0))
        !           408:        {
        !           409:                strcpy(&boardfilename,argv[1]);
        !           410:                if(strchr(boardfilename,'.') == 0)
        !           411:                        strcat(boardfilename,".map");
        !           412:        }
        !           413:        else
        !           414:                strcpy(&boardfilename,"nukeland.map");
        !           415: 
        !           416:        if ((fil = open("setup.dat",O_BINARY|O_RDWR,S_IREAD)) != -1)
        !           417:        {
        !           418:                read(fil,&option[0],NUMOPTIONS);
        !           419:                read(fil,&keys[0],NUMKEYS);
        !           420:                close(fil);
        !           421:        }
        !           422:        if (option[3] != 0) initmouse();
        !           423: 
        !           424:        switch(option[0])
        !           425:        {
        !           426:                case 0: initengine(0,chainxres[option[6]&15],chainyres[option[6]>>4]); break;
        !           427:                case 1: initengine(1,vesares[option[6]&15][0],vesares[option[6]&15][1]); break;
        !           428:                case 2: initengine(2,320L,200L); break;
        !           429:                case 3: initengine(3,320L,200L); break;
        !           430:                case 4: initengine(4,320L,200L); break;
        !           431:                case 5: initengine(5,320L,200L); break;
        !           432:                case 6: initengine(6,320L,200L); break;
        !           433:        }
        !           434:        initkeys();
        !           435:        inittimer();
        !           436:        initmultiplayers(option[4],option[5]);
        !           437: 
        !           438:        pskyoff[0] = 0; pskyoff[1] = 0; pskybits = 1;
        !           439: 
        !           440:        initsb(option[1],option[2],digihz[option[7]>>4],((option[7]&4)>0)+1,((option[7]&2)>0)+1,60,option[7]&1);
        !           441:        if (strcmp(boardfilename,"klab.map") == 0)
        !           442:                loadsong("klabsong.kdm");
        !           443:        else
        !           444:                loadsong("neatsong.kdm");
        !           445:        musicon();
        !           446: 
        !           447:        loadpics("tiles000.art");                      //Load artwork
        !           448:        initlava();
        !           449: 
        !           450:                //Get dmost table for canon
        !           451:        if (waloff[GUNONBOTTOM] == 0) loadtile(GUNONBOTTOM);
        !           452:        x1 = tilesizx[GUNONBOTTOM]; y1 = tilesizy[GUNONBOTTOM];
        !           453:        ptr = (char *)(waloff[GUNONBOTTOM]);
        !           454:        for(i=0;i<x1;i++)
        !           455:        {
        !           456:                y2 = y1-1; while ((ptr[y2] != 255) && (y2 >= 0)) y2--;
        !           457:                gundmost[i] = y2+1;
        !           458:                ptr += y1;
        !           459:        }
        !           460: 
        !           461:                //Try making a title screen & uncommenting this!
        !           462:        //setgamemode();
        !           463:        //setview(0L,0L,xdim-1,(ydim-1)>>detailmode);
        !           464:        //loadtile(TITLESCREEN);
        !           465:        //i = 0; j = 1621;
        !           466:        //for(k=0;k<256;k++)
        !           467:        //{
        !           468:        //   for(l=0;l<256;l++)
        !           469:        //   {
        !           470:        //      ptr = (char *)(waloff[TITLESCREEN]+i);
        !           471:        //      *ptr = 159;
        !           472:        //      i = (i+j)&65535; j = (j+4)&65535;
        !           473:        //   }
        !           474:        //   overwritesprite(0L,0L,TITLESCREEN,0,0,0);
        !           475:        //   nextpage();
        !           476:        //}
        !           477: 
        !           478:                //Here's an example of TRUE ornamented walls
        !           479:                //The allocatepermanenttile should be called right after loadpics
        !           480:                //Since it resets the tile cache for each call.
        !           481:        if (allocatepermanenttile(4095,64,64) >= 0)    //If enough memory
        !           482:        {
        !           483:                        //My face with an explosion written over it
        !           484:                copytilepiece(KENPICTURE,0,0,64,64,4095,0,0);
        !           485:                copytilepiece(EXPLOSION,0,0,64,64,4095,0,0);
        !           486:        }
        !           487:        if (allocatepermanenttile(SLIME,128,128) < 0)    //If enough memory
        !           488:        {
        !           489:                printf("Not enough memory for slime!\n");
        !           490:                exit(0);
        !           491:        }
        !           492: 
        !           493:        for(j=0;j<256;j++)
        !           494:                tempbuf[j] = ((j+32)&255);  //remap colors for screwy palette sectors
        !           495:        makepalookup(16,tempbuf,0,0,0,1);
        !           496: 
        !           497:        for(j=0;j<256;j++) tempbuf[j] = j;
        !           498:        makepalookup(17,tempbuf,24,24,24,1);
        !           499: 
        !           500:        for(j=0;j<256;j++) tempbuf[j] = j; //(j&31)+32;
        !           501:        makepalookup(18,tempbuf,8,8,48,1);
        !           502: 
        !           503:        prepareboard(boardfilename);                   //Load board
        !           504: 
        !           505:        if (option[4] > 0)
        !           506:        {
        !           507:                x1 = (xdim>>1)-(screensize>>1);
        !           508:                x2 = x1+screensize-1;
        !           509:                y1 = ((ydim-32)>>1)-(((screensize*(ydim-32))/xdim)>>1);
        !           510:                y2 = y1 + ((screensize*(ydim-32))/xdim)-1;
        !           511:                permanentwritespritetile(0L,0L,BACKGROUND,0,x1,y1,x2,y2,0);
        !           512: 
        !           513:                sendlogon();
        !           514:                if (option[4] < 5) waitplayers = 2; else waitplayers = option[4]-3;
        !           515:                while (numplayers < waitplayers)
        !           516:                {
        !           517:                        sprintf(tempbuf,"%ld of %ld players in...",numplayers,waitplayers);
        !           518:                        printext256(68L,84L,31,0,tempbuf,0);
        !           519:                        nextpage();
        !           520: 
        !           521:                        if (getpacket(&other,tempbuf) > 0)
        !           522:                                if (tempbuf[0] == 255)
        !           523:                                        keystatus[1] = 1;
        !           524: 
        !           525:                        if (keystatus[1] > 0)
        !           526:                        {
        !           527:                                sendlogoff();         //Signing off
        !           528:                                musicoff();
        !           529:                                uninitmultiplayers();
        !           530:                                uninittimer();
        !           531:                                uninitkeys();
        !           532:                                uninitengine();
        !           533:                                uninitsb();
        !           534:                                uninitgroupfile();
        !           535:                                setvmode(0x3);        //Set back to text mode
        !           536:                                exit(0);
        !           537:                        }
        !           538:                }
        !           539:                screenpeek = myconnectindex;
        !           540:        }
        !           541: 
        !           542:        reccnt = 0;
        !           543:        for(i=connecthead;i>=0;i=connectpoint2[i]) initplayersprite((short)i);
        !           544: 
        !           545:        //waitforeverybody();
        !           546:        resettiming(); ototalclock = 0; gotlastpacketclock = 0;
        !           547: 
        !           548:        ready2send = 1;
        !           549:        while (keystatus[1] == 0)       //Main loop starts here
        !           550:        {
        !           551:                        // backslash (useful only with KDM)
        !           552:                if (keystatus[0x2b] > 0) { keystatus[0x2b] = 0; preparesndbuf(); }
        !           553: 
        !           554:                while (movefifoplc != movefifoend) domovethings();
        !           555:                drawscreen(screenpeek,(totalclock-gotlastpacketclock)*(65536/TICSPERFRAME));
        !           556:        }
        !           557:        ready2send = 0;
        !           558: 
        !           559:        sendlogoff();         //Signing off
        !           560:        musicoff();
        !           561:        uninitmultiplayers();
        !           562:        uninittimer();
        !           563:        uninitkeys();
        !           564:        uninitengine();
        !           565:        uninitsb();
        !           566:        uninitgroupfile();
        !           567:        setvmode(0x3);        //Set back to text mode
        !           568:        showengineinfo();     //Show speed statistics
        !           569: 
        !           570:        return(0);
        !           571: }
        !           572: 
        !           573: operatesector(short dasector)
        !           574: {     //Door code
        !           575:        long i, j, k, s, nexti, good, cnt, datag;
        !           576:        long dax, day, daz, dax2, day2, daz2, centx, centy;
        !           577:        short startwall, endwall, wallfind[2];
        !           578: 
        !           579:        datag = sector[dasector].lotag;
        !           580: 
        !           581:        startwall = sector[dasector].wallptr;
        !           582:        endwall = startwall + sector[dasector].wallnum - 1;
        !           583:        centx = 0L, centy = 0L;
        !           584:        for(i=startwall;i<=endwall;i++)
        !           585:        {
        !           586:                centx += wall[i].x;
        !           587:                centy += wall[i].y;
        !           588:        }
        !           589:        centx /= (endwall-startwall+1);
        !           590:        centy /= (endwall-startwall+1);
        !           591: 
        !           592:                //Simple door that moves up  (tag 8 is a combination of tags 6 & 7)
        !           593:        if ((datag == 6) || (datag == 8))    //If the sector in front is a door
        !           594:        {
        !           595:                i = getanimationgoal((long)&sector[dasector].ceilingz);
        !           596:                if (i >= 0)      //If door already moving, reverse its direction
        !           597:                {
        !           598:                        if (datag == 8)
        !           599:                                daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1);
        !           600:                        else
        !           601:                                daz = sector[dasector].floorz;
        !           602: 
        !           603:                        if (animategoal[i] == daz)
        !           604:                                animategoal[i] = sector[nextsectorneighborz(dasector,sector[dasector].floorz,-1,-1)].ceilingz;
        !           605:                        else
        !           606:                                animategoal[i] = daz;
        !           607:                        animatevel[i] = 0;
        !           608:                }
        !           609:                else      //else insert the door's ceiling on the animation list
        !           610:                {
        !           611:                        if (sector[dasector].ceilingz == sector[dasector].floorz)
        !           612:                                daz = sector[nextsectorneighborz(dasector,sector[dasector].floorz,-1,-1)].ceilingz;
        !           613:                        else
        !           614:                        {
        !           615:                                if (datag == 8)
        !           616:                                        daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1);
        !           617:                                else
        !           618:                                        daz = sector[dasector].floorz;
        !           619:                        }
        !           620:                        if ((j = setanimation(&sector[dasector].ceilingz,daz,6L,6L)) >= 0)
        !           621:                                wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,&centx,&centy,0);
        !           622:                }
        !           623:        }
        !           624:                //Simple door that moves down
        !           625:        if ((datag == 7) || (datag == 8)) //If the sector in front's elevator
        !           626:        {
        !           627:                i = getanimationgoal((long)&sector[dasector].floorz);
        !           628:                if (i >= 0)      //If elevator already moving, reverse its direction
        !           629:                {
        !           630:                        if (datag == 8)
        !           631:                                daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1);
        !           632:                        else
        !           633:                                daz = sector[dasector].ceilingz;
        !           634: 
        !           635:                        if (animategoal[i] == daz)
        !           636:                                animategoal[i] = sector[nextsectorneighborz(dasector,sector[dasector].ceilingz,1,1)].floorz;
        !           637:                        else
        !           638:                                animategoal[i] = daz;
        !           639:                        animatevel[i] = 0;
        !           640:                }
        !           641:                else      //else insert the elevator's ceiling on the animation list
        !           642:                {
        !           643:                        if (sector[dasector].floorz == sector[dasector].ceilingz)
        !           644:                                daz = sector[nextsectorneighborz(dasector,sector[dasector].ceilingz,1,1)].floorz;
        !           645:                        else
        !           646:                        {
        !           647:                                if (datag == 8)
        !           648:                                        daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1);
        !           649:                                else
        !           650:                                        daz = sector[dasector].ceilingz;
        !           651:                        }
        !           652:                        if ((j = setanimation(&sector[dasector].floorz,daz,6L,6L)) >= 0)
        !           653:                                wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,&centx,&centy,0);
        !           654:                }
        !           655:        }
        !           656: 
        !           657:        if (datag == 9)   //Smooshy-wall sideways double-door
        !           658:        {
        !           659:                //find any points with either same x or same y coordinate
        !           660:                //  as center (centx, centy) - should be 2 points found.
        !           661:                wallfind[0] = -1;
        !           662:                wallfind[1] = -1;
        !           663:                for(i=startwall;i<=endwall;i++)
        !           664:                        if ((wall[i].x == centx) || (wall[i].y == centy))
        !           665:                        {
        !           666:                                if (wallfind[0] == -1)
        !           667:                                        wallfind[0] = i;
        !           668:                                else
        !           669:                                        wallfind[1] = i;
        !           670:                        }
        !           671: 
        !           672:                for(j=0;j<2;j++)
        !           673:                {
        !           674:                        if ((wall[wallfind[j]].x == centx) && (wall[wallfind[j]].y == centy))
        !           675:                        {
        !           676:                                //find what direction door should open by averaging the
        !           677:                                //  2 neighboring points of wallfind[0] & wallfind[1].
        !           678:                                i = wallfind[j]-1; if (i < startwall) i = endwall;
        !           679:                                dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x;
        !           680:                                day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y;
        !           681:                                if (dax2 != 0)
        !           682:                                {
        !           683:                                        dax2 = wall[wall[wall[wallfind[j]].point2].point2].x;
        !           684:                                        dax2 -= wall[wall[wallfind[j]].point2].x;
        !           685:                                        setanimation(&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,4L,0L);
        !           686:                                        setanimation(&wall[i].x,wall[i].x+dax2,4L,0L);
        !           687:                                        setanimation(&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,4L,0L);
        !           688:                                }
        !           689:                                else if (day2 != 0)
        !           690:                                {
        !           691:                                        day2 = wall[wall[wall[wallfind[j]].point2].point2].y;
        !           692:                                        day2 -= wall[wall[wallfind[j]].point2].y;
        !           693:                                        setanimation(&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,4L,0L);
        !           694:                                        setanimation(&wall[i].y,wall[i].y+day2,4L,0L);
        !           695:                                        setanimation(&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,4L,0L);
        !           696:                                }
        !           697:                        }
        !           698:                        else
        !           699:                        {
        !           700:                                i = wallfind[j]-1; if (i < startwall) i = endwall;
        !           701:                                dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x;
        !           702:                                day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y;
        !           703:                                if (dax2 != 0)
        !           704:                                {
        !           705:                                        setanimation(&wall[wallfind[j]].x,centx,4L,0L);
        !           706:                                        setanimation(&wall[i].x,centx+dax2,4L,0L);
        !           707:                                        setanimation(&wall[wall[wallfind[j]].point2].x,centx+dax2,4L,0L);
        !           708:                                }
        !           709:                                else if (day2 != 0)
        !           710:                                {
        !           711:                                        setanimation(&wall[wallfind[j]].y,centy,4L,0L);
        !           712:                                        setanimation(&wall[i].y,centy+day2,4L,0L);
        !           713:                                        setanimation(&wall[wall[wallfind[j]].point2].y,centy+day2,4L,0L);
        !           714:                                }
        !           715:                        }
        !           716:                }
        !           717:                wsayfollow("updowndr.wav",4096L-256L,256L,&centx,&centy,0);
        !           718:                wsayfollow("updowndr.wav",4096L+256L,256L,&centx,&centy,0);
        !           719:        }
        !           720: 
        !           721:        if (datag == 13)  //Swinging door
        !           722:        {
        !           723:                for(i=0;i<swingcnt;i++)
        !           724:                {
        !           725:                        if (swingsector[i] == dasector)
        !           726:                        {
        !           727:                                if (swinganginc[i] == 0)
        !           728:                                {
        !           729:                                        if (swingang[i] == swingangclosed[i])
        !           730:                                        {
        !           731:                                                swinganginc[i] = swingangopendir[i];
        !           732:                                                wsayfollow("opendoor.wav",4096L+(krand()&511)-256,256L,&centx,&centy,0);
        !           733:                                        }
        !           734:                                        else
        !           735:                                                swinganginc[i] = -swingangopendir[i];
        !           736:                                }
        !           737:                                else
        !           738:                                        swinganginc[i] = -swinganginc[i];
        !           739:                        }
        !           740:                }
        !           741:        }
        !           742: 
        !           743:        if (datag == 16)  //True sideways double-sliding door
        !           744:        {
        !           745:                 //get 2 closest line segments to center (dax, day)
        !           746:                wallfind[0] = -1;
        !           747:                wallfind[1] = -1;
        !           748:                for(i=startwall;i<=endwall;i++)
        !           749:                        if (wall[i].lotag == 6)
        !           750:                        {
        !           751:                                if (wallfind[0] == -1)
        !           752:                                        wallfind[0] = i;
        !           753:                                else
        !           754:                                        wallfind[1] = i;
        !           755:                        }
        !           756: 
        !           757:                for(j=0;j<2;j++)
        !           758:                {
        !           759:                        if ((((wall[wallfind[j]].x+wall[wall[wallfind[j]].point2].x)>>1) == centx) && (((wall[wallfind[j]].y+wall[wall[wallfind[j]].point2].y)>>1) == centy))
        !           760:                        {     //door was closed
        !           761:                                        //find what direction door should open
        !           762:                                i = wallfind[j]-1; if (i < startwall) i = endwall;
        !           763:                                dax2 = wall[i].x-wall[wallfind[j]].x;
        !           764:                                day2 = wall[i].y-wall[wallfind[j]].y;
        !           765:                                if (dax2 != 0)
        !           766:                                {
        !           767:                                        dax2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].x;
        !           768:                                        dax2 -= wall[wall[wall[wallfind[j]].point2].point2].x;
        !           769:                                        setanimation(&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,4L,0L);
        !           770:                                        setanimation(&wall[i].x,wall[i].x+dax2,4L,0L);
        !           771:                                        setanimation(&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,4L,0L);
        !           772:                                        setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,wall[wall[wall[wallfind[j]].point2].point2].x+dax2,4L,0L);
        !           773:                                }
        !           774:                                else if (day2 != 0)
        !           775:                                {
        !           776:                                        day2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].y;
        !           777:                                        day2 -= wall[wall[wall[wallfind[j]].point2].point2].y;
        !           778:                                        setanimation(&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,4L,0L);
        !           779:                                        setanimation(&wall[i].y,wall[i].y+day2,4L,0L);
        !           780:                                        setanimation(&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,4L,0L);
        !           781:                                        setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,wall[wall[wall[wallfind[j]].point2].point2].y+day2,4L,0L);
        !           782:                                }
        !           783:                        }
        !           784:                        else
        !           785:                        {    //door was not closed
        !           786:                                i = wallfind[j]-1; if (i < startwall) i = endwall;
        !           787:                                dax2 = wall[i].x-wall[wallfind[j]].x;
        !           788:                                day2 = wall[i].y-wall[wallfind[j]].y;
        !           789:                                if (dax2 != 0)
        !           790:                                {
        !           791:                                        setanimation(&wall[wallfind[j]].x,centx,4L,0L);
        !           792:                                        setanimation(&wall[i].x,centx+dax2,4L,0L);
        !           793:                                        setanimation(&wall[wall[wallfind[j]].point2].x,centx,4L,0L);
        !           794:                                        setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,centx+dax2,4L,0L);
        !           795:                                }
        !           796:                                else if (day2 != 0)
        !           797:                                {
        !           798:                                        setanimation(&wall[wallfind[j]].y,centy,4L,0L);
        !           799:                                        setanimation(&wall[i].y,centy+day2,4L,0L);
        !           800:                                        setanimation(&wall[wall[wallfind[j]].point2].y,centy,4L,0L);
        !           801:                                        setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,centy+day2,4L,0L);
        !           802:                                }
        !           803:                        }
        !           804:                }
        !           805:                wsayfollow("updowndr.wav",4096L-64L,256L,&centx,&centy,0);
        !           806:                wsayfollow("updowndr.wav",4096L+64L,256L,&centx,&centy,0);
        !           807:        }
        !           808: }
        !           809: 
        !           810: operatesprite(short dasprite)
        !           811: {
        !           812:        long datag;
        !           813: 
        !           814:        datag = sprite[dasprite].lotag;
        !           815: 
        !           816:        if (datag == 2)    //A sprite that shoots a bomb
        !           817:        {
        !           818:                shootgun(dasprite,
        !           819:                                        sprite[dasprite].x,sprite[dasprite].y,sprite[dasprite].z,
        !           820:                                        sprite[dasprite].ang,100L,sprite[dasprite].sectnum,2);
        !           821:        }
        !           822: }
        !           823: 
        !           824: changehealth(short snum, short deltahealth)
        !           825: {
        !           826:        long dax, day;
        !           827:        short good, k, startwall, endwall, s;
        !           828: 
        !           829:        if (health[snum] > 0)
        !           830:        {
        !           831:                health[snum] += deltahealth;
        !           832:                if (health[snum] > 999) health[snum] = 999;
        !           833: 
        !           834:                if (health[snum] <= 0)
        !           835:                {
        !           836:                        health[snum] = -1;
        !           837:                        wsayfollow("death.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1);
        !           838:                        sprite[playersprite[snum]].picnum = SKELETON;
        !           839:                }
        !           840: 
        !           841:                if ((snum == screenpeek) && (screensize <= xdim))
        !           842:                {
        !           843:                        if (health[snum] > 0)
        !           844:                                sprintf(&tempbuf,"Health: %3d",health[snum]);
        !           845:                        else
        !           846:                                sprintf(&tempbuf,"YOU STINK!!");
        !           847: 
        !           848:                        printext((xdim>>1)-(strlen(tempbuf)<<2),ydim-24,tempbuf,ALPHABET,80);
        !           849:                }
        !           850:        }
        !           851:        return(health[snum] <= 0);      //You were just injured
        !           852: }
        !           853: 
        !           854: changescore(short snum, short deltascore)
        !           855: {
        !           856:        score[snum] += deltascore;
        !           857: 
        !           858:        if ((snum == screenpeek) && (screensize <= xdim))
        !           859:        {
        !           860:                sprintf(&tempbuf,"Score:%ld",score[snum]);
        !           861:                printext((xdim>>1)-(strlen(tempbuf)<<2),ydim-8,tempbuf,ALPHABET,80);
        !           862:        }
        !           863: }
        !           864: 
        !           865: prepareboard(char *daboardfilename)
        !           866: {
        !           867:        short startwall, endwall, dasector;
        !           868:        long i, j, k, s, dax, day, daz, dax2, day2;
        !           869: 
        !           870:        getmessageleng = 0;
        !           871:        typemessageleng = 0;
        !           872: 
        !           873:        randomseed = 17L;
        !           874: 
        !           875:                //Clear (do)animation's list
        !           876:        animatecnt = 0;
        !           877:        typemode = 0;
        !           878:        locselectedgun = 0;
        !           879:        locselectedgun2 = 0;
        !           880: 
        !           881:        if (loadboard(daboardfilename,&posx[0],&posy[0],&posz[0],&ang[0],&cursectnum[0]) == -1)
        !           882:        {
        !           883:                musicoff();
        !           884:                uninitmultiplayers();
        !           885:                uninittimer();
        !           886:                uninitkeys();
        !           887:                uninitengine();
        !           888:                uninitsb();
        !           889:                uninitgroupfile();
        !           890:                setvmode(0x3);        //Set back to text mode
        !           891:                printf("Board not found\n");
        !           892:                exit(0);
        !           893:        }
        !           894:        precache();
        !           895: 
        !           896:        for(i=0;i<MAXPLAYERS;i++)
        !           897:        {
        !           898:                posx[i] = posx[0];
        !           899:                posy[i] = posy[0];
        !           900:                posz[i] = posz[0];
        !           901:                ang[i] = ang[0];
        !           902:                cursectnum[i] = cursectnum[0];
        !           903:                ocursectnum[i] = cursectnum[0];
        !           904:                horiz[i] = 100;
        !           905:                lastchaingun[i] = 0;
        !           906:                health[i] = 100;
        !           907:                score[i] = 0L;
        !           908:                dimensionmode[i] = 3;
        !           909:                numbombs[i] = -1;
        !           910:                zoom[i] = 768L;
        !           911:                deaths[i] = 0L;
        !           912:                playersprite[i] = -1;
        !           913:                saywatchit[i] = -1;
        !           914:                screensize = xdim;
        !           915: 
        !           916:                oposx[i] = posx[0];
        !           917:                oposy[i] = posy[0];
        !           918:                oposz[i] = posz[0];
        !           919:                ohoriz[i] = horiz[0];
        !           920:                ozoom[i] = zoom[0];
        !           921:                oang[i] = ang[0];
        !           922:        }
        !           923: 
        !           924:        movefifoplc = 0; movefifoend = 0;
        !           925:        syncvalplc = 0L; othersyncvalplc = 0L;
        !           926:        syncvalend = 0L; othersyncvalend = 0L;
        !           927:        syncvalcnt = 0L; othersyncvalcnt = 0L;
        !           928: 
        !           929:        setup3dscreen();
        !           930: 
        !           931:        olocvel = 0; olocvel2 = 0;
        !           932:        olocsvel = 0; olocsvel2 = 0;
        !           933:        olocangvel = 0; olocangvel2 = 0;
        !           934:        olocbits = 0; olocbits2 = 0;
        !           935:        for(i=0;i<MAXPLAYERS;i++)
        !           936:        {
        !           937:                fsyncvel[i] = syncvel[i] = osyncvel[i] = 0;
        !           938:                fsyncsvel[i] = syncsvel[i] = osyncsvel[i] = 0;
        !           939:                fsyncangvel[i] = syncangvel[i] = osyncangvel[i] = 0;
        !           940:                fsyncbits[i] = syncbits[i] = osyncbits[i] = 0;
        !           941:        }
        !           942: 
        !           943:                //Scan sector tags
        !           944: 
        !           945:        for(i=0;i<MAXPLAYERS;i++)
        !           946:        {
        !           947:                waterfountainwall[i] = -1;
        !           948:                waterfountaincnt[i] = 0;
        !           949:        }
        !           950:        slimesoundcnt[i] = 0;
        !           951:        warpsectorcnt = 0;      //Make a list of warping sectors
        !           952:        xpanningsectorcnt = 0;  //Make a list of wall x-panning sectors
        !           953:        floorpanningcnt = 0;    //Make a list of slime sectors
        !           954:        dragsectorcnt = 0;      //Make a list of moving platforms
        !           955:        swingcnt = 0;           //Make a list of swinging doors
        !           956:        revolvecnt = 0;         //Make a list of revolving doors
        !           957:        subwaytrackcnt = 0;     //Make a list of subways
        !           958: 
        !           959:        for(i=0;i<numsectors;i++)
        !           960:        {
        !           961:                switch(sector[i].lotag)
        !           962:                {
        !           963:                        case 4:
        !           964:                                floorpanninglist[floorpanningcnt++] = i;
        !           965:                                break;
        !           966:                        case 10:
        !           967:                                warpsectorlist[warpsectorcnt++] = i;
        !           968:                                break;
        !           969:                        case 11:
        !           970:                                xpanningsectorlist[xpanningsectorcnt++] = i;
        !           971:                                break;
        !           972:                        case 12:
        !           973:                                dasector = i;
        !           974:                                dax = 0x7fffffff;
        !           975:                                day = 0x7fffffff;
        !           976:                                dax2 = 0x80000000;
        !           977:                                day2 = 0x80000000;
        !           978:                                startwall = sector[i].wallptr;
        !           979:                                endwall = startwall+sector[i].wallnum-1;
        !           980:                                for(j=startwall;j<=endwall;j++)
        !           981:                                {
        !           982:                                        if (wall[j].x < dax) dax = wall[j].x;
        !           983:                                        if (wall[j].y < day) day = wall[j].y;
        !           984:                                        if (wall[j].x > dax2) dax2 = wall[j].x;
        !           985:                                        if (wall[j].y > day2) day2 = wall[j].y;
        !           986:                                        if (wall[j].lotag == 3) k = j;
        !           987:                                }
        !           988:                                if (wall[k].x == dax) dragxdir[dragsectorcnt] = -16;
        !           989:                                if (wall[k].y == day) dragydir[dragsectorcnt] = -16;
        !           990:                                if (wall[k].x == dax2) dragxdir[dragsectorcnt] = 16;
        !           991:                                if (wall[k].y == day2) dragydir[dragsectorcnt] = 16;
        !           992: 
        !           993:                                dasector = wall[startwall].nextsector;
        !           994:                                dragx1[dragsectorcnt] = 0x7fffffff;
        !           995:                                dragy1[dragsectorcnt] = 0x7fffffff;
        !           996:                                dragx2[dragsectorcnt] = 0x80000000;
        !           997:                                dragy2[dragsectorcnt] = 0x80000000;
        !           998:                                startwall = sector[dasector].wallptr;
        !           999:                                endwall = startwall+sector[dasector].wallnum-1;
        !          1000:                                for(j=startwall;j<=endwall;j++)
        !          1001:                                {
        !          1002:                                        if (wall[j].x < dragx1[dragsectorcnt]) dragx1[dragsectorcnt] = wall[j].x;
        !          1003:                                        if (wall[j].y < dragy1[dragsectorcnt]) dragy1[dragsectorcnt] = wall[j].y;
        !          1004:                                        if (wall[j].x > dragx2[dragsectorcnt]) dragx2[dragsectorcnt] = wall[j].x;
        !          1005:                                        if (wall[j].y > dragy2[dragsectorcnt]) dragy2[dragsectorcnt] = wall[j].y;
        !          1006:                                }
        !          1007: 
        !          1008:                                dragx1[dragsectorcnt] += (wall[sector[i].wallptr].x-dax);
        !          1009:                                dragy1[dragsectorcnt] += (wall[sector[i].wallptr].y-day);
        !          1010:                                dragx2[dragsectorcnt] -= (dax2-wall[sector[i].wallptr].x);
        !          1011:                                dragy2[dragsectorcnt] -= (day2-wall[sector[i].wallptr].y);
        !          1012: 
        !          1013:                                dragfloorz[dragsectorcnt] = sector[i].floorz;
        !          1014: 
        !          1015:                                dragsectorlist[dragsectorcnt++] = i;
        !          1016:                                break;
        !          1017:                        case 13:
        !          1018:                                startwall = sector[i].wallptr;
        !          1019:                                endwall = startwall+sector[i].wallnum-1;
        !          1020:                                for(j=startwall;j<=endwall;j++)
        !          1021:                                {
        !          1022:                                        if (wall[j].lotag == 4)
        !          1023:                                        {
        !          1024:                                                k = wall[wall[wall[wall[j].point2].point2].point2].point2;
        !          1025:                                                if ((wall[j].x == wall[k].x) && (wall[j].y == wall[k].y))
        !          1026:                                                {     //Door opens counterclockwise
        !          1027:                                                        swingwall[swingcnt][0] = j;
        !          1028:                                                        swingwall[swingcnt][1] = wall[j].point2;
        !          1029:                                                        swingwall[swingcnt][2] = wall[wall[j].point2].point2;
        !          1030:                                                        swingwall[swingcnt][3] = wall[wall[wall[j].point2].point2].point2;
        !          1031:                                                        swingangopen[swingcnt] = 1536;
        !          1032:                                                        swingangclosed[swingcnt] = 0;
        !          1033:                                                        swingangopendir[swingcnt] = -1;
        !          1034:                                                }
        !          1035:                                                else
        !          1036:                                                {     //Door opens clockwise
        !          1037:                                                        swingwall[swingcnt][0] = wall[j].point2;
        !          1038:                                                        swingwall[swingcnt][1] = j;
        !          1039:                                                        swingwall[swingcnt][2] = lastwall(j);
        !          1040:                                                        swingwall[swingcnt][3] = lastwall(swingwall[swingcnt][2]);
        !          1041:                                                        swingwall[swingcnt][4] = lastwall(swingwall[swingcnt][3]);
        !          1042:                                                        swingangopen[swingcnt] = 512;
        !          1043:                                                        swingangclosed[swingcnt] = 0;
        !          1044:                                                        swingangopendir[swingcnt] = 1;
        !          1045:                                                }
        !          1046:                                                for(k=0;k<4;k++)
        !          1047:                                                {
        !          1048:                                                        swingx[swingcnt][k] = wall[swingwall[swingcnt][k]].x;
        !          1049:                                                        swingy[swingcnt][k] = wall[swingwall[swingcnt][k]].y;
        !          1050:                                                }
        !          1051: 
        !          1052:                                                swingsector[swingcnt] = i;
        !          1053:                                                swingang[swingcnt] = swingangclosed[swingcnt];
        !          1054:                                                swinganginc[swingcnt] = 0;
        !          1055:                                                swingcnt++;
        !          1056:                                        }
        !          1057:                                }
        !          1058:                                break;
        !          1059:                        case 14:
        !          1060:                                startwall = sector[i].wallptr;
        !          1061:                                endwall = startwall+sector[i].wallnum-1;
        !          1062:                                dax = 0L;
        !          1063:                                day = 0L;
        !          1064:                                for(j=startwall;j<=endwall;j++)
        !          1065:                                {
        !          1066:                                        dax += wall[j].x;
        !          1067:                                        day += wall[j].y;
        !          1068:                                }
        !          1069:                                revolvepivotx[revolvecnt] = dax / (endwall-startwall+1);
        !          1070:                                revolvepivoty[revolvecnt] = day / (endwall-startwall+1);
        !          1071: 
        !          1072:                                k = 0;
        !          1073:                                for(j=startwall;j<=endwall;j++)
        !          1074:                                {
        !          1075:                                        revolvex[revolvecnt][k] = wall[j].x;
        !          1076:                                        revolvey[revolvecnt][k] = wall[j].y;
        !          1077:                                        k++;
        !          1078:                                }
        !          1079:                                revolvesector[revolvecnt] = i;
        !          1080:                                revolveang[revolvecnt] = 0;
        !          1081: 
        !          1082:                                revolvecnt++;
        !          1083:                                break;
        !          1084:                        case 15:
        !          1085:                                subwaytracksector[subwaytrackcnt][0] = i;
        !          1086: 
        !          1087:                                subwaystopcnt[subwaytrackcnt] = 0;
        !          1088:                                dax = 0x7fffffff;
        !          1089:                                day = 0x7fffffff;
        !          1090:                                dax2 = 0x80000000;
        !          1091:                                day2 = 0x80000000;
        !          1092:                                startwall = sector[i].wallptr;
        !          1093:                                endwall = startwall+sector[i].wallnum-1;
        !          1094:                                for(j=startwall;j<=endwall;j++)
        !          1095:                                {
        !          1096:                                        if (wall[j].x < dax) dax = wall[j].x;
        !          1097:                                        if (wall[j].y < day) day = wall[j].y;
        !          1098:                                        if (wall[j].x > dax2) dax2 = wall[j].x;
        !          1099:                                        if (wall[j].y > day2) day2 = wall[j].y;
        !          1100:                                }
        !          1101:                                for(j=startwall;j<=endwall;j++)
        !          1102:                                {
        !          1103:                                        if (wall[j].lotag == 5)
        !          1104:                                        {
        !          1105:                                                if ((wall[j].x > dax) && (wall[j].y > day) && (wall[j].x < dax2) && (wall[j].y < day2))
        !          1106:                                                {
        !          1107:                                                        subwayx[subwaytrackcnt] = wall[j].x;
        !          1108:                                                }
        !          1109:                                                else
        !          1110:                                                {
        !          1111:                                                        subwaystop[subwaytrackcnt][subwaystopcnt[subwaytrackcnt]] = wall[j].x;
        !          1112:                                                        subwaystopcnt[subwaytrackcnt]++;
        !          1113:                                                }
        !          1114:                                        }
        !          1115:                                }
        !          1116: 
        !          1117:                                for(j=1;j<subwaystopcnt[subwaytrackcnt];j++)
        !          1118:                                        for(k=0;k<j;k++)
        !          1119:                                                if (subwaystop[subwaytrackcnt][j] < subwaystop[subwaytrackcnt][k])
        !          1120:                                                {
        !          1121:                                                        s = subwaystop[subwaytrackcnt][j];
        !          1122:                                                        subwaystop[subwaytrackcnt][j] = subwaystop[subwaytrackcnt][k];
        !          1123:                                                        subwaystop[subwaytrackcnt][k] = s;
        !          1124:                                                }
        !          1125: 
        !          1126:                                subwaygoalstop[subwaytrackcnt] = 0;
        !          1127:                                for(j=0;j<subwaystopcnt[subwaytrackcnt];j++)
        !          1128:                                        if (klabs(subwaystop[subwaytrackcnt][j]-subwayx[subwaytrackcnt]) < klabs(subwaystop[subwaytrackcnt][subwaygoalstop[subwaytrackcnt]]-subwayx[subwaytrackcnt]))
        !          1129:                                                subwaygoalstop[subwaytrackcnt] = j;
        !          1130: 
        !          1131:                                subwaytrackx1[subwaytrackcnt] = dax;
        !          1132:                                subwaytracky1[subwaytrackcnt] = day;
        !          1133:                                subwaytrackx2[subwaytrackcnt] = dax2;
        !          1134:                                subwaytracky2[subwaytrackcnt] = day2;
        !          1135: 
        !          1136:                                subwaynumsectors[subwaytrackcnt] = 1;
        !          1137:                                for(j=0;j<numsectors;j++)
        !          1138:                                        if (j != i)
        !          1139:                                        {
        !          1140:                                                startwall = sector[j].wallptr;
        !          1141:                                                if (wall[startwall].x > subwaytrackx1[subwaytrackcnt])
        !          1142:                                                        if (wall[startwall].y > subwaytracky1[subwaytrackcnt])
        !          1143:                                                                if (wall[startwall].x < subwaytrackx2[subwaytrackcnt])
        !          1144:                                                                        if (wall[startwall].y < subwaytracky2[subwaytrackcnt])
        !          1145:                                                                        {
        !          1146:                                                                                if (sector[j].lotag == 16)
        !          1147:                                                                                        sector[j].lotag = 17;   //Make special subway door
        !          1148: 
        !          1149:                                                                                if (sector[j].floorz != sector[i].floorz)
        !          1150:                                                                                {
        !          1151:                                                                                        sector[j].ceilingstat |= 64;
        !          1152:                                                                                        sector[j].floorstat |= 64;
        !          1153:                                                                                }
        !          1154:                                                                                subwaytracksector[subwaytrackcnt][subwaynumsectors[subwaytrackcnt]] = j;
        !          1155:                                                                                subwaynumsectors[subwaytrackcnt]++;
        !          1156:                                                                        }
        !          1157:                                        }
        !          1158: 
        !          1159:                                subwayvel[subwaytrackcnt] = 64;
        !          1160:                                subwaypausetime[subwaytrackcnt] = 720;
        !          1161:                                subwaytrackcnt++;
        !          1162:                                break;
        !          1163:                }
        !          1164:        }
        !          1165: 
        !          1166:                //Scan wall tags
        !          1167: 
        !          1168:        ypanningwallcnt = 0;
        !          1169:        for(i=0;i<numwalls;i++)
        !          1170:        {
        !          1171:                if (wall[i].lotag == 1) ypanningwalllist[ypanningwallcnt++] = i;
        !          1172:        }
        !          1173: 
        !          1174:                //Scan sprite tags&picnum's
        !          1175: 
        !          1176:        rotatespritecnt = 0;
        !          1177:        for(i=0;i<MAXSPRITES;i++)
        !          1178:        {
        !          1179:                if (sprite[i].lotag == 3) rotatespritelist[rotatespritecnt++] = i;
        !          1180: 
        !          1181:                if (sprite[i].statnum < MAXSTATUS)    //That is, if sprite exists
        !          1182:                        switch(sprite[i].picnum)
        !          1183:                        {
        !          1184:                                case BROWNMONSTER:              //All cases here put the sprite
        !          1185:                                        if ((sprite[i].cstat&128) == 0)
        !          1186:                                        {
        !          1187:                                                sprite[i].z -= ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1);
        !          1188:                                                sprite[i].cstat |= 128;
        !          1189:                                        }
        !          1190:                                        sprite[i].clipdist = mulscale(sprite[i].xrepeat,tilesizx[sprite[i].picnum],7);
        !          1191:                                case DOOMGUY:                   //on waiting for you (list 2)
        !          1192:                                        if (sprite[i].statnum != 1) changespritestat(i,2);
        !          1193:                                        sprite[i].lotag = 100;
        !          1194:                                case AL:
        !          1195:                                case EVILAL:
        !          1196:                                        sprite[i].cstat |= 0x101;    //Set the hitscan sensitivity bit
        !          1197:                        }
        !          1198:        }
        !          1199: 
        !          1200:                //Map starts out completed
        !          1201:        for(i=0;i<(MAXSECTORS>>3);i++) show2dsector[i] = 0xff;
        !          1202:        for(i=0;i<(MAXWALLS>>3);i++) show2dwall[i] = 0xff;
        !          1203:        for(i=0;i<(MAXSPRITES>>3);i++) show2dsprite[i] = 0xff;
        !          1204: 
        !          1205:                //Map starts out blank; you map out what you see in 3D mode
        !          1206:        //automapping = 1;
        !          1207: 
        !          1208:        lockclock = 0;
        !          1209:        ototalclock = 0;
        !          1210:        gotlastpacketclock = 0;
        !          1211:        masterslavetexttime = 0;
        !          1212: 
        !          1213:        screensize = xdim;
        !          1214:        dax = (xdim>>1)-(screensize>>1);
        !          1215:        dax2 = dax+screensize-1;
        !          1216:        day = ((ydim-32)>>1)-(((screensize*(ydim-32))/xdim)>>1);
        !          1217:        day2 = day + ((screensize*(ydim-32))/xdim)-1;
        !          1218:        setview(dax,day>>detailmode,dax2,day2>>detailmode);
        !          1219: }
        !          1220: 
        !          1221: 
        !          1222: checktouchsprite(short snum, short sectnum)
        !          1223: {
        !          1224:        long i, nexti;
        !          1225: 
        !          1226:        if ((sectnum < 0) || (sectnum >= numsectors)) return;
        !          1227: 
        !          1228:        for(i=headspritesect[sectnum];i>=0;i=nexti)
        !          1229:        {
        !          1230:                nexti = nextspritesect[i];
        !          1231:                if ((klabs(posx[snum]-sprite[i].x)+klabs(posy[snum]-sprite[i].y) < 512) && (klabs((posz[snum]>>8)-((sprite[i].z>>8)-(tilesizy[sprite[i].picnum]>>1))) <= 40))
        !          1232:                {
        !          1233:                        switch(sprite[i].picnum)
        !          1234:                        {
        !          1235:                                case COINSTACK:
        !          1236:                                        wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0);
        !          1237:                                        changescore(snum,1000);
        !          1238:                                        changehealth(snum,25);
        !          1239:                                        deletesprite((short)i);
        !          1240:                                        break;
        !          1241:                                case GIFTBOX:
        !          1242:                                        wsayfollow("getstuff.wav",4096L+(krand()&127)-64,208L,&sprite[i].x,&sprite[i].y,0);
        !          1243:                                        changescore(snum,1000);
        !          1244:                                        changehealth(snum,10);
        !          1245:                                        deletesprite((short)i);
        !          1246:                                        break;
        !          1247:                                case COIN:
        !          1248:                                        wsayfollow("getstuff.wav",4096L+(krand()&127)-64,192L,&sprite[i].x,&sprite[i].y,0);
        !          1249:                                        changescore(snum,100);
        !          1250:                                        changehealth(snum,5);
        !          1251:                                        deletesprite((short)i);
        !          1252:                                        break;
        !          1253:                                case DIAMONDS:
        !          1254:                                        wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0);
        !          1255:                                        changescore(snum,500);
        !          1256:                                        changehealth(snum,15);
        !          1257:                                        deletesprite((short)i);
        !          1258:                                        break;
        !          1259:                                case CANON:
        !          1260:                                        if (numbombs[snum] == -1)
        !          1261:                                        {
        !          1262:                                                wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0);
        !          1263:                                                changescore(snum,1000);
        !          1264:                                                if (snum == myconnectindex) keystatus[4] = 1;
        !          1265:                                                numbombs[snum] = 32767;
        !          1266:                                        }
        !          1267:                                        break;
        !          1268:                        }
        !          1269:                }
        !          1270:        }
        !          1271: }
        !          1272: 
        !          1273: shootgun(short snum, long x, long y, long z,
        !          1274:                        short daang, long dahoriz, short dasectnum, char guntype)
        !          1275: {
        !          1276:        short hitsect, hitwall, hitsprite, daang2;
        !          1277:        long i, j, daz2, hitx, hity, hitz;
        !          1278: 
        !          1279:        switch(guntype)
        !          1280:        {
        !          1281:                case 0:    //Shoot silver sphere bullet
        !          1282:                        spawnsprite(j,x,y,z,1+128,0,0,16,64,64,0,0,BULLET,daang,
        !          1283:                                                  sintable[(daang+512)&2047]>>5,sintable[daang&2047]>>5,
        !          1284:                                                  (100-dahoriz)<<6,snum+4096,dasectnum,6,0,0,0);
        !          1285:                        wsayfollow("shoot2.wav",4096L+(krand()&127)-64,184L,&sprite[j].x,&sprite[j].y,1);
        !          1286:                        break;
        !          1287:                case 1:    //Shoot chain gun
        !          1288:                        daang2 = ((daang + 2048 + (krand()&31)-16)&2047);
        !          1289:                        daz2 = ((100-dahoriz)*2000) + ((krand()-32768)>>1);
        !          1290: 
        !          1291:                        hitscan(x,y,z,dasectnum,                   //Start position
        !          1292:                                sintable[(daang2+2560)&2047],           //X vector of 3D ang
        !          1293:                                sintable[(daang2+2048)&2047],           //Y vector of 3D ang
        !          1294:                                daz2,                                   //Z vector of 3D ang
        !          1295:                                &hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz);
        !          1296: 
        !          1297:                        if (wall[hitwall].picnum == KENPICTURE)
        !          1298:                        {
        !          1299:                                if (waloff[4095] != 0) wall[hitwall].picnum = 4095;
        !          1300:                                wsayfollow("hello.wav",4096L+(krand()&127)-64,256L,&wall[hitwall].x,&wall[hitwall].y,0);
        !          1301:                        }
        !          1302:                        else if (((hitwall < 0) && (hitsprite < 0) && (hitz >= z) && (sector[hitsect].floorpicnum == SLIME)) || ((hitwall >= 0) && (wall[hitwall].picnum == SLIME)))
        !          1303:                        {    //If you shoot slime, make a splash
        !          1304:                                wsayfollow("splash.wav",4096L+(krand()&511)-256,256L,&hitx,&hity,0);
        !          1305:                                spawnsprite(j,hitx,hity,hitz,2,0,0,32,64,64,0,0,SPLASH,daang,
        !          1306:                                        0,0,0,snum+4096,hitsect,4,63,0,0); //63=time left for splash
        !          1307:                        }
        !          1308:                        else
        !          1309:                        {
        !          1310:                                wsayfollow("shoot.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0);
        !          1311: 
        !          1312:                                if ((hitsprite >= 0) && (sprite[hitsprite].statnum < MAXSTATUS))
        !          1313:                                        switch(sprite[hitsprite].picnum)
        !          1314:                                        {
        !          1315:                                                case BROWNMONSTER:
        !          1316:                                                        if (sprite[hitsprite].lotag > 0) sprite[hitsprite].lotag -= 10;
        !          1317:                                                        if (sprite[hitsprite].lotag > 0)
        !          1318:                                                        {
        !          1319:                                                                wsayfollow("hurt.wav",4096L+(krand()&511)-256,256L,&hitx,&hity,0);
        !          1320:                                                                if (sprite[hitsprite].lotag <= 25)
        !          1321:                                                                        sprite[hitsprite].cstat |= 2;
        !          1322:                                                        }
        !          1323:                                                        else
        !          1324:                                                        {
        !          1325:                                                                wsayfollow("blowup.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0);
        !          1326:                                                                sprite[hitsprite].z += ((tilesizy[sprite[hitsprite].picnum]*sprite[hitsprite].yrepeat)<<1);
        !          1327:                                                                sprite[hitsprite].picnum = GIFTBOX;
        !          1328:                                                                sprite[hitsprite].cstat &= ~0x83;    //Should not clip, foot-z
        !          1329:                                                                changespritestat(hitsprite,0);
        !          1330:                                                                changescore(snum,200);
        !          1331: 
        !          1332:                                                                spawnsprite(j,hitx,hity,hitz+(32<<8),0,-4,0,32,64,64,
        !          1333:                                                                        0,0,EXPLOSION,daang,0,0,0,snum+4096,
        !          1334:                                                                        hitsect,5,31,0,0);
        !          1335:                                                        }
        !          1336:                                                        break;
        !          1337:                                                case EVILAL:
        !          1338:                                                        wsayfollow("blowup.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0);
        !          1339:                                                        sprite[hitsprite].picnum = EVILALGRAVE;
        !          1340:                                                        sprite[hitsprite].cstat = 0;
        !          1341:                                                        sprite[hitsprite].xrepeat = (krand()&63)+16;
        !          1342:                                                        sprite[hitsprite].yrepeat = sprite[hitsprite].xrepeat;
        !          1343:                                                        changespritestat(hitsprite,0);
        !          1344: 
        !          1345:                                                        spawnsprite(j,hitx,hity,hitz+(32<<8),0,-4,0,32,64,64,0,
        !          1346:                                                                0,EXPLOSION,daang,0,0,0,snum+4096,hitsect,5,31,0,0);
        !          1347:                                                                 //31=time left for explosion
        !          1348: 
        !          1349:                                                        break;
        !          1350:                                                case DOOMGUY:
        !          1351:                                                        for(j=connecthead;j>=0;j=connectpoint2[j])
        !          1352:                                                                if (playersprite[j] == hitsprite)
        !          1353:                                                                {
        !          1354:                                                                        wsayfollow("ouch.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0);
        !          1355:                                                                        changehealth(j,-10);
        !          1356:                                                                        break;
        !          1357:                                                                }
        !          1358:                                                        break;
        !          1359:                                        }
        !          1360: 
        !          1361:                                spawnsprite(j,hitx,hity,hitz+(8<<8),2,-4,0,32,16,16,0,0,
        !          1362:                                        EXPLOSION,daang,0,0,0,snum+4096,hitsect,3,63,0,0);
        !          1363: 
        !          1364:                                        //Sprite starts out with center exactly on wall.
        !          1365:                                        //This moves it back enough to see it at all angles.
        !          1366:                                movesprite((short)j,-(((long)sintable[(512+daang)&2047]*TICSPERFRAME)<<4),-(((long)sintable[daang]*TICSPERFRAME)<<4),0L,4L<<8,4L<<8,1);
        !          1367:                        }
        !          1368:                        break;
        !          1369:                case 2:    //Shoot bomb
        !          1370:                  spawnsprite(j,x,y,z,128,0,0,12,16,16,0,0,BOMB,daang,
        !          1371:                          sintable[(daang+2560)&2047]>>6,sintable[(daang+2048)&2047]>>6,
        !          1372:                          (80-dahoriz)<<6,snum+4096,dasectnum,6,0,0,0);
        !          1373: 
        !          1374:                        wsayfollow("shoot3.wav",4096L+(krand()&127)-64,256L,&sprite[j].x,&sprite[j].y,1);
        !          1375:                        break;
        !          1376:        }
        !          1377: }
        !          1378: 
        !          1379: analyzesprites(long dax, long day)
        !          1380: {
        !          1381:        long i, j, k;
        !          1382:        point3d *ospr;
        !          1383:        spritetype *tspr;
        !          1384: 
        !          1385:                //This function is called between drawrooms() and drawmasks()
        !          1386:                //It has a list of possible sprites that may be drawn on this frame
        !          1387: 
        !          1388:        for(i=0,tspr=&tsprite[0];i<spritesortcnt;i++,tspr++)
        !          1389:        {
        !          1390:                switch(tspr->picnum)
        !          1391:                {
        !          1392:                        case DOOMGUY:
        !          1393:                                        //Get which of the 8 angles of the sprite to draw (0-7)
        !          1394:                                        //k ranges from 0-7
        !          1395:                                k = getangle(tspr->x-dax,tspr->y-day);
        !          1396:                                k = (((tspr->ang+3072+128-k)&2047)>>8)&7;
        !          1397:                                        //This guy has only 5 pictures for 8 angles (3 are x-flipped)
        !          1398:                                if (k <= 4)
        !          1399:                                {
        !          1400:                                        tspr->picnum += (k<<2);
        !          1401:                                        tspr->cstat &= ~4;   //clear x-flipping bit
        !          1402:                                }
        !          1403:                                else
        !          1404:                                {
        !          1405:                                        tspr->picnum += ((8-k)<<2);
        !          1406:                                        tspr->cstat |= 4;    //set x-flipping bit
        !          1407:                                }
        !          1408:                                break;
        !          1409:                }
        !          1410: 
        !          1411:                k = tspr->statnum;
        !          1412:                if ((k >= 1) && (k <= 8) && (k != 2))  //Interpolate moving sprite
        !          1413:                {
        !          1414:                        ospr = &osprite[tspr->owner];
        !          1415:                        k = tspr->x-ospr->x; tspr->x = ospr->x;
        !          1416:                        if (k != 0) tspr->x += mulscale(k,smoothratio,16);
        !          1417:                        k = tspr->y-ospr->y; tspr->y = ospr->y;
        !          1418:                        if (k != 0) tspr->y += mulscale(k,smoothratio,16);
        !          1419:                        k = tspr->z-ospr->z; tspr->z = ospr->z;
        !          1420:                        if (k != 0) tspr->z += mulscale(k,smoothratio,16);
        !          1421:                }
        !          1422:        }
        !          1423: }
        !          1424: 
        !          1425: tagcode()
        !          1426: {
        !          1427:        long i, nexti, j, k, l, s, dax, day, daz, dax2, day2, cnt, good;
        !          1428:        short startwall, endwall, dasector, p, oldang;
        !          1429: 
        !          1430:        for(p=connecthead;p>=0;p=connectpoint2[p])
        !          1431:        {
        !          1432:                if (sector[cursectnum[p]].lotag == 1)
        !          1433:                {
        !          1434:                        for(i=0;i<numsectors;i++)
        !          1435:                                if (sector[i].hitag == sector[cursectnum[p]].hitag)
        !          1436:                                        if (sector[i].lotag != 1)
        !          1437:                                                operatesector(i);
        !          1438:                        i = headspritestat[0];
        !          1439:                        while (i != -1)
        !          1440:                        {
        !          1441:                                nexti = nextspritestat[i];
        !          1442:                                if (sprite[i].hitag == sector[cursectnum[p]].hitag)
        !          1443:                                        operatesprite(i);
        !          1444:                                i = nexti;
        !          1445:                        }
        !          1446: 
        !          1447:                        sector[cursectnum[p]].lotag = 0;
        !          1448:                        sector[cursectnum[p]].hitag = 0;
        !          1449:                }
        !          1450:                if ((sector[cursectnum[p]].lotag == 2) && (cursectnum[p] != ocursectnum[p]))
        !          1451:                {
        !          1452:                        for(i=0;i<numsectors;i++)
        !          1453:                                if (sector[i].hitag == sector[cursectnum[p]].hitag)
        !          1454:                                        if (sector[i].lotag != 1)
        !          1455:                                                operatesector(i);
        !          1456:                        i = headspritestat[0];
        !          1457:                        while (i != -1)
        !          1458:                        {
        !          1459:                                nexti = nextspritestat[i];
        !          1460:                                if (sprite[i].hitag == sector[cursectnum[p]].hitag)
        !          1461:                                        operatesprite(i);
        !          1462:                                i = nexti;
        !          1463:                        }
        !          1464:                }
        !          1465:        }
        !          1466: 
        !          1467:        for(i=0;i<warpsectorcnt;i++)
        !          1468:        {
        !          1469:                dasector = warpsectorlist[i];
        !          1470:                j = ((lockclock&127)>>2);
        !          1471:                if (j >= 16) j = 31-j;
        !          1472:                {
        !          1473:                        sector[dasector].ceilingshade = j;
        !          1474:                        sector[dasector].floorshade = j;
        !          1475:                        startwall = sector[dasector].wallptr;
        !          1476:                        endwall = startwall+sector[dasector].wallnum-1;
        !          1477:                        for(s=startwall;s<=endwall;s++)
        !          1478:                                wall[s].shade = j;
        !          1479:                }
        !          1480:        }
        !          1481: 
        !          1482:        for(p=connecthead;p>=0;p=connectpoint2[p])
        !          1483:                if (sector[cursectnum[p]].lotag == 10)  //warp sector
        !          1484:                {
        !          1485:                        if (cursectnum[p] != ocursectnum[p])
        !          1486:                        {
        !          1487:                                warpsprite(playersprite[p]);
        !          1488:                                posx[p] = sprite[playersprite[p]].x;
        !          1489:                                posy[p] = sprite[playersprite[p]].y;
        !          1490:                                posz[p] = sprite[playersprite[p]].z;
        !          1491:                                ang[p] = sprite[playersprite[p]].ang;
        !          1492:                                cursectnum[p] = sprite[playersprite[p]].sectnum;
        !          1493: 
        !          1494:                                sprite[playersprite[p]].z += (32<<8);
        !          1495: 
        !          1496:                                //warp(&posx[p],&posy[p],&posz[p],&ang[p],&cursectnum[p]);
        !          1497:                                        //Update sprite representation of player
        !          1498:                                //setsprite(playersprite[p],posx[p],posy[p],posz[p]+(32<<8));
        !          1499:                                //sprite[playersprite[p]].ang = ang[p];
        !          1500:                        }
        !          1501:                }
        !          1502: 
        !          1503:        for(i=0;i<xpanningsectorcnt;i++)   //animate wall x-panning sectors
        !          1504:        {
        !          1505:                dasector = xpanningsectorlist[i];
        !          1506: 
        !          1507:                startwall = sector[dasector].wallptr;
        !          1508:                endwall = startwall+sector[dasector].wallnum-1;
        !          1509:                for(s=startwall;s<=endwall;s++)
        !          1510:                        wall[s].xpanning = ((lockclock>>2)&255);
        !          1511:        }
        !          1512: 
        !          1513:        for(i=0;i<ypanningwallcnt;i++)
        !          1514:                wall[ypanningwalllist[i]].ypanning = ~(lockclock&255);
        !          1515: 
        !          1516:        for(i=0;i<rotatespritecnt;i++)
        !          1517:        {
        !          1518:                sprite[rotatespritelist[i]].ang += (TICSPERFRAME<<2);
        !          1519:                sprite[rotatespritelist[i]].ang &= 2047;
        !          1520:        }
        !          1521: 
        !          1522:        for(i=0;i<floorpanningcnt;i++)   //animate floor of slime sectors
        !          1523:        {
        !          1524:                sector[floorpanninglist[i]].floorxpanning = ((lockclock>>2)&255);
        !          1525:                sector[floorpanninglist[i]].floorypanning = ((lockclock>>2)&255);
        !          1526:        }
        !          1527: 
        !          1528:        for(i=0;i<dragsectorcnt;i++)
        !          1529:        {
        !          1530:                dasector = dragsectorlist[i];
        !          1531: 
        !          1532:                startwall = sector[dasector].wallptr;
        !          1533:                endwall = startwall+sector[dasector].wallnum-1;
        !          1534: 
        !          1535:                if (wall[startwall].x+dragxdir[i] < dragx1[i]) dragxdir[i] = 16;
        !          1536:                if (wall[startwall].y+dragydir[i] < dragy1[i]) dragydir[i] = 16;
        !          1537:                if (wall[startwall].x+dragxdir[i] > dragx2[i]) dragxdir[i] = -16;
        !          1538:                if (wall[startwall].y+dragydir[i] > dragy2[i]) dragydir[i] = -16;
        !          1539: 
        !          1540:                for(j=startwall;j<=endwall;j++)
        !          1541:                        dragpoint(j,wall[j].x+dragxdir[i],wall[j].y+dragydir[i]);
        !          1542:                j = sector[dasector].floorz;
        !          1543:                sector[dasector].floorz = dragfloorz[i]+(sintable[(lockclock<<4)&2047]>>3);
        !          1544: 
        !          1545:                for(p=connecthead;p>=0;p=connectpoint2[p])
        !          1546:                        if (cursectnum[p] == dasector)
        !          1547:                        {
        !          1548:                                posx[p] += dragxdir[i];
        !          1549:                                posy[p] += dragydir[i];
        !          1550:                                posz[p] += (sector[dasector].floorz-j);
        !          1551: 
        !          1552:                                        //Update sprite representation of player
        !          1553:                                setsprite(playersprite[p],posx[p],posy[p],posz[p]+(32<<8));
        !          1554:                                sprite[playersprite[p]].ang = ang[p];
        !          1555:                                frameinterpolate = 0;
        !          1556:                        }
        !          1557:        }
        !          1558: 
        !          1559:        for(i=0;i<swingcnt;i++)
        !          1560:        {
        !          1561:                if (swinganginc[i] != 0)
        !          1562:                {
        !          1563:                        oldang = swingang[i];
        !          1564:                        for(j=0;j<(TICSPERFRAME<<2);j++)
        !          1565:                        {
        !          1566:                                swingang[i] = ((swingang[i]+2048+swinganginc[i])&2047);
        !          1567:                                if (swingang[i] == swingangclosed[i])
        !          1568:                                {
        !          1569:                                        wsayfollow("closdoor.wav",4096L+(krand()&511)-256,256L,&swingx[i][0],&swingy[i][0],0);
        !          1570:                                        swinganginc[i] = 0;
        !          1571:                                }
        !          1572:                                if (swingang[i] == swingangopen[i]) swinganginc[i] = 0;
        !          1573:                        }
        !          1574:                        for(k=1;k<=3;k++)
        !          1575:                                rotatepoint(swingx[i][0],swingy[i][0],swingx[i][k],swingy[i][k],swingang[i],&wall[swingwall[i][k]].x,&wall[swingwall[i][k]].y);
        !          1576: 
        !          1577:                        if (swinganginc[i] != 0)
        !          1578:                        {
        !          1579:                                for(p=connecthead;p>=0;p=connectpoint2[p])
        !          1580:                                        if ((cursectnum[p] == swingsector[i]) || (testneighborsectors(cursectnum[p],swingsector[i]) == 1))
        !          1581:                                        {
        !          1582:                                                cnt = 256;
        !          1583:                                                do
        !          1584:                                                {
        !          1585:                                                        good = 1;
        !          1586: 
        !          1587:                                                                //swingangopendir is -1 if forwards, 1 is backwards
        !          1588:                                                        l = (swingangopendir[i] > 0);
        !          1589:                                                        for(k=l+3;k>=l;k--)
        !          1590:                                                                if (clipinsidebox(posx[p],posy[p],swingwall[i][k],128L) != 0)
        !          1591:                                                                {
        !          1592:                                                                        good = 0;
        !          1593:                                                                        break;
        !          1594:                                                                }
        !          1595:                                                        if (good == 0)
        !          1596:                                                        {
        !          1597:                                                                if (cnt == 256)
        !          1598:                                                                {
        !          1599:                                                                        swinganginc[i] = -swinganginc[i];
        !          1600:                                                                        swingang[i] = oldang;
        !          1601:                                                                }
        !          1602:                                                                else
        !          1603:                                                                {
        !          1604:                                                                        swingang[i] = ((swingang[i]+2048-swinganginc[i])&2047);
        !          1605:                                                                }
        !          1606:                                                                for(k=1;k<=3;k++)
        !          1607:                                                                        rotatepoint(swingx[i][0],swingy[i][0],swingx[i][k],swingy[i][k],swingang[i],&wall[swingwall[i][k]].x,&wall[swingwall[i][k]].y);
        !          1608:                                                                if (swingang[i] == swingangclosed[i])
        !          1609:                                                                {
        !          1610:                                                                        wsayfollow("closdoor.wav",4096L+(krand()&511)-256,256L,&swingx[i][0],&swingy[i][0],0);
        !          1611:                                                                        swinganginc[i] = 0;
        !          1612:                                                                        break;
        !          1613:                                                                }
        !          1614:                                                                if (swingang[i] == swingangopen[i])
        !          1615:                                                                {
        !          1616:                                                                        swinganginc[i] = 0;
        !          1617:                                                                        break;
        !          1618:                                                                }
        !          1619:                                                                cnt--;
        !          1620:                                                        }
        !          1621:                                                } while ((good == 0) && (cnt > 0));
        !          1622:                                        }
        !          1623:                        }
        !          1624:                }
        !          1625:        }
        !          1626: 
        !          1627:        for(i=0;i<revolvecnt;i++)
        !          1628:        {
        !          1629:                startwall = sector[revolvesector[i]].wallptr;
        !          1630:                endwall = startwall + sector[revolvesector[i]].wallnum - 1;
        !          1631: 
        !          1632:                revolveang[i] = ((revolveang[i]+2048-(TICSPERFRAME<<2))&2047);
        !          1633:                for(k=startwall;k<=endwall;k++)
        !          1634:                {
        !          1635:                        rotatepoint(revolvepivotx[i],revolvepivoty[i],revolvex[i][k-startwall],revolvey[i][k-startwall],revolveang[i],&dax,&day);
        !          1636:                        dragpoint(k,dax,day);
        !          1637:                }
        !          1638:        }
        !          1639: 
        !          1640:        for(i=0;i<subwaytrackcnt;i++)
        !          1641:        {
        !          1642:                dasector = subwaytracksector[i][0];
        !          1643:                startwall = sector[dasector].wallptr;
        !          1644:                endwall = startwall+sector[dasector].wallnum-1;
        !          1645:                for(k=startwall;k<=endwall;k++)
        !          1646:                {
        !          1647:                        if (wall[k].x > subwaytrackx1[i])
        !          1648:                                if (wall[k].y > subwaytracky1[i])
        !          1649:                                        if (wall[k].x < subwaytrackx2[i])
        !          1650:                                                if (wall[k].y < subwaytracky2[i])
        !          1651:                                                        wall[k].x += (subwayvel[i]&0xfffffffc);
        !          1652:                }
        !          1653: 
        !          1654:                for(j=1;j<subwaynumsectors[i];j++)
        !          1655:                {
        !          1656:                        dasector = subwaytracksector[i][j];
        !          1657: 
        !          1658:                        startwall = sector[dasector].wallptr;
        !          1659:                        endwall = startwall+sector[dasector].wallnum-1;
        !          1660:                        for(k=startwall;k<=endwall;k++)
        !          1661:                                wall[k].x += (subwayvel[i]&0xfffffffc);
        !          1662: 
        !          1663:                        s = headspritesect[dasector];
        !          1664:                        while (s != -1)
        !          1665:                        {
        !          1666:                                k = nextspritesect[s];
        !          1667:                                sprite[s].x += (subwayvel[i]&0xfffffffc);
        !          1668:                                s = k;
        !          1669:                        }
        !          1670:                }
        !          1671: 
        !          1672:                for(p=connecthead;p>=0;p=connectpoint2[p])
        !          1673:                        if (cursectnum[p] != subwaytracksector[i][0])
        !          1674:                                if (sector[cursectnum[p]].floorz != sector[subwaytracksector[i][0]].floorz)
        !          1675:                                        if (posx[p] > subwaytrackx1[i])
        !          1676:                                                if (posy[p] > subwaytracky1[i])
        !          1677:                                                        if (posx[p] < subwaytrackx2[i])
        !          1678:                                                                if (posy[p] < subwaytracky2[i])
        !          1679:                                                                {
        !          1680:                                                                        posx[p] += (subwayvel[i]&0xfffffffc);
        !          1681: 
        !          1682:                                                                                //Update sprite representation of player
        !          1683:                                                                        setsprite(playersprite[p],posx[p],posy[p],posz[p]+(32<<8));
        !          1684:                                                                        sprite[playersprite[p]].ang = ang[p];
        !          1685:                                                                        frameinterpolate = 0;
        !          1686:                                                                }
        !          1687: 
        !          1688:                subwayx[i] += (subwayvel[i]&0xfffffffc);
        !          1689: 
        !          1690:                k = subwaystop[i][subwaygoalstop[i]] - subwayx[i];
        !          1691:                if (k > 0)
        !          1692:                {
        !          1693:                        if (k > 2048)
        !          1694:                        {
        !          1695:                                if (subwayvel[i] < 128) subwayvel[i]++;
        !          1696:                        }
        !          1697:                        else
        !          1698:                                subwayvel[i] = (k>>4)+1;
        !          1699:                }
        !          1700:                else if (k < 0)
        !          1701:                {
        !          1702:                        if (k < -2048)
        !          1703:                        {
        !          1704:                                if (subwayvel[i] > -128) subwayvel[i]--;
        !          1705:                        }
        !          1706:                        else
        !          1707:                                subwayvel[i] = ((k>>4)-1);
        !          1708:                }
        !          1709: 
        !          1710:                if (((subwayvel[i]>>2) == 0) && (klabs(k) < 2048))
        !          1711:                {
        !          1712:                        if (subwaypausetime[i] == 720)
        !          1713:                        {
        !          1714:                                for(j=1;j<subwaynumsectors[i];j++)   //Open all subway doors
        !          1715:                                {
        !          1716:                                        dasector = subwaytracksector[i][j];
        !          1717:                                        if (sector[dasector].lotag == 17)
        !          1718:                                        {
        !          1719:                                                sector[dasector].lotag = 16;
        !          1720:                                                operatesector(dasector);
        !          1721:                                                sector[dasector].lotag = 17;
        !          1722:                                        }
        !          1723:                                }
        !          1724:                        }
        !          1725:                        if ((subwaypausetime[i] >= 120) && (subwaypausetime[i]-TICSPERFRAME < 120))
        !          1726:                        {
        !          1727:                                for(j=1;j<subwaynumsectors[i];j++)   //Close all subway doors
        !          1728:                                {
        !          1729:                                        dasector = subwaytracksector[i][j];
        !          1730:                                        if (sector[dasector].lotag == 17)
        !          1731:                                        {
        !          1732:                                                sector[dasector].lotag = 16;
        !          1733:                                                operatesector(dasector);
        !          1734:                                                sector[dasector].lotag = 17;
        !          1735:                                        }
        !          1736:                                }
        !          1737:                        }
        !          1738: 
        !          1739:                        subwaypausetime[i] -= TICSPERFRAME;
        !          1740:                        if (subwaypausetime[i] < 0)
        !          1741:                        {
        !          1742:                                subwaypausetime[i] = 720;
        !          1743:                                if (subwayvel[i] < 0)
        !          1744:                                {
        !          1745:                                        subwaygoalstop[i]--;
        !          1746:                                        if (subwaygoalstop[i] < 0)
        !          1747:                                                subwaygoalstop[i] = 1;
        !          1748:                                }
        !          1749:                                if (subwayvel[i] > 0)
        !          1750:                                {
        !          1751:                                        subwaygoalstop[i]++;
        !          1752:                                        if (subwaygoalstop[i] >= subwaystopcnt[i])
        !          1753:                                                subwaygoalstop[i] = subwaystopcnt[i]-2;
        !          1754:                                }
        !          1755:                        }
        !          1756:                }
        !          1757:        }
        !          1758: }
        !          1759: 
        !          1760: statuslistcode()
        !          1761: {
        !          1762:        short p, target, hitobject, daang, osectnum, movestat;
        !          1763:        long i, nexti, j, nextj, k, l, dax, day, daz, dist, ox, oy, mindist;
        !          1764: 
        !          1765:        i = headspritestat[1];     //Go through active monster sprites
        !          1766:        while (i != -1)
        !          1767:        {
        !          1768:                nexti = nextspritestat[i];
        !          1769: 
        !          1770:                        //Choose a target player
        !          1771:                mindist = 0x7fffffff; target = connecthead;
        !          1772:                for(p=connecthead;p>=0;p=connectpoint2[p])
        !          1773:                {
        !          1774:                        dist = klabs(sprite[i].x-posx[p])+klabs(sprite[i].y-posy[p]);
        !          1775:                        if (dist < mindist) mindist = dist, target = p;
        !          1776:                }
        !          1777: 
        !          1778:                switch(sprite[i].picnum)
        !          1779:                {
        !          1780:                        case BROWNMONSTER:
        !          1781: 
        !          1782:                                k = (krand()&63);  //Only get random number once
        !          1783:                                                                                 //Who cares if the monster won't shoot and
        !          1784:                                                                                 //change direction at the same time
        !          1785: 
        !          1786:                                        //brown monster decides to shoot bullet
        !          1787:                                if ((sprite[i].lotag > 25) && (k == 0))
        !          1788:                                        if (cansee(posx[target],posy[target],posz[target],cursectnum[target],sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum) == 1)
        !          1789:                                        {
        !          1790:                                                wsayfollow("zipguns.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1);
        !          1791: 
        !          1792:                                                spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z,128,0,0,
        !          1793:                                                        16,64,64,0,0,BULLET,
        !          1794:                                                        (getangle(posx[target]-sprite[j].x,
        !          1795:                                                                                 posy[target]-sprite[j].y)+(krand()&15)-8)&2047,
        !          1796:                                                        sintable[(sprite[j].ang+512)&2047]>>6,
        !          1797:                                                        sintable[sprite[j].ang&2047]>>6,
        !          1798:                                                        ((posz[target]+(8<<8)-sprite[j].z)<<8) /
        !          1799:                                                        ksqrt((posx[target]-sprite[j].x) *
        !          1800:                                                                        (posx[target]-sprite[j].x) +
        !          1801:                                                                        (posy[target]-sprite[j].y) *
        !          1802:                                                                        (posy[target]-sprite[j].y)),
        !          1803:                                                        i,sprite[i].sectnum,6,0,0,0);
        !          1804:                                        }
        !          1805: 
        !          1806:                                        //Move brown monster
        !          1807:                                dax = sprite[i].x;   //Back up old x&y if stepping off cliff
        !          1808:                                day = sprite[i].y;
        !          1809: 
        !          1810:                                osectnum = sprite[i].sectnum;
        !          1811:                                movestat = movesprite((short)i,(((long)sintable[(sprite[i].ang+512)&2047])*TICSPERFRAME)<<3,(((long)sintable[sprite[i].ang])*TICSPERFRAME)<<3,0L,4L<<8,4L<<8,0);
        !          1812:                                if (globloz > sprite[i].z+(48<<8))
        !          1813:                                        { sprite[i].x = dax; sprite[i].y = day; movestat = 1; }
        !          1814:                                else
        !          1815:                                        sprite[i].z = globloz-((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1);
        !          1816: 
        !          1817:                                if ((sprite[i].sectnum != osectnum) && (sector[sprite[i].sectnum].lotag == 10))
        !          1818:                                        { warpsprite((short)i); movestat = 0; }
        !          1819: 
        !          1820:                                if ((movestat != 0) || (k == 1))
        !          1821:                                {
        !          1822:                                        daang = (getangle(posx[target]-sprite[i].x,posy[target]-sprite[i].y)&2047);
        !          1823:                                        sprite[i].ang = ((daang+(krand()&1023)-512)&2047);
        !          1824:                                }
        !          1825: 
        !          1826:                                break;
        !          1827: 
        !          1828:                        case EVILAL:
        !          1829:                                if (sprite[i].yrepeat >= 38)
        !          1830:                                {
        !          1831:                                        if (sprite[i].yrepeat < 64)
        !          1832:                                        {
        !          1833:                                                sprite[i].xrepeat++;
        !          1834:                                                sprite[i].yrepeat++;
        !          1835:                                        }
        !          1836:                                        else
        !          1837:                                        {
        !          1838:                                                if ((krand()&63) == 0)  //Al decides to reproduce
        !          1839:                                                {
        !          1840:                                                        if (cansee(posx[target],posy[target],posz[target],cursectnum[target],sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum) == 1)
        !          1841:                                                        {
        !          1842:                                                                spawnsprite(j,sprite[i].x,sprite[i].y,0,1+2+256,0,0,
        !          1843:                                                                        32,38,38,0,0,EVILAL,krand()&2047,0,0,0,i,
        !          1844:                                                                        sprite[i].sectnum,1,0,0,0);
        !          1845:                                                        }
        !          1846:                                                }
        !          1847:                                                if ((krand()&63) == 0)     //Al decides to shoot bullet
        !          1848:                                                {
        !          1849:                                                        if (cansee(posx[target],posy[target],posz[target],cursectnum[target],sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum) == 1)
        !          1850:                                                        {
        !          1851:                                                                wsayfollow("zipguns.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1);
        !          1852: 
        !          1853:                                                                spawnsprite(j,sprite[i].x,sprite[i].y,
        !          1854:                                                                        sector[sprite[i].sectnum].floorz-(24<<8),
        !          1855:                                                                        0,0,0,16,64,64,0,0,BULLET,
        !          1856:                                                                        (getangle(posx[target]-sprite[j].x,
        !          1857:                                                                                 posy[target]-sprite[j].y)+(krand()&15)-8)&2047,
        !          1858:                                                                        sintable[(sprite[j].ang+2560)&2047]>>6,
        !          1859:                                                                        sintable[(sprite[j].ang+2048)&2047]>>6,
        !          1860:                                                                        ((posz[target]+(8<<8)-sprite[j].z)<<8) /
        !          1861:                                                                                ksqrt((posx[target]-sprite[j].x) *
        !          1862:                                                                                                (posx[target]-sprite[j].x) +
        !          1863:                                                                                                (posy[target]-sprite[j].y) *
        !          1864:                                                                                                (posy[target]-sprite[j].y)),
        !          1865:                                                                        i,sprite[i].sectnum,6,0,0,0);
        !          1866:                                                        }
        !          1867:                                                }
        !          1868: 
        !          1869:                                                sprite[i].z = sector[sprite[i].sectnum].floorz;
        !          1870: 
        !          1871:                                                //Move Al
        !          1872:                                                dax = ((sintable[(sprite[i].ang+512)&2047]*TICSPERFRAME)<<4);
        !          1873:                                                day = ((sintable[sprite[i].ang]*TICSPERFRAME)<<4);
        !          1874: 
        !          1875:                                                osectnum = sprite[i].sectnum;
        !          1876:                                                movestat = movesprite((short)i,dax,day,0L,4L<<8,4L<<8,0);
        !          1877:                                                if ((sprite[i].sectnum != osectnum) && (sector[sprite[i].sectnum].lotag == 10))
        !          1878:                                                {
        !          1879:                                                        warpsprite((short)i);
        !          1880:                                                        movestat = 0;
        !          1881:                                                }
        !          1882: 
        !          1883:                                                if (movestat != 0)
        !          1884:                                                {
        !          1885:                                                        if ((krand()&1) == 0)
        !          1886:                                                                sprite[i].ang = getangle(posx[target]-sprite[i].x,posy[target]-sprite[i].y);
        !          1887:                                                        else
        !          1888:                                                                sprite[i].ang = (krand()&2047);
        !          1889:                                                }
        !          1890:                                        }
        !          1891:                                }
        !          1892:                                break;
        !          1893:                }
        !          1894: 
        !          1895:                i = nexti;
        !          1896:        }
        !          1897: 
        !          1898:        i = headspritestat[6];     //Go through travelling bullet sprites
        !          1899:        while (i != -1)
        !          1900:        {
        !          1901:                nexti = nextspritestat[i];
        !          1902: 
        !          1903:                         //If the sprite is a bullet then...
        !          1904:                if ((sprite[i].picnum == BULLET) || (sprite[i].picnum == BOMB))
        !          1905:                {
        !          1906:                        dax = ((((long)sprite[i].xvel)*TICSPERFRAME)<<11);
        !          1907:                        day = ((((long)sprite[i].yvel)*TICSPERFRAME)<<11);
        !          1908:                        daz = ((((long)sprite[i].zvel)*TICSPERFRAME)>>3);
        !          1909:                        if (sprite[i].picnum == BOMB) daz = 0;
        !          1910: 
        !          1911:                        osectnum = sprite[i].sectnum;
        !          1912:                        hitobject = movesprite((short)i,dax,day,daz,4L<<8,4L<<8,1);
        !          1913:                        if ((sprite[i].sectnum != osectnum) && (sector[sprite[i].sectnum].lotag == 10))
        !          1914:                        {
        !          1915:                                warpsprite((short)i);
        !          1916:                                hitobject = 0;
        !          1917:                        }
        !          1918: 
        !          1919:                        if (sprite[i].picnum == BOMB)
        !          1920:                        {
        !          1921:                                sprite[i].z += sprite[i].zvel;
        !          1922:                                sprite[i].zvel += (TICSPERFRAME<<5);
        !          1923:                                if (sprite[i].z < globhiz+(tilesizy[BOMB]<<6))
        !          1924:                                {
        !          1925:                                        sprite[i].z = globhiz+(tilesizy[BOMB]<<6);
        !          1926:                                        sprite[i].zvel = -(sprite[i].zvel>>1);
        !          1927:                                }
        !          1928:                                if (sprite[i].z > globloz-(tilesizy[BOMB]<<6))
        !          1929:                                {
        !          1930:                                        sprite[i].z = globloz-(tilesizy[BOMB]<<6);
        !          1931:                                        sprite[i].zvel = -(sprite[i].zvel>>1);
        !          1932:                                }
        !          1933:                                dax = sprite[i].xvel; day = sprite[i].yvel;
        !          1934:                                dist = dax*dax+day*day;
        !          1935:                                if (dist < 512)
        !          1936:                                {
        !          1937:                                        bombexplode(i);
        !          1938:                                        goto bulletisdeletedskip;
        !          1939:                                }
        !          1940:                                if (dist < 4096)
        !          1941:                                {
        !          1942:                                        sprite[i].xrepeat = ((4096+2048)*16) / (dist+2048);
        !          1943:                                        sprite[i].yrepeat = sprite[i].xrepeat;
        !          1944:                                        sprite[i].xoffset = (krand()&15)-8;
        !          1945:                                        sprite[i].yoffset = (krand()&15)-8;
        !          1946:                                }
        !          1947:                                if (mulscale(krand(),dist,30) == 0)
        !          1948:                                {
        !          1949:                                        sprite[i].xvel -= ksgn(sprite[i].xvel);
        !          1950:                                        sprite[i].yvel -= ksgn(sprite[i].yvel);
        !          1951:                                        sprite[i].zvel -= ksgn(sprite[i].zvel);
        !          1952:                                }
        !          1953:                        }
        !          1954: 
        !          1955:                                //Check for bouncy objects before killing bullet
        !          1956:                        if ((hitobject&0xc000) == 32768)  //Bullet hit a wall
        !          1957:                        {
        !          1958:                                if (wall[hitobject&4095].lotag == 8)
        !          1959:                                {
        !          1960:                                        dax = sprite[i].xvel; day = sprite[i].yvel;
        !          1961:                                        if ((sprite[i].picnum != BOMB) || (dax*dax+day*day >= 512))
        !          1962:                                        {
        !          1963:                                                k = (hitobject&4095); l = wall[k].point2;
        !          1964:                                                j = getangle(wall[l].x-wall[k].x,wall[l].y-wall[k].y)+512;
        !          1965: 
        !          1966:                                                        //k = cos(ang) * sin(ang) * 2
        !          1967:                                                k = mulscale(sintable[(j+512)&2047],sintable[j&2047],13);
        !          1968:                                                        //l = cos(ang * 2)
        !          1969:                                                l = sintable[((j<<1)+512)&2047];
        !          1970: 
        !          1971:                                                ox = sprite[i].xvel; oy = sprite[i].yvel;
        !          1972:                                                dax = -ox; day = -oy;
        !          1973:                                                sprite[i].xvel = mulscale(day,k,14) + mulscale(dax,l,14);
        !          1974:                                                sprite[i].yvel = mulscale(dax,k,14) - mulscale(day,l,14);
        !          1975: 
        !          1976:                                                if (sprite[i].picnum == BOMB)
        !          1977:                                                {
        !          1978:                                                        sprite[i].xvel -= (sprite[i].xvel>>3);
        !          1979:                                                        sprite[i].yvel -= (sprite[i].yvel>>3);
        !          1980:                                                        sprite[i].zvel -= (sprite[i].zvel>>3);
        !          1981:                                                }
        !          1982:                                                ox -= sprite[i].xvel; oy -= sprite[i].yvel;
        !          1983:                                                dist = ((ox*ox+oy*oy)>>8);
        !          1984:                                                wsayfollow("bouncy.wav",4096L+(krand()&127)-64,min(dist,256),&sprite[i].x,&sprite[i].y,1);
        !          1985:                                                hitobject = 0;
        !          1986:                                                sprite[i].owner = -1;   //Bullet turns evil!
        !          1987:                                        }
        !          1988:                                }
        !          1989:                        }
        !          1990:                        else if ((hitobject&0xc000) == 49152)  //Bullet hit a sprite
        !          1991:                        {
        !          1992:                                if (sprite[hitobject&4095].picnum == BOUNCYMAT)
        !          1993:                                {
        !          1994:                                        if ((sprite[hitobject&4095].cstat&48) == 0)
        !          1995:                                        {
        !          1996:                                                sprite[i].xvel = -sprite[i].xvel;
        !          1997:                                                sprite[i].yvel = -sprite[i].yvel;
        !          1998:                                                sprite[i].zvel = -sprite[i].zvel;
        !          1999:                                                dist = 255;
        !          2000:                                        }
        !          2001:                                        else if ((sprite[hitobject&4095].cstat&48) == 16)
        !          2002:                                        {
        !          2003:                                                j = sprite[hitobject&4095].ang;
        !          2004: 
        !          2005:                                                        //k = cos(ang) * sin(ang) * 2
        !          2006:                                                k = mulscale(sintable[(j+512)&2047],sintable[j&2047],13);
        !          2007:                                                        //l = cos(ang * 2)
        !          2008:                                                l = sintable[((j<<1)+512)&2047];
        !          2009: 
        !          2010:                                                ox = sprite[i].xvel; oy = sprite[i].yvel;
        !          2011:                                                dax = -ox; day = -oy;
        !          2012:                                                sprite[i].xvel = mulscale(day,k,14) + mulscale(dax,l,14);
        !          2013:                                                sprite[i].yvel = mulscale(dax,k,14) - mulscale(day,l,14);
        !          2014: 
        !          2015:                                                ox -= sprite[i].xvel; oy -= sprite[i].yvel;
        !          2016:                                                dist = ((ox*ox+oy*oy)>>8);
        !          2017:                                        }
        !          2018:                                        sprite[i].owner = -1;   //Bullet turns evil!
        !          2019:                                        wsayfollow("bouncy.wav",4096L+(krand()&127)-64,min(dist,256),&sprite[i].x,&sprite[i].y,1);
        !          2020:                                        hitobject = 0;
        !          2021:                                }
        !          2022:                        }
        !          2023: 
        !          2024:                        if (hitobject != 0)
        !          2025:                        {
        !          2026:                                if (sprite[i].picnum == BOMB)
        !          2027:                                {
        !          2028:                                        if ((hitobject&0xc000) == 49152)
        !          2029:                                                if (sprite[hitobject&4095].lotag == 5)  //Basketball hoop
        !          2030:                                                {
        !          2031:                                                        wsayfollow("niceshot.wav",3840L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0);
        !          2032:                                                        deletesprite((short)i);
        !          2033:                                                        goto bulletisdeletedskip;
        !          2034:                                                }
        !          2035: 
        !          2036:                                        bombexplode(i);
        !          2037:                                        goto bulletisdeletedskip;
        !          2038:                                }
        !          2039: 
        !          2040:                                if ((hitobject&0xc000) == 16384)  //Hits a ceiling / floor
        !          2041:                                {
        !          2042:                                        wsayfollow("bullseye.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0);
        !          2043:                                        deletesprite((short)i);
        !          2044:                                        goto bulletisdeletedskip;
        !          2045:                                }
        !          2046:                                else if ((hitobject&0xc000) == 32768)  //Bullet hit a wall
        !          2047:                                {
        !          2048:                                        if (wall[hitobject&4095].picnum == KENPICTURE)
        !          2049:                                        {
        !          2050:                                                if (waloff[4095] != 0)
        !          2051:                                                        wall[hitobject&4095].picnum = 4095;
        !          2052:                                                wsayfollow("hello.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0);   //Ken says, "Hello... how are you today!"
        !          2053:                                        }
        !          2054:                                        else
        !          2055:                                                wsayfollow("bullseye.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0);
        !          2056: 
        !          2057:                                        deletesprite((short)i);
        !          2058:                                        goto bulletisdeletedskip;
        !          2059:                                }
        !          2060:                                else if ((hitobject&0xc000) == 49152)  //Bullet hit a sprite
        !          2061:                                {
        !          2062:                                                //Check if bullet hit a player & find which player it was...
        !          2063:                                        if (sprite[hitobject&4095].picnum == DOOMGUY)
        !          2064:                                                for(j=connecthead;j>=0;j=connectpoint2[j])
        !          2065:                                                        if (sprite[i].owner != j+4096)
        !          2066:                                                                if (playersprite[j] == (hitobject&4095))
        !          2067:                                                                {
        !          2068:                                                                        wsayfollow("ouch.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0);
        !          2069:                                                                        changehealth(j,-25);
        !          2070:                                                                        deletesprite((short)i);
        !          2071:                                                                        goto bulletisdeletedskip;
        !          2072:                                                                }
        !          2073: 
        !          2074:                                                //Check if bullet hit any monsters...
        !          2075:                                        j = (hitobject&4095);     //j is the spritenum that the bullet (spritenum i) hit
        !          2076:                                        if (sprite[i].owner != j)
        !          2077:                                        {
        !          2078:                                                switch(sprite[j].picnum)
        !          2079:                                                {
        !          2080:                                                        case BROWNMONSTER:
        !          2081:                                                                if (sprite[j].lotag > 0) sprite[j].lotag -= 25;
        !          2082:                                                                if (sprite[j].lotag > 0)
        !          2083:                                                                {
        !          2084:                                                                        if (sprite[j].lotag <= 25) sprite[j].cstat |= 2;
        !          2085:                                                                        wsayfollow("hurt.wav",4096L+(krand()&511)-256,256L,&sprite[i].x,&sprite[i].y,1);
        !          2086: 
        !          2087:                                                                        for(j=connecthead;j>=0;j=connectpoint2[j])
        !          2088:                                                                                if (sprite[i].owner == j+4096)
        !          2089:                                                                                        changescore(j,200);
        !          2090:                                                                }
        !          2091:                                                                else
        !          2092:                                                                {
        !          2093:                                                                        wsayfollow("blowup.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0);
        !          2094:                                                                        sprite[j].z += ((tilesizy[sprite[j].picnum]*sprite[j].yrepeat)<<1);
        !          2095:                                                                        sprite[j].picnum = GIFTBOX;
        !          2096:                                                                        sprite[j].cstat &= ~0x83;    //Should not clip, foot-z
        !          2097: 
        !          2098:                                                                        spawnsprite(k,sprite[j].x,sprite[j].y,sprite[j].z,
        !          2099:                                                                                0,-4,0,32,64,64,0,0,EXPLOSION,sprite[j].ang,
        !          2100:                                                                                0,0,0,j,sprite[j].sectnum,5,31,0,0);
        !          2101:                                                                                        //31=Time left for explosion to stay
        !          2102: 
        !          2103:                                                                        changespritestat(j,0);
        !          2104: 
        !          2105:                                                                        for(j=connecthead;j>=0;j=connectpoint2[j])
        !          2106:                                                                                if (sprite[i].owner == j+4096)
        !          2107:                                                                                        changescore(j,200);
        !          2108:                                                                }
        !          2109:                                                                deletesprite((short)i);
        !          2110:                                                                goto bulletisdeletedskip;
        !          2111:                                                        case EVILAL:
        !          2112:                                                                wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0);
        !          2113:                                                                sprite[j].picnum = EVILALGRAVE;
        !          2114:                                                                sprite[j].cstat = 0;
        !          2115:                                                                sprite[j].xrepeat = (krand()&63)+16;
        !          2116:                                                                sprite[j].yrepeat = sprite[j].xrepeat;
        !          2117:                                                                changespritestat(j,0);
        !          2118: 
        !          2119:                                                                for(j=connecthead;j>=0;j=connectpoint2[j])
        !          2120:                                                                        if (sprite[i].owner == j+4096)
        !          2121:                                                                                changescore(j,200);
        !          2122: 
        !          2123:                                                                deletesprite((short)i);
        !          2124:                                                                goto bulletisdeletedskip;
        !          2125:                                                        case AL:
        !          2126:                                                                wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0);
        !          2127:                                                                sprite[j].xrepeat += 2;
        !          2128:                                                                sprite[j].yrepeat += 2;
        !          2129:                                                                if (sprite[j].yrepeat >= 38)
        !          2130:                                                                {
        !          2131:                                                                        sprite[j].picnum = EVILAL;
        !          2132:                                                                        sprite[j].cstat |= 2;      //Make him transluscent
        !          2133:                                                                }
        !          2134:                                                                changespritestat(j,1);
        !          2135:                                                                deletesprite((short)i);
        !          2136:                                                                goto bulletisdeletedskip;
        !          2137:                                                        default:
        !          2138:                                                                wsayfollow("bullseye.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0);
        !          2139:                                                                deletesprite((short)i);
        !          2140:                                                                goto bulletisdeletedskip;
        !          2141:                                                }
        !          2142:                                        }
        !          2143:                                }
        !          2144:                        }
        !          2145:                }
        !          2146: 
        !          2147: bulletisdeletedskip:
        !          2148:                i = nexti;
        !          2149:        }
        !          2150: 
        !          2151:        for(j=connecthead;j>=0;j=connectpoint2[j])
        !          2152:                if ((saywatchit[j] >= lockclock-TICSPERFRAME) && (saywatchit[j] < lockclock))
        !          2153:                        wsayfollow("watchit.wav",4096L+(krand()&127)-64,256L,&posx[j],&posy[j],1);
        !          2154: 
        !          2155:        i = headspritestat[2];     //Go through monster waiting for you list
        !          2156:        while (i != -1)
        !          2157:        {
        !          2158:                nexti = nextspritestat[i];
        !          2159: 
        !          2160:                        //Use dot product to see if monster's angle is towards a player
        !          2161:                for(p=connecthead;p>=0;p=connectpoint2[p])
        !          2162:                        if (sintable[(sprite[i].ang+2560)&2047]*(posx[p]-sprite[i].x) + sintable[(sprite[i].ang+2048)&2047]*(posy[p]-sprite[i].y) >= 0)
        !          2163:                                if (cansee(posx[p],posy[p],posz[p],cursectnum[p],sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum) == 1)
        !          2164:                                {
        !          2165:                                        changespritestat(i,1);
        !          2166:                                        wsayfollow("iseeyou.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1);
        !          2167:                                }
        !          2168: 
        !          2169:                i = nexti;
        !          2170:        }
        !          2171: 
        !          2172:        i = headspritestat[3];     //Go through smoke sprites
        !          2173:        while (i >= 0)
        !          2174:        {
        !          2175:                nexti = nextspritestat[i];
        !          2176: 
        !          2177:                sprite[i].z -= (TICSPERFRAME<<6);
        !          2178:                sprite[i].lotag -= TICSPERFRAME;
        !          2179:                if (sprite[i].lotag < 0)
        !          2180:                        deletesprite(i);
        !          2181: 
        !          2182:                i = nexti;
        !          2183:        }
        !          2184: 
        !          2185:        i = headspritestat[4];     //Go through splash sprites
        !          2186:        while (i >= 0)
        !          2187:        {
        !          2188:                nexti = nextspritestat[i];
        !          2189: 
        !          2190:                sprite[i].lotag -= TICSPERFRAME;
        !          2191:                sprite[i].picnum = SPLASH + ((63-sprite[i].lotag)>>4);
        !          2192:                if (sprite[i].lotag < 0)
        !          2193:                        deletesprite(i);
        !          2194: 
        !          2195:                i = nexti;
        !          2196:        }
        !          2197: 
        !          2198:        i = headspritestat[5];     //Go through explosion sprites
        !          2199:        while (i >= 0)
        !          2200:        {
        !          2201:                nexti = nextspritestat[i];
        !          2202: 
        !          2203:                sprite[i].lotag -= TICSPERFRAME;
        !          2204:                if (sprite[i].lotag < 0)
        !          2205:                        deletesprite(i);
        !          2206: 
        !          2207:                i = nexti;
        !          2208:        }
        !          2209: 
        !          2210:        i = headspritestat[7];     //Go through bomb spriral-explosion sprites
        !          2211:        while (i >= 0)
        !          2212:        {
        !          2213:                nexti = nextspritestat[i];
        !          2214: 
        !          2215:                sprite[i].x += ((sprite[i].xvel*TICSPERFRAME)>>4);
        !          2216:                sprite[i].y += ((sprite[i].yvel*TICSPERFRAME)>>4);
        !          2217:                sprite[i].z += ((sprite[i].zvel*TICSPERFRAME)>>4);
        !          2218: 
        !          2219:                sprite[i].zvel += (TICSPERFRAME<<7);
        !          2220:                if (sprite[i].z < sector[sprite[i].sectnum].ceilingz+(4<<8))
        !          2221:                {
        !          2222:                        sprite[i].z = sector[sprite[i].sectnum].ceilingz+(4<<8);
        !          2223:                        sprite[i].zvel = -(sprite[i].zvel>>1);
        !          2224:                }
        !          2225:                if (sprite[i].z > sector[sprite[i].sectnum].floorz-(4<<8))
        !          2226:                {
        !          2227:                        sprite[i].z = sector[sprite[i].sectnum].floorz-(4<<8);
        !          2228:                        sprite[i].zvel = -(sprite[i].zvel>>1);
        !          2229:                }
        !          2230: 
        !          2231:                sprite[i].xrepeat = (sprite[i].lotag>>2);
        !          2232:                sprite[i].yrepeat = (sprite[i].lotag>>2);
        !          2233: 
        !          2234:                sprite[i].lotag -= TICSPERFRAME;
        !          2235:                if (sprite[i].lotag < 0)
        !          2236:                        deletesprite(i);
        !          2237: 
        !          2238:                i = nexti;
        !          2239:        }
        !          2240: }
        !          2241: 
        !          2242: bombexplode(long i)
        !          2243: {
        !          2244:        long j, nextj, k, daang, dax, day, dist;
        !          2245: 
        !          2246:        spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z,0,-4,0,
        !          2247:                32,64,64,0,0,EXPLOSION,sprite[i].ang,
        !          2248:                0,0,0,sprite[i].owner,sprite[i].sectnum,5,31,0,0);
        !          2249:                  //31=Time left for explosion to stay
        !          2250: 
        !          2251:        for(k=0;k<16;k++)
        !          2252:        {
        !          2253:                spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z+(8<<8),2,-4,0,
        !          2254:                        32,24,24,0,0,EXPLOSION,sprite[i].ang,
        !          2255:                        (krand()&511)-256,(krand()&511)-256,(krand()&16384)-8192,
        !          2256:                        sprite[i].owner,sprite[i].sectnum,7,96,0,0);
        !          2257:                                //96=Time left for smoke to be alive
        !          2258:        }
        !          2259: 
        !          2260:        for(j=connecthead;j>=0;j=connectpoint2[j])
        !          2261:        {
        !          2262:                dist = (posx[j]-sprite[i].x)*(posx[j]-sprite[i].x);
        !          2263:                dist += (posy[j]-sprite[i].y)*(posy[j]-sprite[i].y);
        !          2264:                dist += ((posz[j]-sprite[i].z)>>4)*((posz[j]-sprite[i].z)>>4);
        !          2265:                if (dist < 4194304)
        !          2266:                        if (cansee(posx[j],posy[j],posz[j],cursectnum[j],sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum) == 1)
        !          2267:                        {
        !          2268:                                k = ((32768/((dist>>16)+4))>>5);
        !          2269:                                if (j == myconnectindex)
        !          2270:                                {
        !          2271:                                        daang = getangle(posx[j]-sprite[i].x,posy[j]-sprite[i].y);
        !          2272:                                        dax = ((k*sintable[(daang+2560)&2047])>>14);
        !          2273:                                        day = ((k*sintable[(daang+2048)&2047])>>14);
        !          2274:                                        vel += ((dax*sintable[(ang[j]+2560)&2047]+day*sintable[(ang[j]+2048)&2047])>>14);
        !          2275:                                        svel += ((day*sintable[(ang[j]+2560)&2047]-dax*sintable[(ang[j]+2048)&2047])>>14);
        !          2276:                                }
        !          2277:                                if (changehealth(j,-k) == 1)  //If you're dead
        !          2278:                                        if (sprite[i].owner == j+4096)
        !          2279:                                                saywatchit[j] = lockclock+120;
        !          2280:                        }
        !          2281:        }
        !          2282: 
        !          2283:        for(k=1;k<=2;k++)         //Check for hurting monsters
        !          2284:        {
        !          2285:                j = headspritestat[k];
        !          2286:                while (j != -1)
        !          2287:                {
        !          2288:                        nextj = nextspritestat[j];
        !          2289: 
        !          2290:                        dist = (sprite[j].x-sprite[i].x)*(sprite[j].x-sprite[i].x);
        !          2291:                        dist += (sprite[j].y-sprite[i].y)*(sprite[j].y-sprite[i].y);
        !          2292:                        dist += ((sprite[j].z-sprite[i].z)>>4)*((sprite[j].z-sprite[i].z)>>4);
        !          2293:                        if (dist < 4194304)
        !          2294:                                if (cansee(sprite[j].x,sprite[j].y,sprite[j].z-(tilesizy[sprite[j].picnum]<<7),sprite[j].sectnum,sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum) == 1)
        !          2295:                                {
        !          2296:                                        if (sprite[j].picnum == BROWNMONSTER)
        !          2297:                                        {
        !          2298:                                                sprite[j].z += ((tilesizy[sprite[j].picnum]*sprite[j].yrepeat)<<1);
        !          2299:                                                sprite[j].picnum = GIFTBOX;
        !          2300:                                                sprite[j].cstat &= ~0x83;    //Should not clip, foot-z
        !          2301:                                                changespritestat(j,0);
        !          2302:                                        }
        !          2303:                                        if (sprite[j].picnum == EVILAL)
        !          2304:                                        {
        !          2305:                                                sprite[j].picnum = EVILALGRAVE;
        !          2306:                                                sprite[j].cstat = 0;
        !          2307:                                                sprite[j].xrepeat = (krand()&63)+16;
        !          2308:                                                sprite[j].yrepeat = sprite[j].xrepeat;
        !          2309:                                                changespritestat(j,0);
        !          2310:                                        }
        !          2311:                                }
        !          2312: 
        !          2313:                        j = nextj;
        !          2314:                }
        !          2315:        }
        !          2316:        wsayfollow("blowup.wav",3840L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0);
        !          2317:        deletesprite((short)i);
        !          2318: }
        !          2319: 
        !          2320: processinput(short snum)
        !          2321: {
        !          2322:        long oldposx, oldposy, nexti;
        !          2323:        long i, j, k, doubvel, xvect, yvect, goalz;
        !          2324:        long dax, day, dax2, day2, odax, oday, odax2, oday2;
        !          2325:        short startwall, endwall;
        !          2326:        char *ptr;
        !          2327: 
        !          2328:                //SHARED KEYS:
        !          2329:                //Movement code
        !          2330:        if ((syncvel[snum]|syncsvel[snum]) != 0)
        !          2331:        {
        !          2332:                doubvel = (TICSPERFRAME<<((syncbits[snum]&256)>0));
        !          2333: 
        !          2334:                xvect = 0, yvect = 0;
        !          2335:                if (syncvel[snum] != 0)
        !          2336:                {
        !          2337:                        xvect += ((((long)syncvel[snum])*doubvel*(long)sintable[(ang[snum]+2560)&2047])>>3);
        !          2338:                        yvect += ((((long)syncvel[snum])*doubvel*(long)sintable[(ang[snum]+2048)&2047])>>3);
        !          2339:                }
        !          2340:                if (syncsvel[snum] != 0)
        !          2341:                {
        !          2342:                        xvect += ((((long)syncsvel[snum])*doubvel*(long)sintable[(ang[snum]+2048)&2047])>>3);
        !          2343:                        yvect += ((((long)syncsvel[snum])*doubvel*(long)sintable[(ang[snum]+1536)&2047])>>3);
        !          2344:                }
        !          2345:                clipmove(&posx[snum],&posy[snum],&posz[snum],&cursectnum[snum],xvect,yvect,128L,4<<8,4<<8,0);
        !          2346:                frameinterpolate = 1;
        !          2347:                revolvedoorstat[snum] = 1;
        !          2348:        }
        !          2349:        else
        !          2350:        {
        !          2351:                revolvedoorstat[snum] = 0;
        !          2352:        }
        !          2353: 
        !          2354:                //Push player away from walls if clipmove doesn't work
        !          2355:        if (pushmove(&posx[snum],&posy[snum],&posz[snum],&cursectnum[snum],128L,4<<8,4<<8,0) < 0)
        !          2356:                changehealth(snum,-1000);  //If this screws up, then instant death!!!
        !          2357: 
        !          2358:                        // Getzrange returns the highest and lowest z's for an entire box,
        !          2359:                        // NOT just a point.  This prevents you from falling off cliffs
        !          2360:                        // when you step only slightly over the cliff.
        !          2361:        sprite[playersprite[snum]].cstat ^= 1;
        !          2362:        getzrange(posx[snum],posy[snum],posz[snum],cursectnum[snum],&globhiz,&globhihit,&globloz,&globlohit,128L,0);
        !          2363:        sprite[playersprite[snum]].cstat ^= 1;
        !          2364: 
        !          2365:        if (syncangvel[snum] != 0)          //ang += angvel * constant
        !          2366:        {                         //ENGINE calculates angvel for you
        !          2367:                doubvel = TICSPERFRAME;
        !          2368:                if ((syncbits[snum]&256) > 0)  //Lt. shift makes turn velocity 50% faster
        !          2369:                        doubvel += (TICSPERFRAME>>1);
        !          2370:                ang[snum] += ((((long)syncangvel[snum])*doubvel)>>4);
        !          2371:                ang[snum] = (ang[snum]+2048)&2047;
        !          2372:        }
        !          2373: 
        !          2374:        if (health[snum] < 0)
        !          2375:        {
        !          2376:                health[snum] -= TICSPERFRAME;
        !          2377:                if (health[snum] <= -160)
        !          2378:                {
        !          2379:                        hvel[snum] = 0;
        !          2380:                        if (snum == myconnectindex)
        !          2381:                                vel = 0, svel = 0, angvel = 0, keystatus[3] = 1;
        !          2382: 
        !          2383:                        deaths[snum]++;
        !          2384:                        health[snum] = 100;
        !          2385:                        numbombs[snum] = -1;
        !          2386: 
        !          2387:                        findrandomspot(&posx[snum],&posy[snum],&cursectnum[snum]);
        !          2388:                        posz[snum] = sector[cursectnum[snum]].floorz-(1<<8);
        !          2389:                        horiz[snum] = 100;
        !          2390:                        ang[snum] = (krand()&2047);
        !          2391: 
        !          2392:                        setsprite(playersprite[snum],posx[snum],posy[snum],posz[snum]+(32<<8));
        !          2393:                        sprite[playersprite[snum]].picnum = DOOMGUY;
        !          2394:                        sprite[playersprite[snum]].ang = ang[snum];
        !          2395:                        sprite[playersprite[snum]].xrepeat = 64;
        !          2396:                        sprite[playersprite[snum]].yrepeat = 64;
        !          2397: 
        !          2398:                        if ((snum == screenpeek) && (screensize <= xdim))
        !          2399:                        {
        !          2400:                                sprintf(&tempbuf,"Deaths: %d",deaths[snum]);
        !          2401:                                printext((xdim>>1)-(strlen(tempbuf)<<2),ydim-16,tempbuf,ALPHABET,80);
        !          2402:                                sprintf(&tempbuf,"Health: %3d",health[snum]);
        !          2403:                                printext((xdim>>1)-(strlen(tempbuf)<<2),ydim-24,tempbuf,ALPHABET,80);
        !          2404:                        }
        !          2405: 
        !          2406:                        i = playersprite[snum];
        !          2407:                        wsayfollow("zipguns.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1);
        !          2408:                        for(k=0;k<16;k++)
        !          2409:                        {
        !          2410:                                spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z+(8<<8),2,-4,0,
        !          2411:                                        32,24,24,0,0,EXPLOSION,sprite[i].ang,
        !          2412:                                        (krand()&511)-256,(krand()&511)-256,(krand()&16384)-8192,
        !          2413:                                        sprite[i].owner,sprite[i].sectnum,7,96,0,0);
        !          2414:                                                //96=Time left for smoke to be alive
        !          2415:                        }
        !          2416:                }
        !          2417:                else
        !          2418:                {
        !          2419:                        sprite[playersprite[snum]].xrepeat = max(((128+health[snum])>>1),0);
        !          2420:                        sprite[playersprite[snum]].yrepeat = max(((128+health[snum])>>1),0);
        !          2421: 
        !          2422:                        hvel[snum] += (TICSPERFRAME<<2);
        !          2423:                        horiz[snum] = max(horiz[snum]-4,0);
        !          2424:                        posz[snum] += hvel[snum];
        !          2425:                        if (posz[snum] > globloz-(4<<8))
        !          2426:                        {
        !          2427:                                posz[snum] = globloz-(4<<8);
        !          2428:                                horiz[snum] = min(horiz[snum]+5,200);
        !          2429:                                hvel[snum] = 0;
        !          2430:                        }
        !          2431:                }
        !          2432:        }
        !          2433: 
        !          2434:        if (((syncbits[snum]&8) > 0) && (horiz[snum] > 100-(200>>1))) horiz[snum] -= 4;     //-
        !          2435:        if (((syncbits[snum]&4) > 0) && (horiz[snum] < 100+(200>>1))) horiz[snum] += 4;   //+
        !          2436: 
        !          2437:        goalz = globloz-(32<<8);         //32 pixels above floor
        !          2438:        if (sector[cursectnum[snum]].lotag == 4)   //slime sector
        !          2439:                if ((globlohit&0xc000) != 49152)            //You're not on a sprite
        !          2440:                {
        !          2441:                        goalz = globloz-(8<<8);
        !          2442:                        if (posz[snum] >= goalz-(2<<8))
        !          2443:                        {
        !          2444:                                clipmove(&posx[snum],&posy[snum],&posz[snum],&cursectnum[snum],-TICSPERFRAME<<14,-TICSPERFRAME<<14,128L,4<<8,4<<8,0);
        !          2445:                                frameinterpolate = 0;
        !          2446: 
        !          2447:                                if (slimesoundcnt[snum] >= 0)
        !          2448:                                {
        !          2449:                                        slimesoundcnt[snum] -= TICSPERFRAME;
        !          2450:                                        while (slimesoundcnt[snum] < 0)
        !          2451:                                        {
        !          2452:                                                slimesoundcnt[snum] += 120;
        !          2453:                                                wsayfollow("slime.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1);
        !          2454:                                        }
        !          2455:                                }
        !          2456:                        }
        !          2457:                }
        !          2458:        if (goalz < globhiz+(16<<8))   //ceiling&floor too close
        !          2459:                goalz = ((globloz+globhiz)>>1);
        !          2460:        //goalz += mousz;
        !          2461:        if (health[snum] >= 0)
        !          2462:        {
        !          2463:                if ((syncbits[snum]&1) > 0)                         //A (stand high)
        !          2464:                {
        !          2465:                        if (posz[snum] >= globloz-(32<<8))
        !          2466:                        {
        !          2467:                                goalz -= (16<<8);
        !          2468:                                if ((syncbits[snum]&256) > 0)                 //Either shift key
        !          2469:                                        goalz -= (24<<8);
        !          2470:                        }
        !          2471:                }
        !          2472:                if ((syncbits[snum]&2) > 0)                         //Z (stand low)
        !          2473:                {
        !          2474:                        goalz += (12<<8);
        !          2475:                        if ((syncbits[snum]&256) > 0)                    //Either shift key
        !          2476:                                goalz += (12<<8);
        !          2477:                }
        !          2478:        }
        !          2479:        if ((sector[cursectnum[snum]].floorstat&2) > 0) //Groudraw
        !          2480:        {
        !          2481:                if (waloff[sector[cursectnum[snum]].floorheinum] == 0) loadtile(sector[cursectnum[snum]].floorheinum);
        !          2482:                ptr = (char *)(waloff[sector[cursectnum[snum]].floorheinum]+(((posx[snum]>>4)&63)<<6)+((posy[snum]>>4)&63));
        !          2483:                goalz -= ((*ptr)<<8);
        !          2484:        }
        !          2485: 
        !          2486:        if (posz[snum] < goalz)
        !          2487:                hvel[snum] += (TICSPERFRAME<<4);
        !          2488:        else
        !          2489:                hvel[snum] = (((goalz-posz[snum])*TICSPERFRAME)>>5);
        !          2490: 
        !          2491:        posz[snum] += hvel[snum];
        !          2492:        if (posz[snum] > globloz-(4<<8)) posz[snum] = globloz-(4<<8), hvel[snum] = 0;
        !          2493:        if (posz[snum] < globhiz+(4<<8)) posz[snum] = globhiz+(4<<8), hvel[snum] = 0;
        !          2494: 
        !          2495:        if (dimensionmode[snum] != 3)
        !          2496:        {
        !          2497:                if (((syncbits[snum]&32) > 0) && (zoom[snum] > 48)) zoom[snum] -= (zoom[snum]>>4);
        !          2498:                if (((syncbits[snum]&16) > 0) && (zoom[snum] < 4096)) zoom[snum] += (zoom[snum]>>4);
        !          2499:        }
        !          2500: 
        !          2501:                //Update sprite representation of player
        !          2502:                //   -should be after movement, but before shooting code
        !          2503:        setsprite(playersprite[snum],posx[snum],posy[snum],posz[snum]+(32<<8));
        !          2504:        sprite[playersprite[snum]].ang = ang[snum];
        !          2505: 
        !          2506:        if ((cursectnum[snum] < 0) || (cursectnum[snum] >= numsectors))
        !          2507:        {       //How did you get in the wrong sector?
        !          2508:                wsayfollow("ouch.wav",4096L+(krand()&127)-64,64L,&posx[snum],&posy[snum],1);
        !          2509:                changehealth(snum,-TICSPERFRAME);
        !          2510:        }
        !          2511:        else if (globhiz+(8<<8) > globloz)
        !          2512:        {       //Ceiling and floor are smooshing you!
        !          2513:                wsayfollow("ouch.wav",4096L+(krand()&127)-64,64L,&posx[snum],&posy[snum],1);
        !          2514:                changehealth(snum,-TICSPERFRAME);
        !          2515:        }
        !          2516: 
        !          2517:        if ((waterfountainwall[snum] >= 0) && (health[snum] >= 0))
        !          2518:                if ((wall[neartagwall].lotag != 7) || ((syncbits[snum]&1024) == 0))
        !          2519:                {
        !          2520:                        i = waterfountainwall[snum];
        !          2521:                        if (wall[i].overpicnum == USEWATERFOUNTAIN)
        !          2522:                                wall[i].overpicnum = WATERFOUNTAIN;
        !          2523:                        else if (wall[i].picnum == USEWATERFOUNTAIN)
        !          2524:                                wall[i].picnum = WATERFOUNTAIN;
        !          2525: 
        !          2526:                        waterfountainwall[snum] = -1;
        !          2527:                }
        !          2528: 
        !          2529:        if ((syncbits[snum]&1024) > 0)  //Space bar
        !          2530:        {
        !          2531:                        //Continuous triggers...
        !          2532: 
        !          2533:                neartag(posx[snum],posy[snum],posz[snum],cursectnum[snum],ang[snum],&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,1024L,3);
        !          2534:                if (neartagsector == -1)
        !          2535:                {
        !          2536:                        i = cursectnum[snum];
        !          2537:                        if ((sector[i].lotag|sector[i].hitag) != 0)
        !          2538:                                neartagsector = i;
        !          2539:                }
        !          2540: 
        !          2541:                if (wall[neartagwall].lotag == 7)  //Water fountain
        !          2542:                {
        !          2543:                        if (wall[neartagwall].overpicnum == WATERFOUNTAIN)
        !          2544:                        {
        !          2545:                                wsayfollow("water.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1);
        !          2546:                                wall[neartagwall].overpicnum = USEWATERFOUNTAIN;
        !          2547:                                waterfountainwall[snum] = neartagwall;
        !          2548:                        }
        !          2549:                        else if (wall[neartagwall].picnum == WATERFOUNTAIN)
        !          2550:                        {
        !          2551:                                wsayfollow("water.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1);
        !          2552:                                wall[neartagwall].picnum = USEWATERFOUNTAIN;
        !          2553:                                waterfountainwall[snum] = neartagwall;
        !          2554:                        }
        !          2555: 
        !          2556:                        if (waterfountainwall[snum] >= 0)
        !          2557:                        {
        !          2558:                                waterfountaincnt[snum] -= TICSPERFRAME;
        !          2559:                                while (waterfountaincnt[snum] < 0)
        !          2560:                                {
        !          2561:                                        waterfountaincnt[snum] += 120;
        !          2562:                                        wsayfollow("water.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1);
        !          2563:                                        changehealth(snum,2);
        !          2564:                                }
        !          2565:                        }
        !          2566:                }
        !          2567: 
        !          2568:                        //1-time triggers...
        !          2569:                if ((oflags[snum]&1024) == 0)
        !          2570:                {
        !          2571:                        if (neartagsector >= 0)
        !          2572:                                if (sector[neartagsector].hitag == 0)
        !          2573:                                        operatesector(neartagsector);
        !          2574: 
        !          2575:                        if (neartagwall >= 0)
        !          2576:                                if (wall[neartagwall].lotag == 2)  //Switch
        !          2577:                                {
        !          2578:                                        for(i=0;i<numsectors;i++)
        !          2579:                                                if (sector[i].hitag == wall[neartagwall].hitag)
        !          2580:                                                        if (sector[i].lotag != 1)
        !          2581:                                                                operatesector(i);
        !          2582:                                        i = headspritestat[0];
        !          2583:                                        while (i != -1)
        !          2584:                                        {
        !          2585:                                                nexti = nextspritestat[i];
        !          2586:                                                if (sprite[i].hitag == wall[neartagwall].hitag)
        !          2587:                                                        operatesprite(i);
        !          2588:                                                i = nexti;
        !          2589:                                        }
        !          2590: 
        !          2591:                                        j = wall[neartagwall].overpicnum;
        !          2592:                                        if (j == SWITCH1ON)                     //1-time switch
        !          2593:                                        {
        !          2594:                                                wall[neartagwall].overpicnum = GIFTBOX;
        !          2595:                                                wall[neartagwall].lotag = 0;
        !          2596:                                                wall[neartagwall].hitag = 0;
        !          2597:                                        }
        !          2598:                                        if (j == GIFTBOX)                       //1-time switch
        !          2599:                                        {
        !          2600:                                                wall[neartagwall].overpicnum = SWITCH1ON;
        !          2601:                                                wall[neartagwall].lotag = 0;
        !          2602:                                                wall[neartagwall].hitag = 0;
        !          2603:                                        }
        !          2604:                                        if (j == SWITCH2ON) wall[neartagwall].overpicnum = SWITCH2OFF;
        !          2605:                                        if (j == SWITCH2OFF) wall[neartagwall].overpicnum = SWITCH2ON;
        !          2606:                                        if (j == SWITCH3ON) wall[neartagwall].overpicnum = SWITCH3OFF;
        !          2607:                                        if (j == SWITCH3OFF) wall[neartagwall].overpicnum = SWITCH3ON;
        !          2608: 
        !          2609:                                        i = wall[neartagwall].point2;
        !          2610:                                        dax = ((wall[neartagwall].x+wall[i].x)>>1);
        !          2611:                                        day = ((wall[neartagwall].y+wall[i].y)>>1);
        !          2612:                                        wsayfollow("switch.wav",4096L+(krand()&255)-128,256L,&dax,&day,0);
        !          2613:                                }
        !          2614: 
        !          2615:                        if (neartagsprite >= 0)
        !          2616:                        {
        !          2617:                                if (sprite[neartagsprite].lotag == 1)
        !          2618:                                {  //if you're shoving innocent little AL around, he gets mad!
        !          2619:                                        if (sprite[neartagsprite].picnum == AL)
        !          2620:                                        {
        !          2621:                                                sprite[neartagsprite].picnum = EVILAL;
        !          2622:                                                sprite[neartagsprite].cstat |= 2;   //Make him transluscent
        !          2623:                                                sprite[neartagsprite].xrepeat = 38;
        !          2624:                                                sprite[neartagsprite].yrepeat = 38;
        !          2625:                                        }
        !          2626:                                        changespritestat(neartagsprite,1);
        !          2627:                                }
        !          2628:                                if (sprite[neartagsprite].lotag == 4)
        !          2629:                                {
        !          2630:                                        for(i=0;i<numsectors;i++)
        !          2631:                                                if (sector[i].hitag == sprite[neartagsprite].hitag)
        !          2632:                                                        if (sector[i].lotag != 1)
        !          2633:                                                                operatesector(i);
        !          2634:                                        i = headspritestat[0];
        !          2635:                                        while (i != -1)
        !          2636:                                        {
        !          2637:                                                nexti = nextspritestat[i];
        !          2638:                                                if (sprite[i].hitag == sprite[neartagsprite].hitag)
        !          2639:                                                        operatesprite(i);
        !          2640:                                                i = nexti;
        !          2641:                                        }
        !          2642: 
        !          2643:                                        j = sprite[neartagsprite].picnum;
        !          2644:                                        if (j == SWITCH1ON)                     //1-time switch
        !          2645:                                        {
        !          2646:                                                sprite[neartagsprite].picnum = GIFTBOX;
        !          2647:                                                sprite[neartagsprite].lotag = 0;
        !          2648:                                                sprite[neartagsprite].hitag = 0;
        !          2649:                                        }
        !          2650:                                        if (j == GIFTBOX)                       //1-time switch
        !          2651:                                        {
        !          2652:                                                sprite[neartagsprite].picnum = SWITCH1ON;
        !          2653:                                                sprite[neartagsprite].lotag = 0;
        !          2654:                                                sprite[neartagsprite].hitag = 0;
        !          2655:                                        }
        !          2656:                                        if (j == SWITCH2ON) sprite[neartagsprite].picnum = SWITCH2OFF;
        !          2657:                                        if (j == SWITCH2OFF) sprite[neartagsprite].picnum = SWITCH2ON;
        !          2658:                                        if (j == SWITCH3ON) sprite[neartagsprite].picnum = SWITCH3OFF;
        !          2659:                                        if (j == SWITCH3OFF) sprite[neartagsprite].picnum = SWITCH3ON;
        !          2660: 
        !          2661:                                        dax = sprite[neartagsprite].x;
        !          2662:                                        day = sprite[neartagsprite].y;
        !          2663:                                        wsayfollow("switch.wav",4096L+(krand()&255)-128,256L,&dax,&day,0);
        !          2664:                                }
        !          2665:                        }
        !          2666:                }
        !          2667:        }
        !          2668: 
        !          2669:        if ((syncbits[snum]&2048) > 0)      //Shoot a bullet
        !          2670:        {
        !          2671:                if ((health[snum] >= 0) || ((krand()&127) > -health[snum]))
        !          2672:                        switch((syncbits[snum]>>13)&7)
        !          2673:                        {
        !          2674:                                case 0:
        !          2675:                                        if ((oflags[snum]&2048) == 0)
        !          2676:                                                shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],0);
        !          2677:                                        break;
        !          2678:                                case 1:
        !          2679:                                        if (lockclock > lastchaingun[snum]+8)
        !          2680:                                        {
        !          2681:                                                lastchaingun[snum] = lockclock;
        !          2682:                                                shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],1);
        !          2683:                                        }
        !          2684:                                        break;
        !          2685:                                case 2:
        !          2686:                                        if ((oflags[snum]&2048) == 0)
        !          2687:                                                if (numbombs[snum] > 0)
        !          2688:                                                {
        !          2689:                                                        shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],2);
        !          2690:                                                        numbombs[snum]--;
        !          2691:                                                }
        !          2692:                                        break;
        !          2693:                        }
        !          2694:        }
        !          2695: 
        !          2696:        if ((syncbits[snum]&4096) > (oflags[snum]&4096))  //Keypad enter
        !          2697:        {
        !          2698:                dimensionmode[snum]++;
        !          2699:                if (dimensionmode[snum] > 3) dimensionmode[snum] = 1;
        !          2700:                if (snum == screenpeek)
        !          2701:                {
        !          2702:                        if (dimensionmode[snum] == 2) setview(0L,0L,xdim-1,(ydim-1)>>detailmode);
        !          2703:                        if (dimensionmode[snum] == 3) setup3dscreen();
        !          2704:                }
        !          2705:        }
        !          2706: 
        !          2707:        oflags[snum] = syncbits[snum];
        !          2708: }
        !          2709: 
        !          2710: static char lockbyte4094;
        !          2711: drawscreen(short snum, long dasmoothratio)
        !          2712: {
        !          2713:        long i, j, k, charsperline, templong, dx, dy, top, bot;
        !          2714:        long x1, y1, x2, y2, ox1, oy1, ox2, oy2, dist, maxdist;
        !          2715:        long cposx, cposy, cposz, choriz, czoom, tposx, tposy, thoriz;
        !          2716:        short cang, tang;
        !          2717:        char ch, *ptr, *ptr2, *ptr3, *ptr4;
        !          2718: 
        !          2719:        smoothratio = max(min(dasmoothratio,65536),0);
        !          2720: 
        !          2721:        setears(posx[snum],posy[snum],(long)sintable[(ang[snum]+512)&2047]<<14,(long)sintable[ang[snum]&2047]<<14);
        !          2722: 
        !          2723:        cposx = oposx[snum]+mulscale(posx[snum]-oposx[snum],smoothratio,16);
        !          2724:        cposy = oposy[snum]+mulscale(posy[snum]-oposy[snum],smoothratio,16);
        !          2725:        cposz = oposz[snum]+mulscale(posz[snum]-oposz[snum],smoothratio,16);
        !          2726:        if (frameinterpolate == 0)
        !          2727:                { cposx = posx[snum]; cposy = posy[snum]; cposz = posz[snum]; }
        !          2728:        choriz = ohoriz[snum]+mulscale(horiz[snum]-ohoriz[snum],smoothratio,16);
        !          2729:        czoom = ozoom[snum]+mulscale(zoom[snum]-ozoom[snum],smoothratio,16);
        !          2730:        cang = oang[snum]+mulscale(((ang[snum]+1024-oang[snum])&2047)-1024,smoothratio,16);
        !          2731: 
        !          2732:        if (dimensionmode[snum] != 2)
        !          2733:        {
        !          2734:                if ((numplayers > 1) && (option[4] == 0))
        !          2735:                {
        !          2736:                                //Do not draw other views constantly if they're staying still
        !          2737:                                //It's a shame this trick will only work in screen-buffer mode
        !          2738:                                //At least screen-buffer mode covers all the HI hi-res modes
        !          2739:                        if (vidoption == 1)
        !          2740:                        {
        !          2741:                                for(i=connecthead;i>=0;i=connectpoint2[i]) frame2draw[i] = 0;
        !          2742:                                frame2draw[snum] = 1;
        !          2743: 
        !          2744:                                        //2-1,3-1,4-2
        !          2745:                                        //5-2,6-2,7-2,8-3,9-3,10-3,11-3,12-4,13-4,14-4,15-4,16-5
        !          2746:                                x1 = posx[snum]; y1 = posy[snum];
        !          2747:                                for(j=(numplayers>>2)+1;j>0;j--)
        !          2748:                                {
        !          2749:                                        maxdist = 0x80000000;
        !          2750:                                        for(i=connecthead;i>=0;i=connectpoint2[i])
        !          2751:                                                if (frame2draw[i] == 0)
        !          2752:                                                {
        !          2753:                                                        x2 = posx[i]-x1; y2 = posy[i]-y1;
        !          2754:                                                        dist = mulscale(x2,x2,12) + mulscale(y2,y2,12);
        !          2755: 
        !          2756:                                                        if (dist < 64) dist = 16384;
        !          2757:                                                        else if (dist > 16384) dist = 64;
        !          2758:                                                        else dist = 1048576 / dist;
        !          2759: 
        !          2760:                                                        dist *= frameskipcnt[i];
        !          2761: 
        !          2762:                                                                //Increase frame rate if screen is moving
        !          2763:                                                        if ((posx[i] != oposx[i]) || (posy[i] != oposy[i]) ||
        !          2764:                                                                 (posz[i] != oposz[i]) || (ang[i] != oang[i]) ||
        !          2765:                                                                 (horiz[i] != ohoriz[i])) dist += dist;
        !          2766: 
        !          2767:                                                        if (dist > maxdist) maxdist = dist, k = i;
        !          2768:                                                }
        !          2769: 
        !          2770:                                        for(i=connecthead;i>=0;i=connectpoint2[i])
        !          2771:                                                frameskipcnt[i] += (frameskipcnt[i]>>3)+1;
        !          2772:                                        frameskipcnt[k] = 0;
        !          2773: 
        !          2774:                                        frame2draw[k] = 1;
        !          2775:                                }
        !          2776:                        }
        !          2777:                        else
        !          2778:                        {
        !          2779:                                for(i=connecthead;i>=0;i=connectpoint2[i]) frame2draw[i] = 1;
        !          2780:                        }
        !          2781: 
        !          2782:                        for(i=connecthead,j=0;i>=0;i=connectpoint2[i],j++)
        !          2783:                                if (frame2draw[i] != 0)
        !          2784:                                {
        !          2785:                                        if (numplayers <= 4)
        !          2786:                                        {
        !          2787:                                                switch(j)
        !          2788:                                                {
        !          2789:                                                        case 0: setview(0,0,(xdim>>1)-1,(ydim>>1)-1); break;
        !          2790:                                                        case 1: setview((xdim>>1),0,xdim-1,(ydim>>1)-1); break;
        !          2791:                                                        case 2: setview(0,(ydim>>1),(xdim>>1)-1,ydim-1); break;
        !          2792:                                                        case 3: setview((xdim>>1),(ydim>>1),xdim-1,ydim-1); break;
        !          2793:                                                }
        !          2794:                                        }
        !          2795:                                        else
        !          2796:                                        {
        !          2797:                                                switch(j)
        !          2798:                                                {
        !          2799:                                                        case 0: setview(0,0,(xdim>>2)-1,(ydim>>2)-1); break;
        !          2800:                                                        case 1: setview(xdim>>2,0,(xdim>>1)-1,(ydim>>2)-1); break;
        !          2801:                                                        case 2: setview(xdim>>1,0,xdim-(xdim>>2)-1,(ydim>>2)-1); break;
        !          2802:                                                        case 3: setview(xdim-(xdim>>2),0,xdim-1,(ydim>>2)-1); break;
        !          2803:                                                        case 4: setview(0,ydim>>2,(xdim>>2)-1,(ydim>>1)-1); break;
        !          2804:                                                        case 5: setview(xdim>>2,ydim>>2,(xdim>>1)-1,(ydim>>1)-1); break;
        !          2805:                                                        case 6: setview(xdim>>1,ydim>>2,xdim-(xdim>>2)-1,(ydim>>1)-1); break;
        !          2806:                                                        case 7: setview(xdim-(xdim>>2),ydim>>2,xdim-1,(ydim>>1)-1); break;
        !          2807:                                                        case 8: setview(0,ydim>>1,(xdim>>2)-1,ydim-(ydim>>2)-1); break;
        !          2808:                                                        case 9: setview(xdim>>2,ydim>>1,(xdim>>1)-1,ydim-(ydim>>2)-1); break;
        !          2809:                                                        case 10: setview(xdim>>1,ydim>>1,xdim-(xdim>>2)-1,ydim-(ydim>>2)-1); break;
        !          2810:                                                        case 11: setview(xdim-(xdim>>2),ydim>>1,xdim-1,ydim-(ydim>>2)-1); break;
        !          2811:                                                        case 12: setview(0,ydim-(ydim>>2),(xdim>>2)-1,ydim-1); break;
        !          2812:                                                        case 13: setview(xdim>>2,ydim-(ydim>>2),(xdim>>1)-1,ydim-1); break;
        !          2813:                                                        case 14: setview(xdim>>1,ydim-(ydim>>2),xdim-(xdim>>2)-1,ydim-1); break;
        !          2814:                                                        case 15: setview(xdim-(xdim>>2),ydim-(ydim>>2),xdim-1,ydim-1); break;
        !          2815:                                                }
        !          2816:                                        }
        !          2817: 
        !          2818:                                        if (i == snum)
        !          2819:                                                drawrooms(cposx,cposy,cposz,cang,choriz,cursectnum[i]);
        !          2820:                                        else
        !          2821:                                                drawrooms(posx[i],posy[i],posz[i],ang[i],horiz[i],cursectnum[i]);
        !          2822:                                        analyzesprites(posx[i],posy[i]);
        !          2823:                                        drawmasks();
        !          2824:                                        if (numbombs[i] > 0)
        !          2825:                                                overwritesprite(160L,184L,GUNONBOTTOM,sector[cursectnum[i]].floorshade,1|2,0);
        !          2826: 
        !          2827:                                        if (lockclock < 384)
        !          2828:                                        {
        !          2829:                                                if (lockclock < 128)
        !          2830:                                                        rotatesprite(320<<15,200<<15,lockclock<<9,lockclock<<4,DEMOSIGN,(128-lockclock)>>2,0,1+2);
        !          2831:                                                else if (lockclock < 256)
        !          2832:                                                        rotatesprite(320<<15,200<<15,65536,0,DEMOSIGN,0,0,2);
        !          2833:                                                else
        !          2834:                                                        rotatesprite(320<<15,200<<15,(384-lockclock)<<9,lockclock<<4,DEMOSIGN,(lockclock-256)>>2,0,1+2);
        !          2835:                                        }
        !          2836: 
        !          2837:                                        if (health[i] <= 0)
        !          2838:                                                rotatesprite(320<<15,200<<15,(-health[i])<<11,(-health[i])<<5,NO,0,0,2);
        !          2839:                                }
        !          2840:                }
        !          2841:                else
        !          2842:                {
        !          2843:                                //Startdmost optimization for weapons
        !          2844:                        if ((numbombs[screenpeek] > 0) && (windowx1 == 0) && (windowx2 == 320))
        !          2845:                        {
        !          2846:                                x1 = 160L-(tilesizx[GUNONBOTTOM]>>1);
        !          2847:                                y1 = 184L-(tilesizy[GUNONBOTTOM]>>1);
        !          2848:                                for(i=0;i<tilesizx[GUNONBOTTOM];i++)
        !          2849:                                        startdmost[i+x1] = min(windowy2+1,gundmost[i]+y1);
        !          2850:                        }
        !          2851: 
        !          2852:                        drawrooms(cposx,cposy,cposz,cang,choriz,cursectnum[snum]);
        !          2853:                        analyzesprites(posx[snum],posy[snum]);
        !          2854:                        drawmasks();
        !          2855:                        if (numbombs[screenpeek] > 0)
        !          2856:                        {
        !          2857:                                        //Reset startdmost to bottom of screen
        !          2858:                                if ((windowx1 == 0) && (windowx2 == 320))
        !          2859:                                {
        !          2860:                                        x1 = 160L-(tilesizx[GUNONBOTTOM]>>1); y1 = windowy2+1;
        !          2861:                                        for(i=0;i<tilesizx[GUNONBOTTOM];i++)
        !          2862:                                                startdmost[i+x1] = y1;
        !          2863:                                }
        !          2864:                                overwritesprite(160L,184L,GUNONBOTTOM,sector[cursectnum[screenpeek]].floorshade,1|2,0);
        !          2865:                        }
        !          2866: 
        !          2867:                        if (lockclock < 384)
        !          2868:                        {
        !          2869:                                if (lockclock < 128)
        !          2870:                                        rotatesprite(320<<15,200<<15,lockclock<<9,lockclock<<4,DEMOSIGN,(128-lockclock)>>2,0,1+2);
        !          2871:                                else if (lockclock < 256)
        !          2872:                                        rotatesprite(320<<15,200<<15,65536,0,DEMOSIGN,0,0,2);
        !          2873:                                else
        !          2874:                                        rotatesprite(320<<15,200<<15,(384-lockclock)<<9,lockclock<<4,DEMOSIGN,(lockclock-256)>>2,0,1+2);
        !          2875:                        }
        !          2876: 
        !          2877:                        if (health[screenpeek] <= 0)
        !          2878:                                rotatesprite(320<<15,200<<15,(-health[screenpeek])<<11,(-health[screenpeek])<<5,NO,0,0,2);
        !          2879:                }
        !          2880:        }
        !          2881: 
        !          2882:                //Only animate lava if its picnum is on screen
        !          2883:                //gotpic is a bit array where the tile number's bit is set
        !          2884:                //whenever it is drawn (ceilings, walls, sprites, etc.)
        !          2885:        if ((gotpic[SLIME>>3]&(1<<(SLIME&7))) > 0)
        !          2886:        {
        !          2887:                gotpic[SLIME>>3] &= ~(1<<(SLIME&7));
        !          2888:                if (waloff[SLIME] != 0) movelava((char *)waloff[SLIME]);
        !          2889:        }
        !          2890: 
        !          2891:        if (dimensionmode[snum] != 3)
        !          2892:        {
        !          2893:                        //Move back pivot point
        !          2894:                cposx += (sintable[(cang+512)&2047]<<6) / czoom;
        !          2895:                cposy += (sintable[cang&2047]<<6) / czoom;
        !          2896:                if (dimensionmode[snum] == 2)
        !          2897:                {
        !          2898:                        clearview(0L);  //Clear screen to specified color
        !          2899:                        drawmapview(cposx,cposy,czoom,cang);
        !          2900:                }
        !          2901:                drawoverheadmap(cposx,cposy,czoom,cang);
        !          2902:        }
        !          2903: 
        !          2904:        if (numplayers >= 2)
        !          2905:        {
        !          2906:                        //Tell who's master or slave
        !          2907:                if (lockclock < masterslavetexttime+120)
        !          2908:                {
        !          2909:                        if (myconnectindex == connecthead)
        !          2910:                                printext256(152L,0L,31,-1,"Master",0);
        !          2911:                        else
        !          2912:                                printext256(152L,0L,31,-1,"Slave",0);
        !          2913:                }
        !          2914:        }
        !          2915: 
        !          2916:        if (typemode != 0)
        !          2917:        {
        !          2918:                charsperline = 40;
        !          2919:                //if (dimensionmode[snum] == 2) charsperline = 80;
        !          2920: 
        !          2921:                for(i=0;i<=typemessageleng;i+=charsperline)
        !          2922:                {
        !          2923:                        for(j=0;j<charsperline;j++)
        !          2924:                                tempbuf[j] = typemessage[i+j];
        !          2925:                        if (typemessageleng < i+charsperline)
        !          2926:                        {
        !          2927:                                tempbuf[(typemessageleng-i)] = '_';
        !          2928:                                tempbuf[(typemessageleng-i)+1] = 0;
        !          2929:                        }
        !          2930:                        else
        !          2931:                                tempbuf[charsperline] = 0;
        !          2932:                        //if (dimensionmode[snum] == 3)
        !          2933:                                printext256(0L,(i/charsperline)<<3,183,-1,tempbuf,0);
        !          2934:                        //else
        !          2935:                        //   printext16(0L,((i/charsperline)<<3)+(pageoffset/640),10,-1,tempbuf,0);
        !          2936:                }
        !          2937:        }
        !          2938:        else
        !          2939:        {
        !          2940:                if (dimensionmode[myconnectindex] == 3)
        !          2941:                {
        !          2942:                        templong = screensize;
        !          2943: 
        !          2944:                        if (((locbits&32) > (screensizeflag&32)) && (screensize > 64))
        !          2945:                        {
        !          2946:                                ox1 = (xdim>>1)-(screensize>>1);
        !          2947:                                ox2 = ox1+screensize-1;
        !          2948:                                oy1 = ((ydim-32)>>1)-(((screensize*(ydim-32))/xdim)>>1);
        !          2949:                                oy2 = oy1+((screensize*(ydim-32))/xdim)-1;
        !          2950:                                screensize -= (screensize>>3);
        !          2951: 
        !          2952:                                if (templong > xdim)
        !          2953:                                {
        !          2954:                                        screensize = xdim;
        !          2955: 
        !          2956:                                        permanentwritesprite((xdim-320)>>1,ydim-32,STATUSBAR,0,0,0,xdim-1,ydim-1,0);
        !          2957:                                        i = ((xdim-320)>>1);
        !          2958:                                        while (i >= 8) i -= 8, permanentwritesprite(i,ydim-32,STATUSBARFILL8,0,0,0,xdim-1,ydim-1,0);
        !          2959:                                        if (i >= 4) i -= 4, permanentwritesprite(i,ydim-32,STATUSBARFILL4,0,0,0,xdim-1,ydim-1,0);
        !          2960:                                        i = ((xdim-320)>>1)+320;
        !          2961:                                        while (i <= xdim-8) permanentwritesprite(i,ydim-32,STATUSBARFILL8,0,0,0,xdim-1,ydim-1,0), i += 8;
        !          2962:                                        if (i <= xdim-4) permanentwritesprite(i,ydim-32,STATUSBARFILL4,0,0,0,xdim-1,ydim-1,0), i += 4;
        !          2963: 
        !          2964:                                        sprintf(&tempbuf,"Deaths: %d",deaths[screenpeek]);
        !          2965:                                        printext((xdim>>1)-(strlen(tempbuf)<<2),ydim-16,tempbuf,ALPHABET,80);
        !          2966: 
        !          2967:                                        sprintf(&tempbuf,"Health: %3d",health[screenpeek]);
        !          2968:                                        printext((xdim>>1)-(strlen(tempbuf)<<2),ydim-24,tempbuf,ALPHABET,80);
        !          2969: 
        !          2970:                                        sprintf(&tempbuf,"Score:%ld",score[screenpeek]);
        !          2971:                                        printext((xdim>>1)-(strlen(tempbuf)<<2),ydim-8,tempbuf,ALPHABET,80);
        !          2972:                                }
        !          2973: 
        !          2974:                                x1 = (xdim>>1)-(screensize>>1);
        !          2975:                                x2 = x1+screensize-1;
        !          2976:                                y1 = ((ydim-32)>>1)-(((screensize*(ydim-32))/xdim)>>1);
        !          2977:                                y2 = y1+((screensize*(ydim-32))/xdim)-1;
        !          2978:                                setview(x1,y1>>detailmode,x2,y2>>detailmode);
        !          2979: 
        !          2980:                                // (ox1,oy1)�����������������Ŀ
        !          2981:                                //          ï¿½  (x1,y1)        ï¿½
        !          2982:                                //          ï¿½     �����Ŀ     �
        !          2983:                                //          ï¿½     �     �     �
        !          2984:                                //          ï¿½     �������     �
        !          2985:                                //          ï¿½        (x2,y2)  ï¿½
        !          2986:                                //          ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½(ox2,oy2)
        !          2987: 
        !          2988:                                permanentwritespritetile(0L,0L,BACKGROUND,0,ox1,oy1,x1-1,oy2,0);
        !          2989:                                permanentwritespritetile(0L,0L,BACKGROUND,0,x2+1,oy1,ox2,oy2,0);
        !          2990:                                permanentwritespritetile(0L,0L,BACKGROUND,0,x1,oy1,x2,y1-1,0);
        !          2991:                                permanentwritespritetile(0L,0L,BACKGROUND,0,x1,y2+1,x2,oy2,0);
        !          2992:                        }
        !          2993:                        if (((locbits&16) > (screensizeflag&16)) && (screensize <= xdim))
        !          2994:                        {
        !          2995:                                screensize += (screensize>>3);
        !          2996:                                if ((screensize > xdim) && (templong == xdim))
        !          2997:                                {
        !          2998:                                        screensize = xdim+1;
        !          2999:                                        x1 = 0; y1 = 0;
        !          3000:                                        x2 = xdim-1; y2 = ydim-1;
        !          3001:                                }
        !          3002:                                else
        !          3003:                                {
        !          3004:                                        if (screensize > xdim) screensize = xdim;
        !          3005:                                        x1 = (xdim>>1)-(screensize>>1);
        !          3006:                                        x2 = x1+screensize-1;
        !          3007:                                        y1 = ((ydim-32)>>1)-(((screensize*(ydim-32))/xdim)>>1);
        !          3008:                                        y2 = y1+((screensize*(ydim-32))/xdim)-1;
        !          3009:                                }
        !          3010:                                setview(x1,y1>>detailmode,x2,y2>>detailmode);
        !          3011:                        }
        !          3012:                        screensizeflag = locbits;
        !          3013:                }
        !          3014:        }
        !          3015: 
        !          3016:        if (getmessageleng > 0)
        !          3017:        {
        !          3018:                charsperline = 40;
        !          3019:                //if (dimensionmode[snum] == 2) charsperline = 80;
        !          3020: 
        !          3021:                for(i=0;i<=getmessageleng;i+=charsperline)
        !          3022:                {
        !          3023:                        for(j=0;j<charsperline;j++)
        !          3024:                                tempbuf[j] = getmessage[i+j];
        !          3025:                        if (getmessageleng < i+charsperline)
        !          3026:                                tempbuf[(getmessageleng-i)] = 0;
        !          3027:                        else
        !          3028:                                tempbuf[charsperline] = 0;
        !          3029: 
        !          3030:                        printext256(0L,((i/charsperline)<<3)+(200-32-8)-(((getmessageleng-1)/charsperline)<<3),151,-1,tempbuf,0);
        !          3031:                }
        !          3032:                if (totalclock > getmessagetimeoff)
        !          3033:                        getmessageleng = 0;
        !          3034:        }
        !          3035:        if ((numplayers >= 2) && (screenpeek != myconnectindex))
        !          3036:        {
        !          3037:                strcpy(tempbuf,"Other");
        !          3038: 
        !          3039:                //if (dimensionmode[snum] == 3)
        !          3040:                        printext256((xdim>>1)-(strlen(tempbuf)<<2),0,24,-1,tempbuf,0);
        !          3041:                //else
        !          3042:                //   printext16(xdim-(strlen(tempbuf)<<2),(pageoffset/640),7,-1,tempbuf,0);
        !          3043:        }
        !          3044: 
        !          3045:        if (syncstat != 0) printext256(68L,84L,31,0,"OUT OF SYNC!",0);
        !          3046:        if (syncstate != 0) printext256(68L,92L,31,0,"Missed Network packet!",0);
        !          3047: 
        !          3048:        nextpage();
        !          3049: 
        !          3050:        if (keystatus[0x3f] > 0)   //F5
        !          3051:        {
        !          3052:                keystatus[0x3f] = 0;
        !          3053:                detailmode ^= 1;
        !          3054:                if (detailmode == 0)
        !          3055:                {
        !          3056:                        setview(windowx1,windowy1<<1,windowx2,(windowy2<<1)+1);
        !          3057:                        outp(0x3d4,0x9); outp(0x3d5,(inp(0x3d5)&~31)|1);
        !          3058:                }
        !          3059:                else
        !          3060:                {
        !          3061:                        setview(windowx1,windowy1>>detailmode,windowx2,windowy2>>detailmode);
        !          3062:                        setaspect(yxaspect>>1);
        !          3063:                        outp(0x3d4,0x9); outp(0x3d5,(inp(0x3d5)&~31)|3);
        !          3064:                }
        !          3065:        }
        !          3066:        if (keystatus[0x58] > 0)   //F12
        !          3067:        {
        !          3068:                keystatus[0x58] = 0;
        !          3069:                screencapture("captxxxx.pcx",keystatus[0x2a]|keystatus[0x36]);
        !          3070:        }
        !          3071:        if (stereofps != 0)  //Adjustments for red-blue / 120 crystal eyes modes
        !          3072:        {
        !          3073:                if ((keystatus[0x2a]|keystatus[0x36]) > 0)
        !          3074:                {
        !          3075:                        if (keystatus[0x1a] > 0) stereopixelwidth--;   //Shift [
        !          3076:                        if (keystatus[0x1b] > 0) stereopixelwidth++;   //Shift ]
        !          3077:                }
        !          3078:                else
        !          3079:                {
        !          3080:                        if (keystatus[0x1a] > 0) stereowidth -= 512;   //[
        !          3081:                        if (keystatus[0x1b] > 0) stereowidth += 512;   //]
        !          3082:                }
        !          3083:        }
        !          3084: 
        !          3085:        if (option[4] == 0)           //Single player only keys
        !          3086:        {
        !          3087:                if (keystatus[0xd2] > 0)   //Insert - Insert player
        !          3088:                {
        !          3089:                        keystatus[0xd2] = 0;
        !          3090:                        if (numplayers < MAXPLAYERS)
        !          3091:                        {
        !          3092:                                connectpoint2[numplayers-1] = numplayers;
        !          3093:                                connectpoint2[numplayers] = -1;
        !          3094: 
        !          3095:                                initplayersprite(numplayers);
        !          3096: 
        !          3097:                                clearallviews(0L);  //Clear screen to specified color
        !          3098: 
        !          3099:                                numplayers++;
        !          3100:                        }
        !          3101:                }
        !          3102:                if (keystatus[0xd3] > 0)   //Delete - Delete player
        !          3103:                {
        !          3104:                        keystatus[0xd3] = 0;
        !          3105:                        if (numplayers > 1)
        !          3106:                        {
        !          3107:                                numplayers--;
        !          3108:                                connectpoint2[numplayers-1] = -1;
        !          3109: 
        !          3110:                                deletesprite(playersprite[numplayers]);
        !          3111:                                playersprite[numplayers] = -1;
        !          3112: 
        !          3113:                                if (myconnectindex >= numplayers) myconnectindex = 0;
        !          3114:                                if (screenpeek >= numplayers) screenpeek = 0;
        !          3115: 
        !          3116:                                if (numplayers < 2)
        !          3117:                                        setup3dscreen();
        !          3118:                                else
        !          3119:                                        clearallviews(0L);  //Clear screen to specified color
        !          3120:                        }
        !          3121:                }
        !          3122:                if (keystatus[0x46] > 0)   //Scroll Lock
        !          3123:                {
        !          3124:                        keystatus[0x46] = 0;
        !          3125: 
        !          3126:                        myconnectindex = connectpoint2[myconnectindex];
        !          3127:                        if (myconnectindex < 0) myconnectindex = connecthead;
        !          3128:                        screenpeek = myconnectindex;
        !          3129:                }
        !          3130:        }
        !          3131: }
        !          3132: 
        !          3133: movethings()
        !          3134: {
        !          3135:        long i;
        !          3136: 
        !          3137:        gotlastpacketclock = totalclock;
        !          3138:        for(i=connecthead;i>=0;i=connectpoint2[i])
        !          3139:        {
        !          3140:                baksyncvel[movefifoend][i] = fsyncvel[i];
        !          3141:                baksyncsvel[movefifoend][i] = fsyncsvel[i];
        !          3142:                baksyncangvel[movefifoend][i] = fsyncangvel[i];
        !          3143:                baksyncbits[movefifoend][i] = fsyncbits[i];
        !          3144:        }
        !          3145:        movefifoend = ((movefifoend+1)&(MOVEFIFOSIZ-1));
        !          3146: 
        !          3147:                //Do this for Master/Slave switching
        !          3148:        for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i])
        !          3149:                if (syncbits[i]&512) ready2send = 0;
        !          3150: }
        !          3151: 
        !          3152: domovethings()
        !          3153: {
        !          3154:        short i, j, startwall, endwall;
        !          3155:        spritetype *spr;
        !          3156:        walltype *wal;
        !          3157:        point3d *ospr;
        !          3158: 
        !          3159:        for(i=connecthead;i>=0;i=connectpoint2[i])
        !          3160:        {
        !          3161:                syncvel[i] = baksyncvel[movefifoplc][i];
        !          3162:                syncsvel[i] = baksyncsvel[movefifoplc][i];
        !          3163:                syncangvel[i] = baksyncangvel[movefifoplc][i];
        !          3164:                syncbits[i] = baksyncbits[movefifoplc][i];
        !          3165:        }
        !          3166:        movefifoplc = ((movefifoplc+1)&(MOVEFIFOSIZ-1));
        !          3167: 
        !          3168:        syncval[syncvalend] = getsyncstat();
        !          3169:        syncvalend = ((syncvalend+1)&(MOVEFIFOSIZ-1));
        !          3170: 
        !          3171:        for(i=connecthead;i>=0;i=connectpoint2[i])
        !          3172:        {
        !          3173:                oposx[i] = posx[i];
        !          3174:                oposy[i] = posy[i];
        !          3175:                oposz[i] = posz[i];
        !          3176:                ohoriz[i] = horiz[i];
        !          3177:                ozoom[i] = zoom[i];
        !          3178:                oang[i] = ang[i];
        !          3179:        }
        !          3180: 
        !          3181:        for(i=1;i<=8;i++)
        !          3182:                if (i != 2)
        !          3183:                        for(j=headspritestat[i];j>=0;j=nextspritestat[j])
        !          3184:                                copybuf(&sprite[j].x,&osprite[j].x,3);
        !          3185: 
        !          3186:        for(i=connecthead;i>=0;i=connectpoint2[i])
        !          3187:                ocursectnum[i] = cursectnum[i];
        !          3188: 
        !          3189:        if ((numplayers <= 2) && (recstat == 1))
        !          3190:        {
        !          3191:                j = 0;
        !          3192:                for(i=connecthead;i>=0;i=connectpoint2[i])
        !          3193:                {
        !          3194:                        recsyncvel[reccnt][j] = syncvel[i];
        !          3195:                        recsyncsvel[reccnt][j] = syncsvel[i];
        !          3196:                        recsyncangvel[reccnt][j] = syncangvel[i];
        !          3197:                        recsyncbits[reccnt][j] = syncbits[i];
        !          3198:                        j++;
        !          3199:                }
        !          3200:                reccnt++; if (reccnt > 16383) reccnt = 16383;
        !          3201:        }
        !          3202: 
        !          3203:        lockclock += TICSPERFRAME;
        !          3204: 
        !          3205:        for(i=connecthead;i>=0;i=connectpoint2[i])
        !          3206:        {
        !          3207:                processinput(i);                        //Move player
        !          3208: 
        !          3209:                checktouchsprite(i,cursectnum[i]);      //Pick up coins
        !          3210:                startwall = sector[cursectnum[i]].wallptr;
        !          3211:                endwall = startwall + sector[cursectnum[i]].wallnum;
        !          3212:                for(j=startwall,wal=&wall[j];j<endwall;j++,wal++)
        !          3213:                        if (wal->nextsector >= 0) checktouchsprite(i,wal->nextsector);
        !          3214:        }
        !          3215: 
        !          3216:        doanimations();
        !          3217:        tagcode();            //Door code, moving sector code, other stuff
        !          3218:        statuslistcode();     //Monster / bullet code / explosions
        !          3219: 
        !          3220:        checkmasterslaveswitch();
        !          3221: }
        !          3222: 
        !          3223: getinput()
        !          3224: {
        !          3225:        char ch, keystate, *ptr;
        !          3226:        long i, j, k;
        !          3227:        short mousx, mousy, bstatus;
        !          3228: 
        !          3229:        if (typemode == 0)           //if normal game keys active
        !          3230:        {
        !          3231:                if ((keystatus[0x2a]&keystatus[0x36]&keystatus[0x13]) > 0)   //Sh.Sh.R (replay)
        !          3232:                {
        !          3233:                        keystatus[0x13] = 0;
        !          3234:                        playback();
        !          3235:                }
        !          3236: 
        !          3237:                if ((keystatus[0x26]&(keystatus[0x1d]|keystatus[0x9d])) > 0) //Load game
        !          3238:                {
        !          3239:                        keystatus[0x26] = 0;
        !          3240:                        loadgame();
        !          3241:                }
        !          3242: 
        !          3243:                if ((keystatus[0x1f]&(keystatus[0x1d]|keystatus[0x9d])) > 0) //Save game
        !          3244:                {
        !          3245:                        keystatus[0x1f] = 0;
        !          3246:                        savegame();
        !          3247:                }
        !          3248: 
        !          3249:                if (keystatus[keys[15]] > 0)
        !          3250:                {
        !          3251:                        keystatus[keys[15]] = 0;
        !          3252: 
        !          3253:                        screenpeek = connectpoint2[screenpeek];
        !          3254:                        if (screenpeek < 0) screenpeek = connecthead;
        !          3255:                }
        !          3256: 
        !          3257:                for(i=7;i>=0;i--)
        !          3258:                        if (keystatus[i+2] > 0)
        !          3259:                                { keystatus[i+2] = 0; locselectedgun = i; break; }
        !          3260:        }
        !          3261: 
        !          3262: 
        !          3263:                //KEYTIMERSTUFF
        !          3264:        if (keystatus[keys[5]] == 0)
        !          3265:        {
        !          3266:                if (keystatus[keys[2]] > 0) angvel = max(angvel-16*TICSPERFRAME,-128);
        !          3267:                if (keystatus[keys[3]] > 0) angvel = min(angvel+16*TICSPERFRAME,127);
        !          3268:        }
        !          3269:        else
        !          3270:        {
        !          3271:                if (keystatus[keys[2]] > 0) svel = min(svel+8*TICSPERFRAME,127);
        !          3272:                if (keystatus[keys[3]] > 0) svel = max(svel-8*TICSPERFRAME,-128);
        !          3273:        }
        !          3274:        if (keystatus[keys[0]] > 0) vel = min(vel+8*TICSPERFRAME,127);
        !          3275:        if (keystatus[keys[1]] > 0) vel = max(vel-8*TICSPERFRAME,-128);
        !          3276:        if (keystatus[keys[12]] > 0) svel = min(svel+8*TICSPERFRAME,127);
        !          3277:        if (keystatus[keys[13]] > 0) svel = max(svel-8*TICSPERFRAME,-128);
        !          3278: 
        !          3279:        if (angvel < 0) angvel = min(angvel+12*TICSPERFRAME,0);
        !          3280:        if (angvel > 0) angvel = max(angvel-12*TICSPERFRAME,0);
        !          3281:        if (svel < 0) svel = min(svel+2*TICSPERFRAME,0);
        !          3282:        if (svel > 0) svel = max(svel-2*TICSPERFRAME,0);
        !          3283:        if (vel < 0) vel = min(vel+2*TICSPERFRAME,0);
        !          3284:        if (vel > 0) vel = max(vel-2*TICSPERFRAME,0);
        !          3285: 
        !          3286:        if ((option[4] == 0) && (numplayers == 2))
        !          3287:        {
        !          3288:                if (keystatus[0x4f] == 0)
        !          3289:                {
        !          3290:                        if (keystatus[0x4b] > 0) angvel2 = max(angvel2-16*TICSPERFRAME,-128);
        !          3291:                        if (keystatus[0x4d] > 0) angvel2 = min(angvel2+16*TICSPERFRAME,127);
        !          3292:                }
        !          3293:                else
        !          3294:                {
        !          3295:                        if (keystatus[0x4b] > 0) svel2 = min(svel2+8*TICSPERFRAME,127);
        !          3296:                        if (keystatus[0x4d] > 0) svel2 = max(svel2-8*TICSPERFRAME,-128);
        !          3297:                }
        !          3298:                if (keystatus[0x48] > 0) vel2 = min(vel2+8*TICSPERFRAME,127);
        !          3299:                if (keystatus[0x4c] > 0) vel2 = max(vel2-8*TICSPERFRAME,-128);
        !          3300: 
        !          3301:                if (angvel2 < 0) angvel2 = min(angvel2+12*TICSPERFRAME,0);
        !          3302:                if (angvel2 > 0) angvel2 = max(angvel2-12*TICSPERFRAME,0);
        !          3303:                if (svel2 < 0) svel2 = min(svel2+2*TICSPERFRAME,0);
        !          3304:                if (svel2 > 0) svel2 = max(svel2-2*TICSPERFRAME,0);
        !          3305:                if (vel2 < 0) vel2 = min(vel2+2*TICSPERFRAME,0);
        !          3306:                if (vel2 > 0) vel2 = max(vel2-2*TICSPERFRAME,0);
        !          3307:        }
        !          3308: 
        !          3309:        locvel = min(max(vel,-128+8),127-8);
        !          3310:        locsvel = min(max(svel,-128+8),127-8);
        !          3311:        locangvel = min(max(angvel,-128+16),127-16);
        !          3312: 
        !          3313:        getmousevalues(&mousx,&mousy,&bstatus);
        !          3314:        locangvel = min(max(locangvel+(mousx<<3),-128),127);
        !          3315:        locvel = min(max(locvel-(mousy<<3),-128),127);
        !          3316: 
        !          3317:        locbits = (locselectedgun<<13);
        !          3318:        if (typemode == 0)           //if normal game keys active
        !          3319:        {
        !          3320:                locbits |= (keystatus[0x32]<<9);                 //M (be master)
        !          3321:                locbits |= ((keystatus[keys[14]]==1)<<12);       //Map mode
        !          3322:        }
        !          3323:        locbits |= keystatus[keys[8]];                   //Stand high
        !          3324:        locbits |= (keystatus[keys[9]]<<1);              //Stand low
        !          3325:        locbits |= (keystatus[keys[16]]<<4);             //Zoom in
        !          3326:        locbits |= (keystatus[keys[17]]<<5);             //Zoom out
        !          3327:        locbits |= (keystatus[keys[4]]<<8);                 //Run
        !          3328:        locbits |= (keystatus[keys[10]]<<2);                //Look up
        !          3329:        locbits |= (keystatus[keys[11]]<<3);                //Look down
        !          3330:        locbits |= ((keystatus[keys[7]]==1)<<10);           //Space
        !          3331:        locbits |= ((keystatus[keys[6]]==1)<<11);           //Shoot
        !          3332:        locbits |= (((bstatus&6)>(oldmousebstatus&6))<<10); //Space
        !          3333:        locbits |= (((bstatus&1)>(oldmousebstatus&1))<<11); //Shoot
        !          3334: 
        !          3335:        oldmousebstatus = bstatus;
        !          3336:        if (((locbits&2048) > 0) && (locselectedgun == 1))
        !          3337:                oldmousebstatus &= ~1;     //Allow continous fire with mouse for chain gun
        !          3338: 
        !          3339:                //PRIVATE KEYS:
        !          3340:        if (keystatus[0xb7] > 0)  //Printscreen
        !          3341:        {
        !          3342:                keystatus[0xb7] = 0;
        !          3343:                printscreeninterrupt();
        !          3344:        }
        !          3345:        if (keystatus[0x57] > 0)  //F11 - brightness
        !          3346:        {
        !          3347:                keystatus[0x57] = 0;
        !          3348:                brightness++;
        !          3349:                if (brightness > 8) brightness = 0;
        !          3350:                setbrightness(brightness);
        !          3351:        }
        !          3352: 
        !          3353:        if (typemode == 0)           //if normal game keys active
        !          3354:        {
        !          3355:                if (keystatus[0x19] > 0)  //P
        !          3356:                {
        !          3357:                        keystatus[0x19] = 0;
        !          3358:                        parallaxtype++;
        !          3359:                        if (parallaxtype > 2) parallaxtype = 0;
        !          3360:                }
        !          3361:                if ((keystatus[0x38]|keystatus[0xb8]) > 0)  //ALT
        !          3362:                {
        !          3363:                        if (keystatus[0x4a] > 0)  // Keypad -
        !          3364:                                visibility = min(visibility+(visibility>>3),16384);
        !          3365:                        if (keystatus[0x4e] > 0)  // Keypad +
        !          3366:                                visibility = max(visibility-(visibility>>3),128);
        !          3367:                }
        !          3368: 
        !          3369:                /*if ((option[1] == 1) && (option[4] >= 5))
        !          3370:                {
        !          3371:                        if ((keystatus[0x13] > 0) && (recsnddone == 1) && (recording == -2))      //R (record)
        !          3372:                        {
        !          3373:                                wrec(32768L);
        !          3374:                                recording = -1;
        !          3375:                        }
        !          3376:                        if ((recording == -1) && ((keystatus[0x13] == 0) || (recsnddone == 1)))
        !          3377:                        {
        !          3378:                                continueplay();
        !          3379:                                recsnddone = 1;
        !          3380:                                recording = 0;
        !          3381:                                wsay("recordedvoice",2972L,255L,255L);
        !          3382:                        }
        !          3383:                        if ((recording >= 0) && (screenpeek != myconnectindex))
        !          3384:                        {
        !          3385:                                tempbuf[0] = 3;
        !          3386: 
        !          3387:                                ptr = (char *)(recsndoffs+recording);
        !          3388:                                for(i=0;i<256;i++)
        !          3389:                                        tempbuf[i+1] = *ptr++;
        !          3390:                                recording += 256;
        !          3391: 
        !          3392:                                sendpacket(screenpeek,tempbuf,257L);
        !          3393:                                if (recording >= 32768)
        !          3394:                                        recording = -2;
        !          3395:                        }
        !          3396:                }*/
        !          3397: 
        !          3398:                if ((keystatus[keys[18]]) > 0)   //Typing mode
        !          3399:                {
        !          3400:                        keystatus[keys[18]] = 0;
        !          3401:                        typemode = 1;
        !          3402:                        keyfifoplc = keyfifoend;      //Reset keyboard fifo
        !          3403:                }
        !          3404:        }
        !          3405:        else
        !          3406:        {
        !          3407:                while (keyfifoplc != keyfifoend)
        !          3408:                {
        !          3409:                        ch = keyfifo[keyfifoplc];
        !          3410:                        keystate = keyfifo[(keyfifoplc+1)&(KEYFIFOSIZ-1)];
        !          3411:                        keyfifoplc = ((keyfifoplc+2)&(KEYFIFOSIZ-1));
        !          3412: 
        !          3413:                        if (keystate != 0)
        !          3414:                        {
        !          3415:                                if (ch == 0xe)   //Backspace
        !          3416:                                {
        !          3417:                                        if (typemessageleng == 0) { typemode = 0; break; }
        !          3418:                                        typemessageleng--;
        !          3419:                                }
        !          3420:                                if (ch == 0xf)
        !          3421:                                {
        !          3422:                                        keystatus[0xf] = 0;
        !          3423:                                        typemode = 0;
        !          3424:                                        break;
        !          3425:                                }
        !          3426:                                if ((ch == 0x1c) || (ch == 0x9c))  //Either ENTER
        !          3427:                                {
        !          3428:                                        keystatus[0x1c] = 0; keystatus[0x9c] = 0;
        !          3429:                                        if (typemessageleng > 0)
        !          3430:                                        {
        !          3431:                                                tempbuf[0] = 2;          //Sending text is message type 4
        !          3432:                                                for(j=typemessageleng-1;j>=0;j--)
        !          3433:                                                        tempbuf[j+1] = typemessage[j];
        !          3434: 
        !          3435:                                                for(i=connecthead;i>=0;i=connectpoint2[i])
        !          3436:                                                        if (i != myconnectindex)
        !          3437:                                                                sendpacket(i,tempbuf,typemessageleng+1);
        !          3438: 
        !          3439:                                                typemessageleng = 0;
        !          3440:                                        }
        !          3441:                                        typemode = 0;
        !          3442:                                        break;
        !          3443:                                }
        !          3444: 
        !          3445:                                if ((typemessageleng < 159) && (ch < 128))
        !          3446:                                {
        !          3447:                                        if ((keystatus[0x2a]|keystatus[0x36]) != 0)
        !          3448:                                                ch = scantoascwithshift[ch];
        !          3449:                                        else
        !          3450:                                                ch = scantoasc[ch];
        !          3451: 
        !          3452:                                        if (ch != 0) typemessage[typemessageleng++] = ch;
        !          3453:                                }
        !          3454:                        }
        !          3455:                }
        !          3456:                        //Here's a trick of making key repeat after a 1/2 second
        !          3457:                if (keystatus[0xe] > 0)
        !          3458:                {
        !          3459:                        if (keystatus[0xe] < 30)
        !          3460:                                keystatus[0xe] += TICSPERFRAME;
        !          3461:                        else
        !          3462:                        {
        !          3463:                                if (typemessageleng == 0)
        !          3464:                                        typemode = 0;
        !          3465:                                else
        !          3466:                                        typemessageleng--;
        !          3467:                        }
        !          3468:                }
        !          3469:        }
        !          3470: }
        !          3471: 
        !          3472: initplayersprite(short snum)
        !          3473: {
        !          3474:        long i;
        !          3475: 
        !          3476:        if (playersprite[snum] >= 0) return;
        !          3477: 
        !          3478:        spawnsprite(playersprite[snum],posx[snum],posy[snum],posz[snum]+(32<<8),
        !          3479:                1+256,0,snum,32,64,64,0,0,DOOMGUY,ang[snum],0,0,0,snum+4096,
        !          3480:                cursectnum[snum],8,0,0,0);
        !          3481: 
        !          3482:        switch(snum)
        !          3483:        {
        !          3484:                case 1: for(i=0;i<32;i++) tempbuf[i+192] = i+128; break; //green->red
        !          3485:                case 2: for(i=0;i<32;i++) tempbuf[i+192] = i+32; break;  //green->blue
        !          3486:                case 3: for(i=0;i<32;i++) tempbuf[i+192] = i+224; break; //green->pink
        !          3487:                case 4: for(i=0;i<32;i++) tempbuf[i+192] = i+64; break;  //green->brown
        !          3488:                case 5: for(i=0;i<32;i++) tempbuf[i+192] = i+96; break;
        !          3489:                case 6: for(i=0;i<32;i++) tempbuf[i+192] = i+160; break;
        !          3490:                case 7: for(i=0;i<32;i++) tempbuf[i+192] = i+192; break;
        !          3491:                default: for(i=0;i<256;i++) tempbuf[i] = i; break;
        !          3492:        }
        !          3493:        makepalookup(snum,tempbuf,0,0,0,1);
        !          3494: }
        !          3495: 
        !          3496: playback()
        !          3497: {
        !          3498:        long i, j, k;
        !          3499: 
        !          3500:        ready2send = 0;
        !          3501:        recstat = 0; i = reccnt;
        !          3502:        while (keystatus[1] == 0)
        !          3503:        {
        !          3504:                while (totalclock >= lockclock+TICSPERFRAME)
        !          3505:                {
        !          3506:                        if (i >= reccnt)
        !          3507:                        {
        !          3508:                                prepareboard(boardfilename);
        !          3509:                                for(i=connecthead;i>=0;i=connectpoint2[i])
        !          3510:                                        initplayersprite((short)i);
        !          3511:                                resettiming(); ototalclock = 0; gotlastpacketclock = 0;
        !          3512:                                i = 0;
        !          3513:                        }
        !          3514: 
        !          3515:                        k = 0;
        !          3516:                        for(j=connecthead;j>=0;j=connectpoint2[j])
        !          3517:                        {
        !          3518:                                fsyncvel[j] = recsyncvel[i][k];
        !          3519:                                fsyncsvel[j] = recsyncsvel[i][k];
        !          3520:                                fsyncangvel[j] = recsyncangvel[i][k];
        !          3521:                                fsyncbits[j] = recsyncbits[i][k];
        !          3522:                                k++;
        !          3523:                        }
        !          3524:                        movethings(); domovethings();
        !          3525:                        i++;
        !          3526:                }
        !          3527:                drawscreen(screenpeek,(totalclock-lockclock)*(65536/TICSPERFRAME));
        !          3528: 
        !          3529:                if (keystatus[keys[15]] > 0)
        !          3530:                {
        !          3531:                        keystatus[keys[15]] = 0;
        !          3532: 
        !          3533:                        screenpeek = connectpoint2[screenpeek];
        !          3534:                        if (screenpeek < 0) screenpeek = connecthead;
        !          3535:                }
        !          3536:                if (keystatus[keys[14]] > 0)
        !          3537:                {
        !          3538:                        keystatus[keys[14]] = 0;
        !          3539:                        dimensionmode[screenpeek]++;
        !          3540:                        if (dimensionmode[screenpeek] > 3) dimensionmode[screenpeek] = 1;
        !          3541:                        if (dimensionmode[screenpeek] == 2) setview(0L,0L,xdim-1,(ydim-1)>>detailmode);
        !          3542:                        if (dimensionmode[screenpeek] == 3) setup3dscreen();
        !          3543:                }
        !          3544:        }
        !          3545: 
        !          3546:        musicoff();
        !          3547:        uninitmultiplayers();
        !          3548:        uninittimer();
        !          3549:        uninitkeys();
        !          3550:        uninitengine();
        !          3551:        uninitsb();
        !          3552:        uninitgroupfile();
        !          3553:        setvmode(0x3);        //Set back to text mode
        !          3554:        exit(0);
        !          3555: }
        !          3556: 
        !          3557: setup3dscreen()
        !          3558: {
        !          3559:        long i, dax, day, dax2, day2;
        !          3560: 
        !          3561:        setgamemode();
        !          3562: 
        !          3563:        if (screensize > xdim)
        !          3564:        {
        !          3565:                dax = 0; day = 0;
        !          3566:                dax2 = xdim-1; day2 = ydim-1;
        !          3567:        }
        !          3568:        else
        !          3569:        {
        !          3570:                dax = (xdim>>1)-(screensize>>1);
        !          3571:                dax2 = dax+screensize-1;
        !          3572:                day = ((ydim-32)>>1)-(((screensize*(ydim-32))/xdim)>>1);
        !          3573:                day2 = day + ((screensize*(ydim-32))/xdim)-1;
        !          3574:                setview(dax,day>>detailmode,dax2,day2>>detailmode);
        !          3575:        }
        !          3576: 
        !          3577:        if (screensize < xdim)
        !          3578:                permanentwritespritetile(0L,0L,BACKGROUND,0,0L,0L,xdim-1,ydim-1,0);      //Draw background
        !          3579: 
        !          3580:        if (screensize <= xdim)
        !          3581:        {
        !          3582:                permanentwritesprite((xdim-320)>>1,ydim-32,STATUSBAR,0,0,0,xdim-1,ydim-1,0);
        !          3583:                i = ((xdim-320)>>1);
        !          3584:                while (i >= 8) i -= 8, permanentwritesprite(i,ydim-32,STATUSBARFILL8,0,0,0,xdim-1,ydim-1,0);
        !          3585:                if (i >= 4) i -= 4, permanentwritesprite(i,ydim-32,STATUSBARFILL4,0,0,0,xdim-1,ydim-1,0);
        !          3586:                i = ((xdim-320)>>1)+320;
        !          3587:                while (i <= xdim-8) permanentwritesprite(i,ydim-32,STATUSBARFILL8,0,0,0,xdim-1,ydim-1,0), i += 8;
        !          3588:                if (i <= xdim-4) permanentwritesprite(i,ydim-32,STATUSBARFILL4,0,0,0,xdim-1,ydim-1,0), i += 4;
        !          3589: 
        !          3590:                sprintf(&tempbuf,"Deaths: %d",deaths[screenpeek]);
        !          3591:                printext((xdim>>1)-(strlen(tempbuf)<<2),ydim-16,tempbuf,ALPHABET,80);
        !          3592: 
        !          3593:                sprintf(&tempbuf,"Health: %3d",health[screenpeek]);
        !          3594:                printext((xdim>>1)-(strlen(tempbuf)<<2),ydim-24,tempbuf,ALPHABET,80);
        !          3595: 
        !          3596:                sprintf(&tempbuf,"Score:%ld",score[screenpeek]);
        !          3597:                printext((xdim>>1)-(strlen(tempbuf)<<2),ydim-8,tempbuf,ALPHABET,80);
        !          3598:        }
        !          3599: }
        !          3600: 
        !          3601: findrandomspot(long *x, long *y, short *sectnum)
        !          3602: {
        !          3603:        short startwall, endwall, s;
        !          3604:        long dax, day, minx, maxx, miny, maxy, cnt, k;
        !          3605: 
        !          3606:        cnt = 256;
        !          3607:        while (cnt > 0)
        !          3608:        {
        !          3609:                do
        !          3610:                {
        !          3611:                        k = mulscale(krand(),numsectors,16);
        !          3612:                } while ((sector[k].ceilingz >= sector[k].floorz) || (sector[k].lotag != 0) || ((sector[k].floorstat&2) != 0));
        !          3613: 
        !          3614:                startwall = sector[k].wallptr;
        !          3615:                endwall = startwall+sector[k].wallnum-1;
        !          3616:                if (endwall > startwall)
        !          3617:                {
        !          3618:                        dax = 0L;
        !          3619:                        day = 0L;
        !          3620:                        minx = 0x7fffffff; maxx = 0x80000000;
        !          3621:                        miny = 0x7fffffff; maxy = 0x80000000;
        !          3622: 
        !          3623:                        for(s=startwall;s<=endwall;s++)
        !          3624:                        {
        !          3625:                                dax += wall[s].x;
        !          3626:                                day += wall[s].y;
        !          3627:                                if (wall[s].x < minx) minx = wall[s].x;
        !          3628:                                if (wall[s].x > maxx) maxx = wall[s].x;
        !          3629:                                if (wall[s].y < miny) miny = wall[s].y;
        !          3630:                                if (wall[s].y > maxy) maxy = wall[s].y;
        !          3631:                        }
        !          3632:                        if ((maxx-minx > 256) && (maxy-miny > 256))
        !          3633:                        {
        !          3634:                                dax /= (endwall-startwall+1);
        !          3635:                                day /= (endwall-startwall+1);
        !          3636:                                if (inside(dax,day,k) == 1)
        !          3637:                                {
        !          3638:                                        *x = dax;
        !          3639:                                        *y = day;
        !          3640:                                        *sectnum = k;
        !          3641:                                        return;
        !          3642:                                }
        !          3643:                        }
        !          3644:                }
        !          3645:                cnt--;
        !          3646:        }
        !          3647: }
        !          3648: 
        !          3649: warp(long *x, long *y, long *z, short *daang, short *dasector)
        !          3650: {
        !          3651:        short startwall, endwall, s;
        !          3652:        long i, j, dax, day, ox, oy;
        !          3653: 
        !          3654:        ox = *x; oy = *y;
        !          3655: 
        !          3656:        for(i=0;i<warpsectorcnt;i++)
        !          3657:                if (warpsectorlist[i] == *dasector)
        !          3658:                {
        !          3659:                        j = sector[*dasector].hitag;
        !          3660:                        do
        !          3661:                        {
        !          3662:                                i++;
        !          3663:                                if (i >= warpsectorcnt) i = 0;
        !          3664:                        } while (sector[warpsectorlist[i]].hitag != j);
        !          3665:                        *dasector = warpsectorlist[i];
        !          3666:                        break;
        !          3667:                }
        !          3668: 
        !          3669:                //Find center of sector
        !          3670:        startwall = sector[*dasector].wallptr;
        !          3671:        endwall = startwall+sector[*dasector].wallnum-1;
        !          3672:        dax = 0L, day = 0L;
        !          3673:        for(s=startwall;s<=endwall;s++)
        !          3674:        {
        !          3675:                dax += wall[s].x, day += wall[s].y;
        !          3676:                if (wall[s].nextsector >= 0)
        !          3677:                        i = s;
        !          3678:        }
        !          3679:        *x = dax / (endwall-startwall+1);
        !          3680:        *y = day / (endwall-startwall+1);
        !          3681:        *z = sector[*dasector].floorz-(32<<8);
        !          3682:        updatesector(*x,*y,dasector);
        !          3683:        dax = ((wall[i].x+wall[wall[i].point2].x)>>1);
        !          3684:        day = ((wall[i].y+wall[wall[i].point2].y)>>1);
        !          3685:        *daang = getangle(dax-*x,day-*y);
        !          3686: 
        !          3687:        wsayfollow("warp.wav",3072L+(krand()&127)-64,192L,&ox,&oy,0);
        !          3688:        wsayfollow("warp.wav",4096L+(krand()&127)-64,256L,x,y,0);
        !          3689: }
        !          3690: 
        !          3691: warpsprite(short spritenum)
        !          3692: {
        !          3693:        short dasectnum;
        !          3694: 
        !          3695:        dasectnum = sprite[spritenum].sectnum;
        !          3696:        warp(&sprite[spritenum].x,&sprite[spritenum].y,&sprite[spritenum].z,
        !          3697:                  &sprite[spritenum].ang,&dasectnum);
        !          3698: 
        !          3699:        copybuf(&sprite[spritenum].x,&osprite[spritenum].x,3);
        !          3700:        changespritesect(spritenum,dasectnum);
        !          3701: }
        !          3702: 
        !          3703: initlava()
        !          3704: {
        !          3705:        long x, y, z, r;
        !          3706: 
        !          3707:        for(x=-16;x<=16;x++)
        !          3708:                for(y=-16;y<=16;y++)
        !          3709:                {
        !          3710:                        r = ksqrt(x*x + y*y);
        !          3711:                        lavaradx[r][lavaradcnt[r]] = x;
        !          3712:                        lavarady[r][lavaradcnt[r]] = y;
        !          3713:                        lavaradcnt[r]++;
        !          3714:                }
        !          3715: 
        !          3716:        for(z=0;z<16;z++)
        !          3717:                lavadropsizlookup[z] = 8 / (ksqrt(z)+1);
        !          3718: 
        !          3719:        for(z=0;z<LAVASIZ;z++)
        !          3720:                lavainc[z] = klabs((((z^17)>>4)&7)-4)+12;
        !          3721: 
        !          3722:        lavanumdrops = 0;
        !          3723:        lavanumframes = 0;
        !          3724: }
        !          3725: 
        !          3726: movelava(char *dapic)
        !          3727: {
        !          3728:        char dat, *ptr;
        !          3729:        long x, y, z, zx, dalavadropsiz, dadropsizlookup, offs, offs2;
        !          3730:        long dalavax, dalavay;
        !          3731: 
        !          3732:        z = 3;
        !          3733:        if (lavanumdrops+z >= LAVAMAXDROPS)
        !          3734:                z = LAVAMAXDROPS-lavanumdrops-1;
        !          3735:        while (z >= 0)
        !          3736:        {
        !          3737:                lavadropx[lavanumdrops] = (rand()&(LAVASIZ-1));
        !          3738:                lavadropy[lavanumdrops] = (rand()&(LAVASIZ-1));
        !          3739:                lavadropsiz[lavanumdrops] = 1;
        !          3740:                lavanumdrops++;
        !          3741:                z--;
        !          3742:        }
        !          3743: 
        !          3744:        z = lavanumdrops-1;
        !          3745:        while (z >= 0)
        !          3746:        {
        !          3747:                dadropsizlookup = lavadropsizlookup[lavadropsiz[z]]*(((z&1)<<1)-1);
        !          3748:                dalavadropsiz = lavadropsiz[z];
        !          3749:                dalavax = lavadropx[z]; dalavay = lavadropy[z];
        !          3750:                for(zx=lavaradcnt[lavadropsiz[z]]-1;zx>=0;zx--)
        !          3751:                {
        !          3752:                        offs = (((lavaradx[dalavadropsiz][zx]+dalavax)&(LAVASIZ-1))<<LAVALOGSIZ);
        !          3753:                        offs += ((lavarady[dalavadropsiz][zx]+dalavay)&(LAVASIZ-1));
        !          3754:                        dapic[offs] += dadropsizlookup;
        !          3755:                        if (dapic[offs] < 192) dapic[offs] = 192;
        !          3756:                }
        !          3757: 
        !          3758:                lavadropsiz[z]++;
        !          3759:                if (lavadropsiz[z] > 10)
        !          3760:                {
        !          3761:                        lavanumdrops--;
        !          3762:                        lavadropx[z] = lavadropx[lavanumdrops];
        !          3763:                        lavadropy[z] = lavadropy[lavanumdrops];
        !          3764:                        lavadropsiz[z] = lavadropsiz[lavanumdrops];
        !          3765:                }
        !          3766:                z--;
        !          3767:        }
        !          3768: 
        !          3769:                //Back up dapic with 1 pixel extra on each boundary
        !          3770:                //(to prevent anding for wrap-around)
        !          3771:        offs = ((long)dapic);
        !          3772:        offs2 = (LAVASIZ+2)+1+((long)lavabakpic);
        !          3773:        for(x=0;x<LAVASIZ;x++)
        !          3774:        {
        !          3775:                copybuf(offs,offs2,LAVASIZ>>2);
        !          3776:                offs += LAVASIZ;
        !          3777:                offs2 += LAVASIZ+2;
        !          3778:        }
        !          3779:        for(y=0;y<LAVASIZ;y++)
        !          3780:        {
        !          3781:                lavabakpic[y+1] = dapic[y+((LAVASIZ-1)<<LAVALOGSIZ)];
        !          3782:                lavabakpic[y+1+(LAVASIZ+1)*(LAVASIZ+2)] = dapic[y];
        !          3783:        }
        !          3784:        for(x=0;x<LAVASIZ;x++)
        !          3785:        {
        !          3786:                lavabakpic[(x+1)*(LAVASIZ+2)] = dapic[(x<<LAVALOGSIZ)+(LAVASIZ-1)];
        !          3787:                lavabakpic[(x+1)*(LAVASIZ+2)+(LAVASIZ+1)] = dapic[x<<LAVALOGSIZ];
        !          3788:        }
        !          3789:        lavabakpic[0] = dapic[LAVASIZ*LAVASIZ-1];
        !          3790:        lavabakpic[LAVASIZ+1] = dapic[LAVASIZ*(LAVASIZ-1)];
        !          3791:        lavabakpic[(LAVASIZ+2)*(LAVASIZ+1)] = dapic[LAVASIZ-1];
        !          3792:        lavabakpic[(LAVASIZ+2)*(LAVASIZ+2)-1] = dapic[0];
        !          3793: 
        !          3794:        for(z=(LAVASIZ+2)*(LAVASIZ+2)-4;z>=0;z-=4)
        !          3795:        {
        !          3796:                lavabakpic[z+0] &= 31;
        !          3797:                lavabakpic[z+1] &= 31;
        !          3798:                lavabakpic[z+2] &= 31;
        !          3799:                lavabakpic[z+3] &= 31;
        !          3800:        }
        !          3801: 
        !          3802:        for(x=LAVASIZ-1;x>=0;x--)
        !          3803:        {
        !          3804:                offs = (x+1)*(LAVASIZ+2)+1;
        !          3805:                ptr = (char *)((x<<LAVALOGSIZ) + (long)dapic);
        !          3806: 
        !          3807:                zx = ((x+lavanumframes)&(LAVASIZ-1));
        !          3808: 
        !          3809:                offs2 = LAVASIZ-1;
        !          3810:                for(y=offs;y<offs+LAVASIZ;y++)
        !          3811:                {
        !          3812:                        dat = lavainc[(offs2--)&zx];
        !          3813:                        dat += lavabakpic[y-(LAVASIZ+2)-1];
        !          3814:                        dat += lavabakpic[y-(LAVASIZ+2)];
        !          3815:                        dat += lavabakpic[y-(LAVASIZ+2)+1];
        !          3816:                        dat += lavabakpic[y-1];
        !          3817:                        dat += lavabakpic[y+1];
        !          3818:                        dat += lavabakpic[y+(LAVASIZ+2)];
        !          3819:                        dat += lavabakpic[y+(LAVASIZ+2)-1];
        !          3820:                        *ptr++ = (dat>>3)+192;
        !          3821:                }
        !          3822:        }
        !          3823: 
        !          3824:        lavanumframes++;
        !          3825: }
        !          3826: 
        !          3827: doanimations()
        !          3828: {
        !          3829:        long i, j;
        !          3830: 
        !          3831:        for(i=animatecnt-1;i>=0;i--)
        !          3832:        {
        !          3833:                j = *animateptr[i];
        !          3834: 
        !          3835:                if (j < animategoal[i])
        !          3836:                        j = min(j+animatevel[i]*TICSPERFRAME,animategoal[i]);
        !          3837:                else
        !          3838:                        j = max(j-animatevel[i]*TICSPERFRAME,animategoal[i]);
        !          3839:                animatevel[i] += animateacc[i];
        !          3840: 
        !          3841:                *animateptr[i] = j;
        !          3842: 
        !          3843:                if (j == animategoal[i])
        !          3844:                {
        !          3845:                        animatecnt--;
        !          3846:                        if (i != animatecnt)
        !          3847:                        {
        !          3848:                                animateptr[i] = animateptr[animatecnt];
        !          3849:                                animategoal[i] = animategoal[animatecnt];
        !          3850:                                animatevel[i] = animatevel[animatecnt];
        !          3851:                                animateacc[i] = animateacc[animatecnt];
        !          3852:                        }
        !          3853:                }
        !          3854:        }
        !          3855: }
        !          3856: 
        !          3857: getanimationgoal(long animptr)
        !          3858: {
        !          3859:        long i;
        !          3860: 
        !          3861:        for(i=animatecnt-1;i>=0;i--)
        !          3862:                if (animptr == animateptr[i]) return(i);
        !          3863:        return(-1);
        !          3864: }
        !          3865: 
        !          3866: setanimation(long *animptr, long thegoal, long thevel, long theacc)
        !          3867: {
        !          3868:        long i, j;
        !          3869: 
        !          3870:        if (animatecnt >= MAXANIMATES) return(-1);
        !          3871: 
        !          3872:        j = animatecnt;
        !          3873:        for(i=animatecnt-1;i>=0;i--)
        !          3874:                if (animptr == animateptr[i])
        !          3875:                        { j = i; break; }
        !          3876: 
        !          3877:        animateptr[j] = animptr;
        !          3878:        animategoal[j] = thegoal;
        !          3879:        animatevel[j] = thevel;
        !          3880:        animateacc[j] = theacc;
        !          3881:        if (j == animatecnt) animatecnt++;
        !          3882:        return(j);
        !          3883: }
        !          3884: 
        !          3885: checkmasterslaveswitch()
        !          3886: {
        !          3887:        long i, j;
        !          3888: 
        !          3889:        if (option[4] == 0) return;
        !          3890: 
        !          3891:        i = connecthead; j = connectpoint2[i];
        !          3892:        while (j >= 0)
        !          3893:        {
        !          3894:                if ((syncbits[j]&512) > 0)
        !          3895:                {
        !          3896:                        connectpoint2[i] = connectpoint2[j];
        !          3897:                        connectpoint2[j] = connecthead;
        !          3898:                        connecthead = (short)j;
        !          3899: 
        !          3900:                        olocvel = locvel+1; olocvel2 = locvel2+1;
        !          3901:                        olocsvel = locsvel+1; olocsvel2 = locsvel2+1;
        !          3902:                        olocangvel = locangvel+1; olocangvel2 = locangvel2+1;
        !          3903:                        olocbits = locbits+1; olocbits2 = locbits2+1;
        !          3904:                        for(i=0;i<MAXPLAYERS;i++)
        !          3905:                        {
        !          3906:                                osyncvel[i] = fsyncvel[i]+1;
        !          3907:                                osyncsvel[i] = fsyncsvel[i]+1;
        !          3908:                                osyncangvel[i] = fsyncangvel[i]+1;
        !          3909:                                osyncbits[i] = fsyncbits[i]+1;
        !          3910:                        }
        !          3911: 
        !          3912:                        syncvalplc = 0L; othersyncvalplc = 0L;
        !          3913:                        syncvalend = 0L; othersyncvalend = 0L;
        !          3914:                        syncvalcnt = 0L; othersyncvalcnt = 0L;
        !          3915: 
        !          3916:                        totalclock = lockclock;
        !          3917:                        ototalclock = lockclock;
        !          3918:                        gotlastpacketclock = lockclock;
        !          3919:                        masterslavetexttime = lockclock;
        !          3920:                        ready2send = 1;
        !          3921:                        return;
        !          3922:                }
        !          3923:                i = j; j = connectpoint2[i];
        !          3924:        }
        !          3925: }
        !          3926: 
        !          3927: inittimer()
        !          3928: {
        !          3929:        outp(0x43,54); outp(0x40,9942&255); outp(0x40,9942>>8);  //120 times/sec
        !          3930:        oldtimerhandler = _dos_getvect(0x8);
        !          3931:        _disable(); _dos_setvect(0x8, timerhandler); _enable();
        !          3932: }
        !          3933: 
        !          3934: uninittimer()
        !          3935: {
        !          3936:        outp(0x43,54); outp(0x40,255); outp(0x40,255);           //18.2 times/sec
        !          3937:        _disable(); _dos_setvect(0x8, oldtimerhandler); _enable();
        !          3938: }
        !          3939: 
        !          3940: void __interrupt __far timerhandler()
        !          3941: {
        !          3942:        totalclock++;
        !          3943:        outp(0x20,0x20);
        !          3944: }
        !          3945: 
        !          3946: initkeys()
        !          3947: {
        !          3948:        long i;
        !          3949: 
        !          3950:        keyfifoplc = 0; keyfifoend = 0;
        !          3951:        for(i=0;i<256;i++) keystatus[i] = 0;
        !          3952:        oldkeyhandler = _dos_getvect(0x9);
        !          3953:        _disable(); _dos_setvect(0x9, keyhandler); _enable();
        !          3954: }
        !          3955: 
        !          3956: uninitkeys()
        !          3957: {
        !          3958:        short *ptr;
        !          3959: 
        !          3960:        _dos_setvect(0x9, oldkeyhandler);
        !          3961:                //Turn off shifts to prevent stucks with quitting
        !          3962:        ptr = (short *)0x417; *ptr &= ~0x030f;
        !          3963: }
        !          3964: 
        !          3965: void __interrupt __far keyhandler()
        !          3966: {
        !          3967:        koutp(0x20,0x20);
        !          3968:        oldreadch = readch; readch = kinp(0x60);
        !          3969:        keytemp = kinp(0x61); koutp(0x61,keytemp|128); koutp(0x61,keytemp&127);
        !          3970:        if ((readch|1) == 0xe1) { extended = 128; return; }
        !          3971:        if (oldreadch != readch)
        !          3972:        {
        !          3973:                if ((readch&128) == 0)
        !          3974:                {
        !          3975:                        keytemp = readch+extended;
        !          3976:                        if (keystatus[keytemp] == 0)
        !          3977:                        {
        !          3978:                                keystatus[keytemp] = 1;
        !          3979:                                keyfifo[keyfifoend] = keytemp;
        !          3980:                                keyfifo[(keyfifoend+1)&(KEYFIFOSIZ-1)] = 1;
        !          3981:                                keyfifoend = ((keyfifoend+2)&(KEYFIFOSIZ-1));
        !          3982:                        }
        !          3983:                }
        !          3984:                else
        !          3985:                {
        !          3986:                        keytemp = (readch&127)+extended;
        !          3987:                        keystatus[keytemp] = 0;
        !          3988:                        keyfifo[keyfifoend] = keytemp;
        !          3989:                        keyfifo[(keyfifoend+1)&(KEYFIFOSIZ-1)] = 0;
        !          3990:                        keyfifoend = ((keyfifoend+2)&(KEYFIFOSIZ-1));
        !          3991:                }
        !          3992:        }
        !          3993:        extended = 0;
        !          3994: }
        !          3995: 
        !          3996: testneighborsectors(short sect1, short sect2)
        !          3997: {
        !          3998:        short i, startwall, num1, num2;
        !          3999: 
        !          4000:        num1 = sector[sect1].wallnum;
        !          4001:        num2 = sector[sect2].wallnum;
        !          4002:        if (num1 < num2) //Traverse walls of sector with fewest walls (for speed)
        !          4003:        {
        !          4004:                startwall = sector[sect1].wallptr;
        !          4005:                for(i=num1-1;i>=0;i--)
        !          4006:                        if (wall[i+startwall].nextsector == sect2)
        !          4007:                                return(1);
        !          4008:        }
        !          4009:        else
        !          4010:        {
        !          4011:                startwall = sector[sect2].wallptr;
        !          4012:                for(i=num2-1;i>=0;i--)
        !          4013:                        if (wall[i+startwall].nextsector == sect1)
        !          4014:                                return(1);
        !          4015:        }
        !          4016:        return(0);
        !          4017: }
        !          4018: 
        !          4019: loadgame()
        !          4020: {
        !          4021:        long i, fil;
        !          4022: 
        !          4023:        if ((fil = open("save0000.gam",O_BINARY|O_RDWR,S_IREAD)) == -1)
        !          4024:                return(-1);
        !          4025: 
        !          4026:        read(fil,&numplayers,2);
        !          4027:        read(fil,&myconnectindex,2);
        !          4028:        read(fil,&connecthead,2);
        !          4029:        read(fil,connectpoint2,MAXPLAYERS<<1);
        !          4030: 
        !          4031:                //Make sure palookups get set, sprites will get overwritten later
        !          4032:        for(i=connecthead;i>=0;i=connectpoint2[i]) initplayersprite((short)i);
        !          4033: 
        !          4034:        read(fil,posx,MAXPLAYERS<<2);
        !          4035:        read(fil,posy,MAXPLAYERS<<2);
        !          4036:        read(fil,posz,MAXPLAYERS<<2);
        !          4037:        read(fil,horiz,MAXPLAYERS<<2);
        !          4038:        read(fil,zoom,MAXPLAYERS<<2);
        !          4039:        read(fil,hvel,MAXPLAYERS<<2);
        !          4040:        read(fil,ang,MAXPLAYERS<<1);
        !          4041:        read(fil,cursectnum,MAXPLAYERS<<1);
        !          4042:        read(fil,ocursectnum,MAXPLAYERS<<1);
        !          4043:        read(fil,playersprite,MAXPLAYERS<<1);
        !          4044:        read(fil,deaths,MAXPLAYERS<<1);
        !          4045:        read(fil,lastchaingun,MAXPLAYERS<<2);
        !          4046:        read(fil,health,MAXPLAYERS<<2);
        !          4047:        read(fil,score,MAXPLAYERS<<2);
        !          4048:        read(fil,saywatchit,MAXPLAYERS<<2);
        !          4049:        read(fil,numbombs,MAXPLAYERS<<1);
        !          4050:        read(fil,&screensize,2);
        !          4051:        read(fil,oflags,MAXPLAYERS<<1);
        !          4052:        read(fil,dimensionmode,MAXPLAYERS);
        !          4053:        read(fil,revolvedoorstat,MAXPLAYERS);
        !          4054:        read(fil,revolvedoorang,MAXPLAYERS<<1);
        !          4055:        read(fil,revolvedoorrotang,MAXPLAYERS<<1);
        !          4056:        read(fil,revolvedoorx,MAXPLAYERS<<2);
        !          4057:        read(fil,revolvedoory,MAXPLAYERS<<2);
        !          4058: 
        !          4059:        read(fil,&numsectors,2);
        !          4060:        read(fil,sector,sizeof(sectortype)*numsectors);
        !          4061: 
        !          4062:        read(fil,&numwalls,2);
        !          4063:        read(fil,wall,sizeof(walltype)*numwalls);
        !          4064: 
        !          4065:                //Store all sprites (even holes) to preserve indeces
        !          4066:        read(fil,sprite,sizeof(spritetype)*MAXSPRITES);
        !          4067:        read(fil,headspritesect,(MAXSECTORS+1)<<1);
        !          4068:        read(fil,prevspritesect,MAXSPRITES<<1);
        !          4069:        read(fil,nextspritesect,MAXSPRITES<<1);
        !          4070:        read(fil,headspritestat,(MAXSTATUS+1)<<1);
        !          4071:        read(fil,prevspritestat,MAXSPRITES<<1);
        !          4072:        read(fil,nextspritestat,MAXSPRITES<<1);
        !          4073: 
        !          4074:        read(fil,&vel,4);
        !          4075:        read(fil,&svel,4);
        !          4076:        read(fil,&angvel,4);
        !          4077: 
        !          4078:        read(fil,&locselectedgun,4);
        !          4079:        read(fil,&locvel,1);
        !          4080:        read(fil,&olocvel,1);
        !          4081:        read(fil,&locsvel,1);
        !          4082:        read(fil,&olocsvel,1);
        !          4083:        read(fil,&locangvel,1);
        !          4084:        read(fil,&olocangvel,1);
        !          4085:        read(fil,&locbits,2);
        !          4086:        read(fil,&olocbits,2);
        !          4087: 
        !          4088:        read(fil,&locselectedgun2,4);
        !          4089:        read(fil,&locvel2,1);
        !          4090:        read(fil,&olocvel2,1);
        !          4091:        read(fil,&locsvel2,1);
        !          4092:        read(fil,&olocsvel2,1);
        !          4093:        read(fil,&locangvel2,1);
        !          4094:        read(fil,&olocangvel2,1);
        !          4095:        read(fil,&locbits2,2);
        !          4096:        read(fil,&olocbits2,2);
        !          4097: 
        !          4098:        read(fil,syncvel,MAXPLAYERS);
        !          4099:        read(fil,osyncvel,MAXPLAYERS);
        !          4100:        read(fil,syncsvel,MAXPLAYERS);
        !          4101:        read(fil,osyncsvel,MAXPLAYERS);
        !          4102:        read(fil,syncangvel,MAXPLAYERS);
        !          4103:        read(fil,osyncangvel,MAXPLAYERS);
        !          4104:        read(fil,syncbits,MAXPLAYERS<<1);
        !          4105:        read(fil,osyncbits,MAXPLAYERS<<1);
        !          4106: 
        !          4107:        read(fil,boardfilename,80);
        !          4108:        read(fil,&screenpeek,2);
        !          4109:        read(fil,&oldmousebstatus,2);
        !          4110:        read(fil,&brightness,2);
        !          4111:        read(fil,&neartagsector,2);
        !          4112:        read(fil,&neartagwall,2);
        !          4113:        read(fil,&neartagsprite,2);
        !          4114:        read(fil,&lockclock,4);
        !          4115:        read(fil,&neartagdist,4);
        !          4116:        read(fil,&neartaghitdist,4);
        !          4117:        read(fil,&masterslavetexttime,4);
        !          4118: 
        !          4119:        read(fil,rotatespritelist,16<<1);
        !          4120:        read(fil,&rotatespritecnt,2);
        !          4121:        read(fil,warpsectorlist,16<<1);
        !          4122:        read(fil,&warpsectorcnt,2);
        !          4123:        read(fil,xpanningsectorlist,16<<1);
        !          4124:        read(fil,&xpanningsectorcnt,2);
        !          4125:        read(fil,ypanningwalllist,64<<1);
        !          4126:        read(fil,&ypanningwallcnt,2);
        !          4127:        read(fil,floorpanninglist,64<<1);
        !          4128:        read(fil,&floorpanningcnt,2);
        !          4129:        read(fil,dragsectorlist,16<<1);
        !          4130:        read(fil,dragxdir,16<<1);
        !          4131:        read(fil,dragydir,16<<1);
        !          4132:        read(fil,&dragsectorcnt,2);
        !          4133:        read(fil,dragx1,16<<2);
        !          4134:        read(fil,dragy1,16<<2);
        !          4135:        read(fil,dragx2,16<<2);
        !          4136:        read(fil,dragy2,16<<2);
        !          4137:        read(fil,dragfloorz,16<<2);
        !          4138:        read(fil,&swingcnt,2);
        !          4139:        read(fil,swingwall,(32*5)<<1);
        !          4140:        read(fil,swingsector,32<<1);
        !          4141:        read(fil,swingangopen,32<<1);
        !          4142:        read(fil,swingangclosed,32<<1);
        !          4143:        read(fil,swingangopendir,32<<1);
        !          4144:        read(fil,swingang,32<<1);
        !          4145:        read(fil,swinganginc,32<<1);
        !          4146:        read(fil,swingx,(32*8)<<2);
        !          4147:        read(fil,swingy,(32*8)<<2);
        !          4148:        read(fil,revolvesector,4<<1);
        !          4149:        read(fil,revolveang,4<<1);
        !          4150:        read(fil,&revolvecnt,2);
        !          4151:        read(fil,revolvex,(4*16)<<2);
        !          4152:        read(fil,revolvey,(4*16)<<2);
        !          4153:        read(fil,revolvepivotx,4<<2);
        !          4154:        read(fil,revolvepivoty,4<<2);
        !          4155:        read(fil,subwaytracksector,(4*128)<<1);
        !          4156:        read(fil,subwaynumsectors,4<<1);
        !          4157:        read(fil,&subwaytrackcnt,2);
        !          4158:        read(fil,subwaystop,(4*8)<<2);
        !          4159:        read(fil,subwaystopcnt,4<<2);
        !          4160:        read(fil,subwaytrackx1,4<<2);
        !          4161:        read(fil,subwaytracky1,4<<2);
        !          4162:        read(fil,subwaytrackx2,4<<2);
        !          4163:        read(fil,subwaytracky2,4<<2);
        !          4164:        read(fil,subwayx,4<<2);
        !          4165:        read(fil,subwaygoalstop,4<<2);
        !          4166:        read(fil,subwayvel,4<<2);
        !          4167:        read(fil,subwaypausetime,4<<2);
        !          4168:        read(fil,waterfountainwall,MAXPLAYERS<<1);
        !          4169:        read(fil,waterfountaincnt,MAXPLAYERS<<1);
        !          4170:        read(fil,slimesoundcnt,MAXPLAYERS<<1);
        !          4171: 
        !          4172:                //Warning: only works if all pointers are in sector structures!
        !          4173:        read(fil,animateptr,MAXANIMATES<<2);
        !          4174:        for(i=MAXANIMATES-1;i>=0;i--)
        !          4175:                animateptr[i] = (long *)(animateptr[i]+((long)sector));
        !          4176:        read(fil,animategoal,MAXANIMATES<<2);
        !          4177:        read(fil,animatevel,MAXANIMATES<<2);
        !          4178:        read(fil,animateacc,MAXANIMATES<<2);
        !          4179:        read(fil,&animatecnt,4);
        !          4180: 
        !          4181:        read(fil,&totalclock,4);
        !          4182:        read(fil,&numframes,4);
        !          4183:        read(fil,&randomseed,4);
        !          4184:        read(fil,startumost,MAXXDIM<<1);
        !          4185:        read(fil,startdmost,MAXXDIM<<1);
        !          4186:        read(fil,&numpalookups,2);
        !          4187: 
        !          4188:        read(fil,&visibility,4);
        !          4189:        read(fil,&parallaxtype,1);
        !          4190:        read(fil,&parallaxyoffs,4);
        !          4191:        read(fil,pskyoff,MAXPSKYTILES<<1);
        !          4192:        read(fil,&pskybits,2);
        !          4193: 
        !          4194:        read(fil,show2dsector,MAXSECTORS>>3);
        !          4195:        read(fil,show2dwall,MAXWALLS>>3);
        !          4196:        read(fil,show2dsprite,MAXSPRITES>>3);
        !          4197:        read(fil,&automapping,1);
        !          4198: 
        !          4199:        close(fil);
        !          4200: 
        !          4201:        for(i=connecthead;i>=0;i=connectpoint2[i]) initplayersprite((short)i);
        !          4202: 
        !          4203:        totalclock = lockclock;
        !          4204:        ototalclock = lockclock;
        !          4205: 
        !          4206:        strcpy(getmessage,"Game loaded.");
        !          4207:        getmessageleng = strlen(getmessage);
        !          4208:        getmessagetimeoff = totalclock+360+(getmessageleng<<4);
        !          4209:        return(0);
        !          4210: }
        !          4211: 
        !          4212: savegame()
        !          4213: {
        !          4214:        long i, fil;
        !          4215: 
        !          4216:        if ((fil = open("save0000.gam",O_BINARY|O_TRUNC|O_CREAT|O_WRONLY,S_IWRITE)) == -1)
        !          4217:                return(-1);
        !          4218: 
        !          4219:        write(fil,&numplayers,2);
        !          4220:        write(fil,&myconnectindex,2);
        !          4221:        write(fil,&connecthead,2);
        !          4222:        write(fil,connectpoint2,MAXPLAYERS<<1);
        !          4223: 
        !          4224:        write(fil,posx,MAXPLAYERS<<2);
        !          4225:        write(fil,posy,MAXPLAYERS<<2);
        !          4226:        write(fil,posz,MAXPLAYERS<<2);
        !          4227:        write(fil,horiz,MAXPLAYERS<<2);
        !          4228:        write(fil,zoom,MAXPLAYERS<<2);
        !          4229:        write(fil,hvel,MAXPLAYERS<<2);
        !          4230:        write(fil,ang,MAXPLAYERS<<1);
        !          4231:        write(fil,cursectnum,MAXPLAYERS<<1);
        !          4232:        write(fil,ocursectnum,MAXPLAYERS<<1);
        !          4233:        write(fil,playersprite,MAXPLAYERS<<1);
        !          4234:        write(fil,deaths,MAXPLAYERS<<1);
        !          4235:        write(fil,lastchaingun,MAXPLAYERS<<2);
        !          4236:        write(fil,health,MAXPLAYERS<<2);
        !          4237:        write(fil,score,MAXPLAYERS<<2);
        !          4238:        write(fil,saywatchit,MAXPLAYERS<<2);
        !          4239:        write(fil,numbombs,MAXPLAYERS<<1);
        !          4240:        write(fil,&screensize,2);
        !          4241:        write(fil,oflags,MAXPLAYERS<<1);
        !          4242:        write(fil,dimensionmode,MAXPLAYERS);
        !          4243:        write(fil,revolvedoorstat,MAXPLAYERS);
        !          4244:        write(fil,revolvedoorang,MAXPLAYERS<<1);
        !          4245:        write(fil,revolvedoorrotang,MAXPLAYERS<<1);
        !          4246:        write(fil,revolvedoorx,MAXPLAYERS<<2);
        !          4247:        write(fil,revolvedoory,MAXPLAYERS<<2);
        !          4248: 
        !          4249:        write(fil,&numsectors,2);
        !          4250:        write(fil,sector,sizeof(sectortype)*numsectors);
        !          4251: 
        !          4252:        write(fil,&numwalls,2);
        !          4253:        write(fil,wall,sizeof(walltype)*numwalls);
        !          4254: 
        !          4255:                //Store all sprites (even holes) to preserve indeces
        !          4256:        write(fil,sprite,sizeof(spritetype)*MAXSPRITES);
        !          4257:        write(fil,headspritesect,(MAXSECTORS+1)<<1);
        !          4258:        write(fil,prevspritesect,MAXSPRITES<<1);
        !          4259:        write(fil,nextspritesect,MAXSPRITES<<1);
        !          4260:        write(fil,headspritestat,(MAXSTATUS+1)<<1);
        !          4261:        write(fil,prevspritestat,MAXSPRITES<<1);
        !          4262:        write(fil,nextspritestat,MAXSPRITES<<1);
        !          4263: 
        !          4264:        write(fil,&vel,4);
        !          4265:        write(fil,&svel,4);
        !          4266:        write(fil,&angvel,4);
        !          4267: 
        !          4268:        write(fil,&locselectedgun,4);
        !          4269:        write(fil,&locvel,1);
        !          4270:        write(fil,&olocvel,1);
        !          4271:        write(fil,&locsvel,1);
        !          4272:        write(fil,&olocsvel,1);
        !          4273:        write(fil,&locangvel,1);
        !          4274:        write(fil,&olocangvel,1);
        !          4275:        write(fil,&locbits,2);
        !          4276:        write(fil,&olocbits,2);
        !          4277: 
        !          4278:        write(fil,&locselectedgun2,4);
        !          4279:        write(fil,&locvel2,1);
        !          4280:        write(fil,&olocvel2,1);
        !          4281:        write(fil,&locsvel2,1);
        !          4282:        write(fil,&olocsvel2,1);
        !          4283:        write(fil,&locangvel2,1);
        !          4284:        write(fil,&olocangvel2,1);
        !          4285:        write(fil,&locbits2,2);
        !          4286:        write(fil,&olocbits2,2);
        !          4287: 
        !          4288:        write(fil,syncvel,MAXPLAYERS);
        !          4289:        write(fil,osyncvel,MAXPLAYERS);
        !          4290:        write(fil,syncsvel,MAXPLAYERS);
        !          4291:        write(fil,osyncsvel,MAXPLAYERS);
        !          4292:        write(fil,syncangvel,MAXPLAYERS);
        !          4293:        write(fil,osyncangvel,MAXPLAYERS);
        !          4294:        write(fil,syncbits,MAXPLAYERS<<1);
        !          4295:        write(fil,osyncbits,MAXPLAYERS<<1);
        !          4296: 
        !          4297:        write(fil,boardfilename,80);
        !          4298:        write(fil,&screenpeek,2);
        !          4299:        write(fil,&oldmousebstatus,2);
        !          4300:        write(fil,&brightness,2);
        !          4301:        write(fil,&neartagsector,2);
        !          4302:        write(fil,&neartagwall,2);
        !          4303:        write(fil,&neartagsprite,2);
        !          4304:        write(fil,&lockclock,4);
        !          4305:        write(fil,&neartagdist,4);
        !          4306:        write(fil,&neartaghitdist,4);
        !          4307:        write(fil,&masterslavetexttime,4);
        !          4308: 
        !          4309:        write(fil,rotatespritelist,16<<1);
        !          4310:        write(fil,&rotatespritecnt,2);
        !          4311:        write(fil,warpsectorlist,16<<1);
        !          4312:        write(fil,&warpsectorcnt,2);
        !          4313:        write(fil,xpanningsectorlist,16<<1);
        !          4314:        write(fil,&xpanningsectorcnt,2);
        !          4315:        write(fil,ypanningwalllist,64<<1);
        !          4316:        write(fil,&ypanningwallcnt,2);
        !          4317:        write(fil,floorpanninglist,64<<1);
        !          4318:        write(fil,&floorpanningcnt,2);
        !          4319:        write(fil,dragsectorlist,16<<1);
        !          4320:        write(fil,dragxdir,16<<1);
        !          4321:        write(fil,dragydir,16<<1);
        !          4322:        write(fil,&dragsectorcnt,2);
        !          4323:        write(fil,dragx1,16<<2);
        !          4324:        write(fil,dragy1,16<<2);
        !          4325:        write(fil,dragx2,16<<2);
        !          4326:        write(fil,dragy2,16<<2);
        !          4327:        write(fil,dragfloorz,16<<2);
        !          4328:        write(fil,&swingcnt,2);
        !          4329:        write(fil,swingwall,(32*5)<<1);
        !          4330:        write(fil,swingsector,32<<1);
        !          4331:        write(fil,swingangopen,32<<1);
        !          4332:        write(fil,swingangclosed,32<<1);
        !          4333:        write(fil,swingangopendir,32<<1);
        !          4334:        write(fil,swingang,32<<1);
        !          4335:        write(fil,swinganginc,32<<1);
        !          4336:        write(fil,swingx,(32*8)<<2);
        !          4337:        write(fil,swingy,(32*8)<<2);
        !          4338:        write(fil,revolvesector,4<<1);
        !          4339:        write(fil,revolveang,4<<1);
        !          4340:        write(fil,&revolvecnt,2);
        !          4341:        write(fil,revolvex,(4*16)<<2);
        !          4342:        write(fil,revolvey,(4*16)<<2);
        !          4343:        write(fil,revolvepivotx,4<<2);
        !          4344:        write(fil,revolvepivoty,4<<2);
        !          4345:        write(fil,subwaytracksector,(4*128)<<1);
        !          4346:        write(fil,subwaynumsectors,4<<1);
        !          4347:        write(fil,&subwaytrackcnt,2);
        !          4348:        write(fil,subwaystop,(4*8)<<2);
        !          4349:        write(fil,subwaystopcnt,4<<2);
        !          4350:        write(fil,subwaytrackx1,4<<2);
        !          4351:        write(fil,subwaytracky1,4<<2);
        !          4352:        write(fil,subwaytrackx2,4<<2);
        !          4353:        write(fil,subwaytracky2,4<<2);
        !          4354:        write(fil,subwayx,4<<2);
        !          4355:        write(fil,subwaygoalstop,4<<2);
        !          4356:        write(fil,subwayvel,4<<2);
        !          4357:        write(fil,subwaypausetime,4<<2);
        !          4358:        write(fil,waterfountainwall,MAXPLAYERS<<1);
        !          4359:        write(fil,waterfountaincnt,MAXPLAYERS<<1);
        !          4360:        write(fil,slimesoundcnt,MAXPLAYERS<<1);
        !          4361: 
        !          4362:                //Warning: only works if all pointers are in sector structures!
        !          4363:        for(i=MAXANIMATES-1;i>=0;i--)
        !          4364:                animateptr[i] = (long *)(animateptr[i]-((long)sector));
        !          4365:        write(fil,animateptr,MAXANIMATES<<2);
        !          4366:        for(i=MAXANIMATES-1;i>=0;i--)
        !          4367:                animateptr[i] = (long *)(animateptr[i]+((long)sector));
        !          4368:        write(fil,animategoal,MAXANIMATES<<2);
        !          4369:        write(fil,animatevel,MAXANIMATES<<2);
        !          4370:        write(fil,animateacc,MAXANIMATES<<2);
        !          4371:        write(fil,&animatecnt,4);
        !          4372: 
        !          4373:        write(fil,&totalclock,4);
        !          4374:        write(fil,&numframes,4);
        !          4375:        write(fil,&randomseed,4);
        !          4376:        write(fil,startumost,MAXXDIM<<1);
        !          4377:        write(fil,startdmost,MAXXDIM<<1);
        !          4378:        write(fil,&numpalookups,2);
        !          4379: 
        !          4380:        write(fil,&visibility,4);
        !          4381:        write(fil,&parallaxtype,1);
        !          4382:        write(fil,&parallaxyoffs,4);
        !          4383:        write(fil,pskyoff,MAXPSKYTILES<<1);
        !          4384:        write(fil,&pskybits,2);
        !          4385: 
        !          4386:        write(fil,show2dsector,MAXSECTORS>>3);
        !          4387:        write(fil,show2dwall,MAXWALLS>>3);
        !          4388:        write(fil,show2dsprite,MAXSPRITES>>3);
        !          4389:        write(fil,&automapping,1);
        !          4390: 
        !          4391:        close(fil);
        !          4392: 
        !          4393:        strcpy(getmessage,"Game saved.");
        !          4394:        getmessageleng = strlen(getmessage);
        !          4395:        getmessagetimeoff = totalclock+360+(getmessageleng<<4);
        !          4396:        return(0);
        !          4397: }
        !          4398: 
        !          4399: faketimerhandler()
        !          4400: {
        !          4401:        short other, tempbufleng;
        !          4402:        long i, j, k, l;
        !          4403: 
        !          4404:        if (totalclock < ototalclock+TICSPERFRAME) return;
        !          4405:        if (ready2send == 0) return;
        !          4406:        ototalclock = totalclock;
        !          4407: 
        !          4408:                //I am the MASTER (or 1 player game)
        !          4409:        if ((myconnectindex == connecthead) || (option[4] == 0))
        !          4410:        {
        !          4411:                if (option[4] != 0)
        !          4412:                        getpackets();
        !          4413: 
        !          4414:                if (getoutputcirclesize() < 16)
        !          4415:                {
        !          4416:                        getinput();
        !          4417:                        fsyncvel[myconnectindex] = locvel;
        !          4418:                        fsyncsvel[myconnectindex] = locsvel;
        !          4419:                        fsyncangvel[myconnectindex] = locangvel;
        !          4420:                        fsyncbits[myconnectindex] = locbits;
        !          4421: 
        !          4422:                        if (option[4] != 0)
        !          4423:                        {
        !          4424:                                tempbuf[0] = 0;
        !          4425:                                j = ((numplayers+1)>>1)+1;
        !          4426:                                for(k=1;k<j;k++) tempbuf[k] = 0;
        !          4427:                                k = (1<<3);
        !          4428:                                for(i=connecthead;i>=0;i=connectpoint2[i])
        !          4429:                                {
        !          4430:                                        l = 0;
        !          4431:                                        if (fsyncvel[i] != osyncvel[i]) tempbuf[j++] = fsyncvel[i], l |= 1;
        !          4432:                                        if (fsyncsvel[i] != osyncsvel[i]) tempbuf[j++] = fsyncsvel[i], l |= 2;
        !          4433:                                        if (fsyncangvel[i] != osyncangvel[i]) tempbuf[j++] = fsyncangvel[i], l |= 4;
        !          4434:                                        if (fsyncbits[i] != osyncbits[i])
        !          4435:                                        {
        !          4436:                                                tempbuf[j++] = (fsyncbits[i]&255);
        !          4437:                                                tempbuf[j++] = ((fsyncbits[i]>>8)&255);
        !          4438:                                                l |= 8;
        !          4439:                                        }
        !          4440:                                        tempbuf[k>>3] |= (l<<(k&7));
        !          4441:                                        k += 4;
        !          4442: 
        !          4443:                                        osyncvel[i] = fsyncvel[i];
        !          4444:                                        osyncsvel[i] = fsyncsvel[i];
        !          4445:                                        osyncangvel[i] = fsyncangvel[i];
        !          4446:                                        osyncbits[i] = fsyncbits[i];
        !          4447:                                }
        !          4448: 
        !          4449:                                while (syncvalplc != syncvalend)
        !          4450:                                {
        !          4451:                                        tempbuf[j] = (char)(syncval[syncvalplc]&255);
        !          4452:                                        tempbuf[j+1] = (char)((syncval[syncvalplc]>>8)&255);
        !          4453:                                        j += 2;
        !          4454:                                        syncvalplc = ((syncvalplc+1)&(MOVEFIFOSIZ-1));
        !          4455:                                }
        !          4456: 
        !          4457:                                for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i])
        !          4458:                                        sendpacket(i,tempbuf,j);
        !          4459:                        }
        !          4460:                        else if (numplayers == 2)
        !          4461:                        {
        !          4462:                                if (keystatus[0xb5] > 0)
        !          4463:                                {
        !          4464:                                        keystatus[0xb5] = 0;
        !          4465:                                        locselectedgun2++;
        !          4466:                                        if (locselectedgun2 >= 3) locselectedgun2 = 0;
        !          4467:                                }
        !          4468: 
        !          4469:                                        //Second player on 1 computer mode
        !          4470:                                locvel2 = min(max(vel2,-128+8),127-8);
        !          4471:                                locsvel2 = min(max(svel2,-128+8),127-8);
        !          4472:                                locangvel2 = min(max(angvel2,-128+16),127-16);
        !          4473:                                locbits2 = (locselectedgun2<<13);
        !          4474:                                locbits2 |= keystatus[0x45];                  //Stand high
        !          4475:                                locbits2 |= (keystatus[0x47]<<1);             //Stand low
        !          4476:                                locbits2 |= (1<<8);                           //Run
        !          4477:                                locbits2 |= (keystatus[0x49]<<2);             //Look up
        !          4478:                                locbits2 |= (keystatus[0x37]<<3);             //Look down
        !          4479:                                locbits2 |= (keystatus[0x50]<<10);            //Space
        !          4480:                                locbits2 |= (keystatus[0x52]<<11);            //Shoot
        !          4481: 
        !          4482:                                other = connectpoint2[myconnectindex];
        !          4483:                                if (other < 0) other = connecthead;
        !          4484: 
        !          4485:                                fsyncvel[other] = locvel2;
        !          4486:                                fsyncsvel[other] = locsvel2;
        !          4487:                                fsyncangvel[other] = locangvel2;
        !          4488:                                fsyncbits[other] = locbits2;
        !          4489:                        }
        !          4490:                        movethings();  //Move EVERYTHING (you too!)
        !          4491:                }
        !          4492:        }
        !          4493:        else                        //I am a SLAVE
        !          4494:        {
        !          4495:                getpackets();
        !          4496: 
        !          4497:                if (getoutputcirclesize() < 16)
        !          4498:                {
        !          4499:                        getinput();
        !          4500: 
        !          4501:                        tempbuf[0] = 1; k = 0;
        !          4502:                        j = 2;
        !          4503: 
        !          4504:                        if (locvel != olocvel) tempbuf[j++] = locvel, k |= 1;
        !          4505:                        if (locsvel != olocsvel) tempbuf[j++] = locsvel, k |= 2;
        !          4506:                        if (locangvel != olocangvel) tempbuf[j++] = locangvel, k |= 4;
        !          4507:                        if ((locbits^olocbits)&0x00ff) tempbuf[j++] = (locbits&255), k |= 8;
        !          4508:                        if ((locbits^olocbits)&0xff00) tempbuf[j++] = ((locbits>>8)&255), k |= 16;
        !          4509: 
        !          4510:                        tempbuf[1] = k;
        !          4511: 
        !          4512:                        olocvel = locvel;
        !          4513:                        olocsvel = locsvel;
        !          4514:                        olocangvel = locangvel;
        !          4515:                        olocbits = locbits;
        !          4516: 
        !          4517:                        sendpacket(connecthead,tempbuf,j);
        !          4518:                }
        !          4519:        }
        !          4520: }
        !          4521: 
        !          4522: getpackets()
        !          4523: {
        !          4524:        long i, j, k, l;
        !          4525:        short other, tempbufleng;
        !          4526: 
        !          4527:        if (option[4] == 0) return;
        !          4528: 
        !          4529:        while ((tempbufleng = getpacket(&other,tempbuf)) > 0)
        !          4530:        {
        !          4531:                switch(tempbuf[0])
        !          4532:                {
        !          4533:                        case 0:  //[0] (receive master sync buffer)
        !          4534:                                j = ((numplayers+1)>>1)+1; k = (1<<3);
        !          4535:                                for(i=connecthead;i>=0;i=connectpoint2[i])
        !          4536:                                {
        !          4537:                                        l = (tempbuf[k>>3]>>(k&7));
        !          4538:                                        if (l&1) fsyncvel[i] = tempbuf[j++];
        !          4539:                                        if (l&2) fsyncsvel[i] = tempbuf[j++];
        !          4540:                                        if (l&4) fsyncangvel[i] = tempbuf[j++];
        !          4541:                                        if (l&8)
        !          4542:                                        {
        !          4543:                                                fsyncbits[i] = ((short)tempbuf[j])+(((short)tempbuf[j+1])<<8);
        !          4544:                                                j += 2;
        !          4545:                                        }
        !          4546:                                        k += 4;
        !          4547:                                }
        !          4548:                                while (j != tempbufleng)
        !          4549:                                {
        !          4550:                                        othersyncval[othersyncvalend] = ((long)tempbuf[j]);
        !          4551:                                        othersyncval[othersyncvalend] += (((long)tempbuf[j+1])<<8);
        !          4552:                                        j += 2;
        !          4553:                                        othersyncvalend = ((othersyncvalend+1)&(MOVEFIFOSIZ-1));
        !          4554:                                }
        !          4555: 
        !          4556:                                i = 0;
        !          4557:                                while (syncvalplc != syncvalend)
        !          4558:                                {
        !          4559:                                        if (othersyncvalcnt > syncvalcnt)
        !          4560:                                        {
        !          4561:                                                if (i == 0) syncstat = 0, i = 1;
        !          4562:                                                syncstat |= (syncval[syncvalplc]^othersyncval[syncvalplc]);
        !          4563:                                        }
        !          4564:                                        syncvalplc = ((syncvalplc+1)&(MOVEFIFOSIZ-1));
        !          4565:                                        syncvalcnt++;
        !          4566:                                }
        !          4567:                                while (othersyncvalplc != othersyncvalend)
        !          4568:                                {
        !          4569:                                        if (syncvalcnt > othersyncvalcnt)
        !          4570:                                        {
        !          4571:                                                if (i == 0) syncstat = 0, i = 1;
        !          4572:                                                syncstat |= (syncval[othersyncvalplc]^othersyncval[othersyncvalplc]);
        !          4573:                                        }
        !          4574:                                        othersyncvalplc = ((othersyncvalplc+1)&(MOVEFIFOSIZ-1));
        !          4575:                                        othersyncvalcnt++;
        !          4576:                                }
        !          4577: 
        !          4578:                                movethings();        //Move all players and sprites
        !          4579:                                break;
        !          4580:                        case 1:  //[1] (receive slave sync buffer)
        !          4581:                                j = 2; k = tempbuf[1];
        !          4582:                                if (k&1) fsyncvel[other] = tempbuf[j++];
        !          4583:                                if (k&2) fsyncsvel[other] = tempbuf[j++];
        !          4584:                                if (k&4) fsyncangvel[other] = tempbuf[j++];
        !          4585:                                if (k&8) fsyncbits[other] = ((fsyncbits[other]&0xff00)|((short)tempbuf[j++]));
        !          4586:                                if (k&16) fsyncbits[other] = ((fsyncbits[other]&0x00ff)|(((short)tempbuf[j++])<<8));
        !          4587:                                break;
        !          4588:                        case 2:
        !          4589:                                getmessageleng = tempbufleng-1;
        !          4590:                                for(j=getmessageleng-1;j>=0;j--) getmessage[j] = tempbuf[j+1];
        !          4591:                                getmessagetimeoff = totalclock+360+(getmessageleng<<4);
        !          4592:                                break;
        !          4593:                        case 3:
        !          4594:                                wsay("getstuff.wav",4096L,63L,63L);
        !          4595:                                break;
        !          4596:                        case 5:
        !          4597:                                playerreadyflag[other] = tempbuf[1];
        !          4598:                                if ((other == connecthead) && (tempbuf[1] == 2))
        !          4599:                                        sendpacket(connecthead,tempbuf,2);
        !          4600:                                break;
        !          4601:                        case 255:  //[255] (logout)
        !          4602:                                keystatus[1] = 1;
        !          4603:                                break;
        !          4604:                }
        !          4605:        }
        !          4606: }
        !          4607: 
        !          4608: drawoverheadmap(long cposx, long cposy, long czoom, short cang)
        !          4609: {
        !          4610:        long i, j, k, l, x1, y1, x2, y2, x3, y3, x4, y4, ox, oy, xoff, yoff;
        !          4611:        long dax, day, cosang, sinang, xspan, yspan, sprx, spry;
        !          4612:        long xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang;
        !          4613:        long xvect, yvect, xvect2, yvect2;
        !          4614:        char col;
        !          4615:        walltype *wal, *wal2;
        !          4616:        spritetype *spr;
        !          4617: 
        !          4618:        xvect = sintable[(2048-cang)&2047] * czoom;
        !          4619:        yvect = sintable[(1536-cang)&2047] * czoom;
        !          4620:        xvect2 = mulscale(xvect,yxaspect,16);
        !          4621:        yvect2 = mulscale(yvect,yxaspect,16);
        !          4622: 
        !          4623:                //Draw red lines
        !          4624:        for(i=0;i<numsectors;i++)
        !          4625:        {
        !          4626:                startwall = sector[i].wallptr;
        !          4627:                endwall = sector[i].wallptr + sector[i].wallnum - 1;
        !          4628: 
        !          4629:                z1 = sector[i].ceilingz; z2 = sector[i].floorz;
        !          4630: 
        !          4631:                for(j=startwall,wal=&wall[startwall];j<=endwall;j++,wal++)
        !          4632:                {
        !          4633:                        k = wal->nextwall; if (k < 0) continue;
        !          4634: 
        !          4635:                        if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue;
        !          4636:                        if ((k > j) && ((show2dwall[k>>3]&(1<<(k&7))) > 0)) continue;
        !          4637: 
        !          4638:                        if (sector[wal->nextsector].ceilingz == z1)
        !          4639:                                if (sector[wal->nextsector].floorz == z2)
        !          4640:                                        if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0) continue;
        !          4641: 
        !          4642:                        col = 152;
        !          4643: 
        !          4644:                        if (dimensionmode[screenpeek] == 2)
        !          4645:                        {
        !          4646:                                if (sector[i].floorz != sector[i].ceilingz)
        !          4647:                                        if (sector[wal->nextsector].floorz != sector[wal->nextsector].ceilingz)
        !          4648:                                                if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0)
        !          4649:                                                        if (sector[i].floorz == sector[wal->nextsector].floorz) continue;
        !          4650:                                if (sector[i].floorpicnum != sector[wal->nextsector].floorpicnum) continue;
        !          4651:                                if (sector[i].floorshade != sector[wal->nextsector].floorshade) continue;
        !          4652:                                col = 12;
        !          4653:                        }
        !          4654: 
        !          4655:                        ox = wal->x-cposx; oy = wal->y-cposy;
        !          4656:                        x1 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
        !          4657:                        y1 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);
        !          4658: 
        !          4659:                        wal2 = &wall[wal->point2];
        !          4660:                        ox = wal2->x-cposx; oy = wal2->y-cposy;
        !          4661:                        x2 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
        !          4662:                        y2 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);
        !          4663: 
        !          4664:                        drawline256(x1+(xdim<<11),y1+(ydim<<11),x2+(xdim<<11),y2+(ydim<<11),col);
        !          4665:                }
        !          4666:        }
        !          4667: 
        !          4668:                //Draw sprites
        !          4669:        k = playersprite[screenpeek];
        !          4670:        for(i=0;i<numsectors;i++)
        !          4671:                for(j=headspritesect[i];j>=0;j=nextspritesect[j])
        !          4672:                        if ((show2dsprite[j>>3]&(1<<(j&7))) > 0)
        !          4673:                        {
        !          4674:                                spr = &sprite[j];
        !          4675:                                col = 56;
        !          4676:                                if ((spr->cstat&1) > 0) col = 248;
        !          4677:                                if (j == k) col = 31;
        !          4678: 
        !          4679:                                sprx = spr->x;
        !          4680:                                spry = spr->y;
        !          4681: 
        !          4682:                                k = spr->statnum;
        !          4683:                                if ((k >= 1) && (k <= 8) && (k != 2))  //Interpolate moving sprite
        !          4684:                                {
        !          4685:                                        sprx = osprite[j].x+mulscale(sprx-osprite[j].x,smoothratio,16);
        !          4686:                                        spry = osprite[j].y+mulscale(spry-osprite[j].y,smoothratio,16);
        !          4687:                                }
        !          4688: 
        !          4689:                                switch (spr->cstat&48)
        !          4690:                                {
        !          4691:                                        case 0:
        !          4692:                                                ox = sprx-cposx; oy = spry-cposy;
        !          4693:                                                x1 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
        !          4694:                                                y1 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);
        !          4695: 
        !          4696:                                                if (dimensionmode[screenpeek] == 1)
        !          4697:                                                {
        !          4698:                                                        ox = (sintable[(spr->ang+512)&2047]>>7);
        !          4699:                                                        oy = (sintable[(spr->ang)&2047]>>7);
        !          4700:                                                        x2 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
        !          4701:                                                        y2 = mulscale(oy,xvect,16) + mulscale(ox,yvect,16);
        !          4702: 
        !          4703:                                                        if (j == playersprite[screenpeek])
        !          4704:                                                        {
        !          4705:                                                                x2 = 0L;
        !          4706:                                                                y2 = -(czoom<<5);
        !          4707:                                                        }
        !          4708: 
        !          4709:                                                        x3 = mulscale(x2,yxaspect,16);
        !          4710:                                                        y3 = mulscale(y2,yxaspect,16);
        !          4711: 
        !          4712:                                                        drawline256(x1-x2+(xdim<<11),y1-y3+(ydim<<11),
        !          4713:                                                                                        x1+x2+(xdim<<11),y1+y3+(ydim<<11),col);
        !          4714:                                                        drawline256(x1-y2+(xdim<<11),y1+x3+(ydim<<11),
        !          4715:                                                                                        x1+x2+(xdim<<11),y1+y3+(ydim<<11),col);
        !          4716:                                                        drawline256(x1+y2+(xdim<<11),y1-x3+(ydim<<11),
        !          4717:                                                                                        x1+x2+(xdim<<11),y1+y3+(ydim<<11),col);
        !          4718:                                                }
        !          4719:                                                else
        !          4720:                                                {
        !          4721:                                                        if (((gotsector[i>>3]&(1<<(i&7))) > 0) && (czoom > 192))
        !          4722:                                                        {
        !          4723:                                                                daang = (spr->ang-cang)&2047;
        !          4724:                                                                if (j == playersprite[screenpeek])
        !          4725:                                                                        { x1 = 0; y1 = (yxaspect<<2); daang = 0; }
        !          4726:                                                                rotatesprite((x1<<4)+(xdim<<15),(y1<<4)+(ydim<<15),mulscale(czoom*spr->yrepeat,yxaspect,16),daang,spr->picnum,spr->shade,spr->pal,(spr->cstat&2)>>1);
        !          4727:                                                        }
        !          4728:                                                }
        !          4729:                                                break;
        !          4730:                                        case 16:
        !          4731:                                                x1 = sprx; y1 = spry;
        !          4732:                                                tilenum = spr->picnum;
        !          4733:                                                xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset);
        !          4734:                                                if ((spr->cstat&4) > 0) xoff = -xoff;
        !          4735:                                                k = spr->ang; l = spr->xrepeat;
        !          4736:                                                dax = sintable[k&2047]*l; day = sintable[(k+1536)&2047]*l;
        !          4737:                                                l = tilesizx[tilenum]; k = (l>>1)+xoff;
        !          4738:                                                x1 -= mulscale(dax,k,16); x2 = x1+mulscale(dax,l,16);
        !          4739:                                                y1 -= mulscale(day,k,16); y2 = y1+mulscale(day,l,16);
        !          4740: 
        !          4741:                                                ox = x1-cposx; oy = y1-cposy;
        !          4742:                                                x1 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
        !          4743:                                                y1 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);
        !          4744: 
        !          4745:                                                ox = x2-cposx; oy = y2-cposy;
        !          4746:                                                x2 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
        !          4747:                                                y2 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);
        !          4748: 
        !          4749:                                                drawline256(x1+(xdim<<11),y1+(ydim<<11),
        !          4750:                                                                                x2+(xdim<<11),y2+(ydim<<11),col);
        !          4751: 
        !          4752:                                                break;
        !          4753:                                        case 32:
        !          4754:                                                if (dimensionmode[screenpeek] == 1)
        !          4755:                                                {
        !          4756:                                                        tilenum = spr->picnum;
        !          4757:                                                        xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset);
        !          4758:                                                        yoff = (long)((signed char)((picanm[tilenum]>>16)&255))+((long)spr->yoffset);
        !          4759:                                                        if ((spr->cstat&4) > 0) xoff = -xoff;
        !          4760:                                                        if ((spr->cstat&8) > 0) yoff = -yoff;
        !          4761: 
        !          4762:                                                        k = spr->ang;
        !          4763:                                                        cosang = sintable[(k+512)&2047]; sinang = sintable[k];
        !          4764:                                                        xspan = tilesizx[tilenum]; xrepeat = spr->xrepeat;
        !          4765:                                                        yspan = tilesizy[tilenum]; yrepeat = spr->yrepeat;
        !          4766: 
        !          4767:                                                        dax = ((xspan>>1)+xoff)*xrepeat; day = ((yspan>>1)+yoff)*yrepeat;
        !          4768:                                                        x1 = sprx + mulscale(sinang,dax,16) + mulscale(cosang,day,16);
        !          4769:                                                        y1 = spry + mulscale(sinang,day,16) - mulscale(cosang,dax,16);
        !          4770:                                                        l = xspan*xrepeat;
        !          4771:                                                        x2 = x1 - mulscale(sinang,l,16);
        !          4772:                                                        y2 = y1 + mulscale(cosang,l,16);
        !          4773:                                                        l = yspan*yrepeat;
        !          4774:                                                        k = -mulscale(cosang,l,16); x3 = x2+k; x4 = x1+k;
        !          4775:                                                        k = -mulscale(sinang,l,16); y3 = y2+k; y4 = y1+k;
        !          4776: 
        !          4777:                                                        ox = x1-cposx; oy = y1-cposy;
        !          4778:                                                        x1 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
        !          4779:                                                        y1 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);
        !          4780: 
        !          4781:                                                        ox = x2-cposx; oy = y2-cposy;
        !          4782:                                                        x2 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
        !          4783:                                                        y2 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);
        !          4784: 
        !          4785:                                                        ox = x3-cposx; oy = y3-cposy;
        !          4786:                                                        x3 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
        !          4787:                                                        y3 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);
        !          4788: 
        !          4789:                                                        ox = x4-cposx; oy = y4-cposy;
        !          4790:                                                        x4 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
        !          4791:                                                        y4 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);
        !          4792: 
        !          4793:                                                        drawline256(x1+(xdim<<11),y1+(ydim<<11),
        !          4794:                                                                                        x2+(xdim<<11),y2+(ydim<<11),col);
        !          4795: 
        !          4796:                                                        drawline256(x2+(xdim<<11),y2+(ydim<<11),
        !          4797:                                                                                        x3+(xdim<<11),y3+(ydim<<11),col);
        !          4798: 
        !          4799:                                                        drawline256(x3+(xdim<<11),y3+(ydim<<11),
        !          4800:                                                                                        x4+(xdim<<11),y4+(ydim<<11),col);
        !          4801: 
        !          4802:                                                        drawline256(x4+(xdim<<11),y4+(ydim<<11),
        !          4803:                                                                                        x1+(xdim<<11),y1+(ydim<<11),col);
        !          4804: 
        !          4805:                                                }
        !          4806:                                                break;
        !          4807:                                }
        !          4808:                        }
        !          4809: 
        !          4810:                //Draw white lines
        !          4811:        for(i=0;i<numsectors;i++)
        !          4812:        {
        !          4813:                startwall = sector[i].wallptr;
        !          4814:                endwall = sector[i].wallptr + sector[i].wallnum - 1;
        !          4815: 
        !          4816:                for(j=startwall,wal=&wall[startwall];j<=endwall;j++,wal++)
        !          4817:                {
        !          4818:                        if (wal->nextwall >= 0) continue;
        !          4819: 
        !          4820:                        if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue;
        !          4821: 
        !          4822:                        if (tilesizx[wal->picnum] == 0) continue;
        !          4823:                        if (tilesizy[wal->picnum] == 0) continue;
        !          4824: 
        !          4825:                        ox = wal->x-cposx; oy = wal->y-cposy;
        !          4826:                        x1 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
        !          4827:                        y1 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);
        !          4828: 
        !          4829:                        wal2 = &wall[wal->point2];
        !          4830:                        ox = wal2->x-cposx; oy = wal2->y-cposy;
        !          4831:                        x2 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
        !          4832:                        y2 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);
        !          4833: 
        !          4834:                        drawline256(x1+(xdim<<11),y1+(ydim<<11),x2+(xdim<<11),y2+(ydim<<11),24);
        !          4835:                }
        !          4836:        }
        !          4837: }
        !          4838: 
        !          4839:        //New movesprite using getzrange.  Note that I made the getzrange
        !          4840:        //parameters global (&globhiz,&globhihit,&globloz,&globlohit) so they
        !          4841:        //don't need to be passed everywhere.  Also this should make this
        !          4842:        //movesprite function compatible with the older movesprite functions.
        !          4843: movesprite(short spritenum, long dx, long dy, long dz, long ceildist, long flordist, char cliptype)
        !          4844: {
        !          4845:        long daz, zoffs, templong;
        !          4846:        short retval, dasectnum, tempshort;
        !          4847:        spritetype *spr;
        !          4848: 
        !          4849:        spr = &sprite[spritenum];
        !          4850: 
        !          4851:        if ((spr->cstat&128) == 0)
        !          4852:                zoffs = -((tilesizy[spr->picnum]*spr->yrepeat)<<1);
        !          4853:        else
        !          4854:                zoffs = 0;
        !          4855: 
        !          4856:        dasectnum = spr->sectnum;  //Can't modify sprite sectors directly becuase of linked lists
        !          4857:        daz = spr->z+zoffs;  //Must do this if not using the new centered centering (of course)
        !          4858:        retval = clipmove(&spr->x,&spr->y,&daz,&dasectnum,dx,dy,
        !          4859:                                                        ((long)spr->clipdist)<<2,ceildist,flordist,cliptype);
        !          4860: 
        !          4861:        if ((dasectnum != spr->sectnum) && (dasectnum >= 0))
        !          4862:                changespritesect(spritenum,dasectnum);
        !          4863: 
        !          4864:                //Set the blocking bit to 0 temporarly so getzrange doesn't pick up
        !          4865:                //its own sprite
        !          4866:        tempshort = spr->cstat; spr->cstat &= ~1;
        !          4867:        getzrange(spr->x,spr->y,spr->z-1,spr->sectnum,
        !          4868:                                 &globhiz,&globhihit,&globloz,&globlohit,
        !          4869:                                 ((long)spr->clipdist)<<2,cliptype);
        !          4870:        spr->cstat = tempshort;
        !          4871: 
        !          4872:        daz = spr->z+zoffs + dz;
        !          4873:        if ((daz <= globhiz) || (daz > globloz))
        !          4874:        {
        !          4875:                if (retval != 0) return(retval);
        !          4876:                return(16384+dasectnum);
        !          4877:        }
        !          4878:        spr->z = daz-zoffs;
        !          4879:        return(retval);
        !          4880: }
        !          4881: 
        !          4882: waitforeverybody()
        !          4883: {
        !          4884:        long i, j, oldtotalclock;
        !          4885: 
        !          4886:        if (numplayers < 2) return;
        !          4887: 
        !          4888:        if (myconnectindex == connecthead)
        !          4889:        {
        !          4890:                for(j=1;j<=2;j++)
        !          4891:                {
        !          4892:                        for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i])
        !          4893:                                playerreadyflag[i] = 0;
        !          4894:                        oldtotalclock = totalclock-8;
        !          4895:                        do
        !          4896:                        {
        !          4897:                                getpackets();
        !          4898:                                if (totalclock >= oldtotalclock+8)
        !          4899:                                {
        !          4900:                                        oldtotalclock = totalclock;
        !          4901:                                        tempbuf[0] = 5;
        !          4902:                                        tempbuf[1] = j;
        !          4903:                                        for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i])
        !          4904:                                                if (playerreadyflag[i] != j) sendpacket(i,tempbuf,2);
        !          4905:                                }
        !          4906:                                for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i])
        !          4907:                                        if (playerreadyflag[i] != j) break;
        !          4908:                        } while (i >= 0);
        !          4909:                }
        !          4910:        }
        !          4911:        else
        !          4912:        {
        !          4913:                playerreadyflag[connecthead] = 0;
        !          4914:                while (playerreadyflag[connecthead] != 2)
        !          4915:                {
        !          4916:                        getpackets();
        !          4917:                        if (playerreadyflag[connecthead] == 1)
        !          4918:                        {
        !          4919:                                playerreadyflag[connecthead] = 0;
        !          4920:                                sendpacket(connecthead,tempbuf,2);
        !          4921:                        }
        !          4922:                }
        !          4923:        }
        !          4924: }
        !          4925: 
        !          4926: getsyncstat()
        !          4927: {
        !          4928:        long i, j;
        !          4929:        unsigned short crc;
        !          4930:        spritetype *spr;
        !          4931: 
        !          4932:        crc = 0;
        !          4933:        updatecrc16(crc,randomseed); updatecrc16(crc,randomseed>>8);
        !          4934:        for(i=connecthead;i>=0;i=connectpoint2[i])
        !          4935:        {
        !          4936:                updatecrc16(crc,posx[i]); //if (syncstat != 0) printf("%ld ",posx[i]);
        !          4937:                updatecrc16(crc,posy[i]); //if (syncstat != 0) printf("%ld ",posy[i]);
        !          4938:                updatecrc16(crc,posz[i]); //if (syncstat != 0) printf("%ld ",posz[i]);
        !          4939:                updatecrc16(crc,ang[i]); //if (syncstat != 0) printf("%ld ",ang[i]);
        !          4940:                updatecrc16(crc,horiz[i]); //if (syncstat != 0) printf("%ld ",horiz[i]);
        !          4941:                updatecrc16(crc,health[i]); //if (syncstat != 0) printf("%ld ",health[i]);
        !          4942:        }
        !          4943: 
        !          4944:        for(i=7;i>=0;i--)
        !          4945:                for(j=headspritestat[i];j>=0;j=nextspritestat[j])
        !          4946:                {
        !          4947:                        spr = &sprite[j];
        !          4948:                        updatecrc16(crc,spr->x); //if (syncstat != 0) printf("%ld ",spr->x);
        !          4949:                        updatecrc16(crc,spr->y); //if (syncstat != 0) printf("%ld ",spr->y);
        !          4950:                        updatecrc16(crc,spr->z); //if (syncstat != 0) printf("%ld ",spr->z);
        !          4951:                        updatecrc16(crc,spr->ang); //if (syncstat != 0) printf("%ld ",spr->ang);
        !          4952:                }
        !          4953:        //if (syncstat != 0) printf("\n");
        !          4954:        return(crc);
        !          4955: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.