|
|
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)§or[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(§or[dasector].ceilingz,daz,6L,6L)) >= 0) ! 621: wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,¢x,¢y,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)§or[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(§or[dasector].floorz,daz,6L,6L)) >= 0) ! 653: wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,¢x,¢y,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,¢x,¢y,0); ! 718: wsayfollow("updowndr.wav",4096L+256L,256L,¢x,¢y,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,¢x,¢y,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,¢x,¢y,0); ! 806: wsayfollow("updowndr.wav",4096L+64L,256L,¢x,¢y,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,¶llaxtype,1); ! 4190: read(fil,¶llaxyoffs,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,¶llaxtype,1); ! 4382: write(fil,¶llaxyoffs,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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.