Annotation of src/corr7eff.c, revision 1.1.1.1

1.1       root        1: /***************************************************************************
                      2:  *   CORR7EFF.C - Special effects functions for Corridor 7
                      3:  *
                      4:  *                                                     02/29/96  Les Bird
                      5:  ***************************************************************************/
                      6: 
                      7: #include "icorp.h"
                      8: #include <memcheck.h>
                      9: 
                     10: #define   MAXBONUSES               100  // maximum polygon bonuses per level
                     11: #define   MAXBLOODCOUNT            16
                     12: #define   MAXGORECOUNT             64
                     13: #define   MAXMOVINGSECTORS         10
                     14: #define   MAXMOVINGSECTORPOINTS    200
                     15: #define   MAXMOVINGSECTORSECTORS   25
                     16: #define   MAXMOVINGDOORS           MAXDOORS
                     17: 
                     18: int  bloodCount,
                     19:      goreCount;
                     20: 
                     21: short lastDamageClock;
                     22: 
                     23: short goreSprite[MAXGORECOUNT];
                     24: 
                     25: short frames[MAXSPRITES],
                     26:      frameDelay[MAXSPRITES],
                     27:      frameDelayReset[MAXSPRITES];
                     28: 
                     29: short hitagWallIndex[MAXWALLS],
                     30:      hitagSpriteIndex[MAXSPRITES];
                     31: 
                     32: char spriteSwitchStatus[MAXSPRITES>>3],
                     33:      wallSwitchStatus[MAXWALLS>>3];
                     34: 
                     35: short belowWaterIndex[MAXSECTORS],
                     36:      doorIndex[MAXSECTORS],
                     37:      movingDoor[MAXMOVINGDOORS],
                     38:      movingSectorIndex[MAXSECTORS],
                     39:      numDoors,
                     40:      numMovingDoors,
                     41:      numMovingSectors;
                     42: 
                     43: short lightWallIndex[MAXLIGHTEFFECTS];
                     44: 
                     45: short sectorEffectIndex[MAXSECTOREFFECTS];
                     46: 
                     47: struct sectorEffect sectorEffectStruct[MAXSECTOREFFECTS];
                     48: 
                     49: struct sectorCenters sectorCenter[MAXSECTORS],
                     50:      *sectorCenterPtr[MAXSECTORS];
                     51: 
                     52: struct message message[MAXMESSAGES],
                     53:      *messagePtr[MAXMESSAGES];
                     54: 
                     55: struct doorData door[MAXDOORS],
                     56:      *doorPtr[MAXDOORS];
                     57: 
                     58: struct movingSectorData {
                     59:      char active;
                     60:      char speed;
                     61:      char goalSpeed;
                     62:      char maxSpeed;
                     63:      short sectnum;
                     64:      short delay;
                     65:      short pivotSprite;
                     66:      short targetSprite;
                     67:      short numSectors;
                     68:      short sector[MAXMOVINGSECTORSECTORS];
                     69:      short pointDeltaX[MAXMOVINGSECTORPOINTS];
                     70:      short pointDeltaY[MAXMOVINGSECTORPOINTS];
                     71: } movingSector[MAXMOVINGSECTORS],
                     72:      *movingSectorPtr[MAXMOVINGSECTORS];
                     73: 
                     74: void
                     75: EFF_init(void)
                     76: {
                     77:      int  i;
                     78: 
                     79:      for (i=0 ; i < MAXSECTORS ; i++) {
                     80:           sectorCenterPtr[i]=&sectorCenter[i];
                     81:      }
                     82:      for (i=0 ; i < MAXMESSAGES ; i++) {
                     83:           messagePtr[i]=&message[i];
                     84:      }
                     85:      for (i=0 ; i < MAXDOORS ; i++) {
                     86:           doorPtr[i]=&door[i];
                     87:      }
                     88:      for (i=0 ; i < MAXMOVINGSECTORS ; i++) {
                     89:           movingSectorPtr[i]=&movingSector[i];
                     90:      }
                     91: }
                     92: 
                     93: void
                     94: EFF_unInit(void)
                     95: {
                     96: }
                     97: 
                     98: short
                     99: EFF_getDoorSpeed(short s)
                    100: {
                    101:      return(sectorPtr[s]->extra&0x00FF);
                    102: }
                    103: 
                    104: void
                    105: EFF_setDoorSpeed(short s,short n)
                    106: {
                    107:      sectorPtr[s]->extra&=~0x00FF;
                    108:      sectorPtr[s]->extra|=(n&0x00FF);
                    109: }
                    110: 
                    111: short
                    112: EFF_getDoorLock(short s)
                    113: {
                    114:      return((sectorPtr[s]->extra>>8)&0x00FF);
                    115: }
                    116: 
                    117: void
                    118: EFF_setDoorLock(short s,short n)
                    119: {
                    120:      sectorPtr[s]->extra&=~0xFF00;
                    121:      sectorPtr[s]->extra|=((n&0x00FF)<<8);
                    122: }
                    123: 
                    124: int
                    125: EFF_isBonusSector(short s)
                    126: {
                    127:      if (sectorPtr[s]->lotag == SEC_BONUSSECTORTAG) {
                    128:           return(1);
                    129:      }
                    130:      return(0);
                    131: }
                    132: 
                    133: short
                    134: EFF_getBonusSectorItem(short s)
                    135: {
                    136:      return((sectorPtr[s]->extra>>8)&0x00FF);
                    137: }
                    138: 
                    139: void
                    140: EFF_setBonusSectorItem(short s,short n)
                    141: {
                    142:      sectorPtr[s]->extra&=~0xFF00;
                    143:      sectorPtr[s]->extra|=((n&0x00FF)<<8);
                    144: }
                    145: 
                    146: short
                    147: EFF_getBonusSectorValue(short s)
                    148: {
                    149:      return(sectorPtr[s]->hitag);
                    150: }
                    151: 
                    152: void
                    153: EFF_setBonusSectorValue(short s,short n)
                    154: {
                    155:      sectorPtr[s]->hitag=n;
                    156: }
                    157: 
                    158: void
                    159: EFF_deleteBonusSector(short s)
                    160: {
                    161:      short i,j,newpic,sectnum;
                    162:      long newx,newy,newz,startz;
                    163:      signed char newshade;
                    164:      struct doorData *dptr;
                    165: 
                    166:      dptr=doorPtr[doorIndex[s]];
                    167:      startz=sectorPtr[s]->floorz;
                    168:      sectnum=nextsectorneighborz(s,startz,1,1);
                    169:      newz=sectorPtr[sectnum]->floorz;
                    170:      newpic=sectorPtr[sectnum]->floorpicnum;
                    171:      newshade=sectorPtr[sectnum]->floorshade;
                    172:      sectorPtr[s]->floorz=newz;
                    173:      sectorPtr[s]->floorpicnum=newpic;
                    174:      sectorPtr[s]->floorshade=newshade;
                    175:      sectorPtr[s]->lotag=0;
                    176:      i=0;
                    177:      while ((j=dptr->wallIndex[i]) >= 0) {
                    178:           newx=dptr->wallx[i];
                    179:           newy=dptr->wally[i];
                    180:           dragpoint(j,newx,newy);
                    181:           i++;
                    182:      }
                    183: }
                    184: 
                    185: short
                    186: EFF_getSpriteKey(short s)
                    187: {
                    188:      return(spritePtr[s]->extra);
                    189: }
                    190: 
                    191: void
                    192: EFF_setSpriteKey(short s,short n)
                    193: {
                    194:      spritePtr[s]->extra=n;
                    195: }
                    196: 
                    197: short
                    198: EFF_getWallKey(short w)
                    199: {
                    200:      return(wallPtr[w]->extra);
                    201: }
                    202: 
                    203: void
                    204: EFF_setWallKey(short w,short n)
                    205: {
                    206:      wallPtr[w]->extra=n;
                    207: }
                    208: 
                    209: short
                    210: EFF_getWarpDestination(short w)
                    211: {
                    212:      return(wallPtr[w]->hitag);
                    213: }
                    214: 
                    215: void
                    216: EFF_setWarpDestination(short w,short n)
                    217: {
                    218:      wallPtr[w]->hitag=n;
                    219: }
                    220: 
                    221: short
                    222: EFF_getWarpSpriteTag(short s)
                    223: {
                    224:      return(spritePtr[s]->hitag);
                    225: }
                    226: 
                    227: void
                    228: EFF_setWarpSpriteTag(short s,short n)
                    229: {
                    230:      spritePtr[s]->hitag=n;
                    231: }
                    232: 
                    233: int
                    234: EFF_isWallSwitch(short w)
                    235: {
                    236:      switch (wallPtr[w]->lotag) {
                    237:      case WAL_SWITCHTAG:
                    238:           return(1);
                    239:      }
                    240:      return(0);
                    241: }
                    242: 
                    243: int
                    244: EFF_isWallTrigger(short w)
                    245: {
                    246:      switch (wallPtr[w]->lotag) {
                    247:      case WAL_TRIGGERTAG:
                    248:           return(1);
                    249:      }
                    250:      return(0);
                    251: }
                    252: 
                    253: int
                    254: EFF_isSpriteSwitch(short s)
                    255: {
                    256:      switch (spritePtr[s]->lotag) {
                    257:      case SPR_SWITCHTAG:
                    258:           return(1);
                    259:      }
                    260:      return(0);
                    261: }
                    262: 
                    263: int
                    264: EFF_getSpriteSwitchStatus(short s)
                    265: {
                    266:      if ((spriteSwitchStatus[s>>3]&(1<<(s&7))) != 0) {
                    267:           return(1);
                    268:      }
                    269:      return(0);
                    270: }
                    271: 
                    272: void
                    273: EFF_setSpriteSwitchStatus(short s,short onoff)
                    274: {
                    275:      if (onoff) {
                    276:           spriteSwitchStatus[s>>3]|=(1<<(s&7));
                    277:      }
                    278:      else {
                    279:           spriteSwitchStatus[s>>3]&=~(1<<(s&7));
                    280:      }
                    281: }
                    282: 
                    283: int
                    284: EFF_getWallSwitchStatus(short w)
                    285: {
                    286:      if ((wallSwitchStatus[w>>3]&(1<<(w&7))) != 0) {
                    287:           return(1);
                    288:      }
                    289:      return(0);
                    290: }
                    291: 
                    292: void
                    293: EFF_setWallSwitchStatus(short w,short onoff)
                    294: {
                    295:      if (onoff) {
                    296:           wallSwitchStatus[w>>3]|=(1<<(w&7));
                    297:      }
                    298:      else {
                    299:           wallSwitchStatus[w>>3]&=~(1<<(w&7));
                    300:      }
                    301: }
                    302: 
                    303: int
                    304: EFF_checkSwitches(short hitag,short *key)
                    305: {
                    306:      short i,n=0,retval=0,s,w;
                    307: 
                    308:      if (hitag > 0) {
                    309:           i=0;
                    310:           while ((s=hitagSpriteIndex[i++]) >= 0) {
                    311:                if (spritePtr[s]->hitag != hitag) {
                    312:                     continue;
                    313:                }
                    314:                if (EFF_isSpriteSwitch(s)) {
                    315:                     if (EFF_getSpriteSwitchStatus(s)) {
                    316:                          n+=EFF_getSpriteKey(s);
                    317:                          retval=1;
                    318:                     }
                    319:                }
                    320:                else if (EFF_isMovingSectorMarker(s)) {
                    321:                     retval=1;
                    322:                }
                    323:           }
                    324:           i=0;
                    325:           while ((w=hitagWallIndex[i++]) >= 0) {
                    326:                if (wallPtr[w]->hitag != hitag) {
                    327:                     continue;
                    328:                }
                    329:                if (EFF_isWallSwitch(w)) {
                    330:                     if (EFF_getWallSwitchStatus(w)) {
                    331:                          n+=EFF_getWallKey(w);
                    332:                          retval=1;
                    333:                     }
                    334:                }
                    335:                else if (EFF_isWallTrigger(w)) {
                    336:                     retval=1;
                    337:                }
                    338:           }
                    339:      }
                    340:      else {
                    341:           retval=1;
                    342:      }
                    343:      *key=n;
                    344:      return(retval);
                    345: }
                    346: 
                    347: int
                    348: EFF_testSpriteFlag(short s,short n)
                    349: {
                    350:      return(spritePtr[s]->yvel&n);
                    351: }
                    352: 
                    353: short
                    354: EFF_getSpriteFlag(short s)
                    355: {
                    356:      return(spritePtr[s]->yvel);
                    357: }
                    358: 
                    359: void
                    360: EFF_setSpriteFlag(short s,short n)
                    361: {
                    362:      spritePtr[s]->yvel|=n;
                    363: }
                    364: 
                    365: void
                    366: EFF_resetSpriteFlag(short s,short n)
                    367: {
                    368:      spritePtr[s]->yvel&=~n;
                    369: }
                    370: 
                    371: void
                    372: EFF_setSpriteFrames(short s, long tics, short picbeg, short picend)
                    373: {
                    374:      spritePtr[s]->picnum = picbeg;
                    375:      frameDelayReset[s] = tics;
                    376:      frameDelay[s] = tics;
                    377:      frames[s] = picend - picbeg;
                    378: }
                    379: 
                    380: short
                    381: EFF_getSectorLight(short s)
                    382: {
                    383:      return(sectorPtr[s]->visibility);
                    384: }
                    385: 
                    386: void
                    387: EFF_setSectorLight(short s,short n)
                    388: {
                    389:      sectorPtr[s]->visibility=n;
                    390: }
                    391: 
                    392: short
                    393: EFF_adjSectorLight(short s,short n)
                    394: {
                    395:      short v;
                    396: 
                    397:      v=EFF_getSectorLight(s);
                    398:      v+=n;
                    399:      if (v > 239) {
                    400:           EFF_setSectorLight(s,239);
                    401:      }
                    402:      else if (v < 0) {
                    403:           EFF_setSectorLight(s,0);
                    404:      }
                    405:      else {
                    406:           EFF_setSectorLight(s,v);
                    407:      }
                    408:      return(v);
                    409: }
                    410: 
                    411: void
                    412: EFF_sectorLightsOff(short s)
                    413: {
                    414:      EFF_setSectorLight(s,239);
                    415: }
                    416: 
                    417: void
                    418: EFF_sectorLightsOn(short s)
                    419: {
                    420:      EFF_setSectorLight(s,0);
                    421: }
                    422: 
                    423: short
                    424: EFF_getDamageClock(void)
                    425: {
                    426:      return(lastDamageClock);
                    427: }
                    428: 
                    429: void
                    430: EFF_resetDamageClock(void)
                    431: {
                    432:      lastDamageClock=0;
                    433: }
                    434: 
                    435: //**
                    436: //** Special effects code
                    437: //**
                    438: 
                    439: short
                    440: EFF_getNextSectorEffectIndex(void)
                    441: {
                    442:      short i;
                    443: 
                    444:      for (i=0 ; i < MAXSECTOREFFECTS ; i++) {
                    445:           if (sectorEffectIndex[i] == -1) {
                    446:                return(i);
                    447:           }
                    448:      }
                    449:      return(-1);
                    450: }
                    451: 
                    452: short
                    453: EFF_addSectorEffect(short s,short tag)
                    454: {
                    455:      short j;
                    456: 
                    457:      if ((j=EFF_getNextSectorEffectIndex()) >= 0) {
                    458:           sectorEffectIndex[j]=s;
                    459:           sectorEffectStruct[j].effectTag=tag;
                    460:      }
                    461:      return(j);
                    462: }
                    463: 
                    464: void
                    465: EFF_warpEffect(short s)
                    466: {
                    467:      short j;
                    468: 
                    469:      j=ENG_insertsprite(spritePtr[s]->sectnum,STAT_HITSCANEXPLODE);
                    470:      spritePtr[j]->x=spritePtr[s]->x;
                    471:      spritePtr[j]->y=spritePtr[s]->y;
                    472:      spritePtr[j]->z=spritePtr[s]->z-(32<<8);
                    473:      spritePtr[j]->cstat=SPRC_REALCENTERED;
                    474:      spritePtr[j]->xrepeat=64;
                    475:      spritePtr[j]->yrepeat=64;
                    476:      spritePtr[j]->shade=0;
                    477:      EFF_setSpriteFrames(j,TMR_getSecondFraction(16),WARPBEGPIC,WARPENDPIC);
                    478:      SND_playTeleportSound(j);
                    479: }
                    480: 
                    481: void
                    482: EFF_warpSprite(short w,short snum,short *ang,short *sect,
                    483:                long *x,long *y,long *z)
                    484: {
                    485:      short warpto;
                    486: 
                    487:      warpto=EFF_getWarpDestination(w);
                    488:      EFF_warpEffect(snum);
                    489:      EFF_warpEffect(warpto);
                    490:      *x=spritePtr[warpto]->x;
                    491:      *y=spritePtr[warpto]->y;
                    492:      *z=spritePtr[warpto]->z;
                    493:      *sect=spritePtr[warpto]->sectnum;
                    494:      *ang=spritePtr[warpto]->ang;
                    495: }
                    496: 
                    497: void
                    498: EFF_spawnSplash(spritetype *spr)
                    499: {
                    500: }
                    501: 
                    502: void
                    503: EFF_warpBelowWater(short s,spritetype *spr,short *sect,long *x,long *y,long *z)
                    504: {
                    505:      short clipdist,clipheight,cursect,newsect;
                    506:      long offsetx,offsety;
                    507: 
                    508:      cursect=*sect;     
                    509:      if ((newsect=belowWaterIndex[cursect]) == -1) {
                    510:           return;
                    511:      }
                    512:      EFF_spawnSplash(spr);
                    513:      clipdist=ACT_getActorClipDist(spr);
                    514:      clipheight=ACT_getActorClipHeight(spr);
                    515:      offsetx=sectorCenterPtr[cursect]->centerx-*x;
                    516:      offsety=sectorCenterPtr[cursect]->centery-*y;
                    517:      *sect=newsect;
                    518:      *x=sectorCenterPtr[newsect]->centerx-offsetx;
                    519:      *y=sectorCenterPtr[newsect]->centery-offsety;
                    520:      *z=sectorPtr[newsect]->ceilingz+(clipheight<<1);
                    521:      getzrange(*x,*y,*z,newsect,&globhiz,&globhihit,&globloz,&globlohit,
                    522:                clipdist,clipheight);
                    523:      GAM_underWater(s,1);
                    524:      GAM_onGround(s,0);
                    525: }
                    526: 
                    527: void
                    528: EFF_warpAboveWater(short s,spritetype *spr,short *sect,long *x,long *y,long *z)
                    529: {
                    530:      short clipdist,clipheight,cursect,newsect;
                    531:      long offsetx,offsety;
                    532: 
                    533:      cursect=*sect;
                    534:      if ((newsect=belowWaterIndex[cursect]) == -1) {
                    535:           return;
                    536:      }
                    537:      EFF_spawnSplash(spr);
                    538:      clipdist=ACT_getActorClipDist(spr);
                    539:      clipheight=ACT_getActorClipHeight(spr);
                    540:      offsetx=sectorCenterPtr[cursect]->centerx-*x;
                    541:      offsety=sectorCenterPtr[cursect]->centery-*y;
                    542:      *sect=newsect;
                    543:      *x=sectorCenterPtr[newsect]->centerx-offsetx;
                    544:      *y=sectorCenterPtr[newsect]->centery-offsety;
                    545:      *z=sectorPtr[newsect]->floorz-(clipheight<<1);
                    546:      getzrange(*x,*y,*z,newsect,&globhiz,&globhihit,&globloz,&globlohit,
                    547:                clipdist,clipheight);
                    548:      GAM_underWater(s,0);
                    549:      GAM_onGround(s,1);
                    550: }
                    551: 
                    552: int
                    553: EFF_isAboveWaterSector(short s)
                    554: {
                    555:      switch (sectorPtr[s]->lotag) {
                    556:      case SEC_ABOVEWATERTAG:
                    557:           return(1);
                    558:           break;
                    559:      }
                    560:      return(0);
                    561: }
                    562: 
                    563: int
                    564: EFF_isBelowWaterSector(short s)
                    565: {
                    566:      switch (sectorPtr[s]->lotag) {
                    567:      case SEC_BELOWWATERTAG:
                    568:           return(1);
                    569:           break;
                    570:      }
                    571:      return(0);
                    572: }
                    573: 
                    574: void
                    575: EFF_onSprite(short snum,short onsprite,short *ang,short *sect,
                    576:              long *x,long *y,long *z)
                    577: {
                    578:      short i,j;
                    579:      spritetype *spr;
                    580: 
                    581:      spr=spritePtr[snum];
                    582:      switch (spritePtr[onsprite]->lotag) {
                    583:      case SPR_BLUEKEYTAG:
                    584:           if (PLR_isPlayer(spr,-1)) {
                    585:                PLR_addInventoryItem(snum,INV_BLUEKEY);
                    586:                ENG_deletesprite(onsprite);
                    587:           }
                    588:           break;
                    589:      case SPR_YELLOWKEYTAG:
                    590:           if (PLR_isPlayer(spr,-1)) {
                    591:                PLR_addInventoryItem(snum,INV_YELLOWKEY);
                    592:                ENG_deletesprite(onsprite);
                    593:           }
                    594:           break;
                    595:      case SPR_BACKPACKTAG:
                    596:           for (i=0 ; i < MAXWEAPONS ; i++) {
                    597:                if (weaponPtr[i]->registered) {
                    598:                     WEP_setMaxAmmo(snum,weaponPtr[i]->registered-1,
                    599:                                    weaponPtr[i]->defaultAmmo<<1);
                    600:                     j=WEP_getMaxAmmo(snum,weaponPtr[i]->registered-1);
                    601:                     WEP_setAmmo(snum,weaponPtr[i]->registered-1,j);
                    602:                }
                    603:           }
                    604:           ENG_deletesprite(onsprite);
                    605:           break;
                    606:      case SPR_REDKEYTAG:
                    607:           if (PLR_isPlayer(spr,-1)) {
                    608:                PLR_addInventoryItem(snum,INV_REDKEY);
                    609:                ENG_deletesprite(onsprite);
                    610:           }
                    611:           break;
                    612:      case SPR_CELLCHARGEPACKTAG:
                    613:           j=WEP_getMaxAmmo(snum,WEAPON_ENERGY);
                    614:           if (WEP_getAmmo(snum,WEAPON_ENERGY) < j) {
                    615:                WEP_adjAmmo(snum,WEAPON_ENERGY,j);
                    616:                ENG_deletesprite(onsprite);
                    617:           }
                    618:           break;
                    619:      case SPR_REDSKULLKEYTAG:
                    620:           if (PLR_isPlayer(spr,-1)) {
                    621:                PLR_addInventoryItem(snum,INV_REDKEY);
                    622:                ENG_deletesprite(onsprite);
                    623:           }
                    624:           break;
                    625:      case SPR_YELLOWSKULLKEYTAG:
                    626:           if (PLR_isPlayer(spr,-1)) {
                    627:                PLR_addInventoryItem(snum,INV_YELLOWKEY);
                    628:                ENG_deletesprite(onsprite);
                    629:           }
                    630:           break;
                    631:      case SPR_BLUESKULLKEYTAG:
                    632:           if (PLR_isPlayer(spr,-1)) {
                    633:                PLR_addInventoryItem(snum,INV_BLUEKEY);
                    634:                ENG_deletesprite(onsprite);
                    635:           }
                    636:           break;
                    637:      case SPR_DOUBLESHOTGUNTAG:
                    638:           i=WEP_getWeaponAmmoType(GUN_4);
                    639:           j=WEP_getMaxAmmo(snum,i);
                    640:           WEP_addWeapon(snum,GUN_4);
                    641:           if (WEP_getAmmo(snum,i) < WEP_getMaxAmmo(snum,i)) {
                    642:                WEP_adjAmmo(snum,i,weaponPtr[GUN_4]->defaultAmmo);
                    643:                ENG_deletesprite(onsprite);
                    644:           }
                    645:           break;
                    646:      case SPR_MEGASPHERETAG:
                    647:           if (ACT_getHealth(snum) < playerMaxHealth) {
                    648:                j=ACT_getHealth(onsprite);
                    649:                if (j <= 0) {
                    650:                     j=playerMaxHealth<<1;
                    651:                }
                    652:                ACT_healActor(snum,j);
                    653:                ENG_deletesprite(onsprite);
                    654:           }
                    655:           break;
                    656:      case SPR_SHOTGUNTAG:
                    657:           i=WEP_getWeaponAmmoType(GUN_3);
                    658:           j=WEP_getMaxAmmo(snum,i);
                    659:           WEP_addWeapon(snum,GUN_3);
                    660:           if (WEP_getAmmo(snum,i) < WEP_getMaxAmmo(snum,i)) {
                    661:                WEP_adjAmmo(snum,i,weaponPtr[GUN_3]->defaultAmmo);
                    662:                ENG_deletesprite(onsprite);
                    663:           }
                    664:           break;
                    665:      case SPR_CHAINGUNTAG:
                    666:           i=WEP_getWeaponAmmoType(GUN_1);
                    667:           j=WEP_getMaxAmmo(snum,i);
                    668:           WEP_addWeapon(snum,GUN_1);
                    669:           if (WEP_getAmmo(snum,i) < WEP_getMaxAmmo(snum,i)) {
                    670:                WEP_adjAmmo(snum,i,weaponPtr[GUN_1]->defaultAmmo);
                    671:                ENG_deletesprite(onsprite);
                    672:           }
                    673:           break;
                    674:      case SPR_ROCKETLAUNCHERTAG:
                    675:           i=WEP_getWeaponAmmoType(GUN_5);
                    676:           j=WEP_getMaxAmmo(snum,i);
                    677:           WEP_addWeapon(snum,GUN_5);
                    678:           if (WEP_getAmmo(snum,i) < WEP_getMaxAmmo(snum,i)) {
                    679:                WEP_adjAmmo(snum,i,weaponPtr[GUN_5]->defaultAmmo);
                    680:                ENG_deletesprite(onsprite);
                    681:           }
                    682:           break;
                    683:      case SPR_PLASMAGUNTAG:
                    684:           i=WEP_getWeaponAmmoType(GUN_6);
                    685:           j=WEP_getMaxAmmo(snum,i);
                    686:           WEP_addWeapon(snum,GUN_6);
                    687:           if (WEP_getAmmo(snum,i) < WEP_getMaxAmmo(snum,i)) {
                    688:                WEP_adjAmmo(snum,i,weaponPtr[GUN_6]->defaultAmmo);
                    689:                ENG_deletesprite(onsprite);
                    690:           }
                    691:           break;
                    692:      case SPR_CHAINSAWTAG:
                    693:           i=WEP_getWeaponAmmoType(GUN_2);
                    694:           j=WEP_getMaxAmmo(snum,i);
                    695:           WEP_addWeapon(snum,GUN_2);
                    696:           if (WEP_getAmmo(snum,i) < WEP_getMaxAmmo(snum,i)) {
                    697:                WEP_adjAmmo(snum,i,weaponPtr[GUN_2]->defaultAmmo);
                    698:                ENG_deletesprite(onsprite);
                    699:           }
                    700:           break;
                    701:      case SPR_BFG9000TAG:
                    702:           i=WEP_getWeaponAmmoType(GUN_7);
                    703:           j=WEP_getMaxAmmo(snum,i);
                    704:           WEP_addWeapon(snum,GUN_7);
                    705:           if (WEP_getAmmo(snum,i) < WEP_getMaxAmmo(snum,i)) {
                    706:                WEP_adjAmmo(snum,i,weaponPtr[GUN_7]->defaultAmmo);
                    707:                ENG_deletesprite(onsprite);
                    708:           }
                    709:           break;
                    710:      case SPR_AMMOCLIPTAG:
                    711:           i=WEAPON_BULLET;
                    712:           if (WEP_getAmmo(snum,i) < WEP_getMaxAmmo(snum,i)) {
                    713:                WEP_adjAmmo(snum,i,25);
                    714:                ENG_deletesprite(onsprite);
                    715:           }
                    716:           break;
                    717:      case SPR_SHOTGUNSHELLSTAG:
                    718:           i=WEAPON_SHELL;
                    719:           if (WEP_getAmmo(snum,i) < WEP_getMaxAmmo(snum,i)) {
                    720:                WEP_adjAmmo(snum,i,5);
                    721:                ENG_deletesprite(onsprite);
                    722:           }
                    723:           break;
                    724:      case SPR_ROCKETTAG:
                    725:           i=WEAPON_MISSILE;
                    726:           if (WEP_getAmmo(snum,i) < WEP_getMaxAmmo(snum,i)) {
                    727:                WEP_adjAmmo(snum,i,2);
                    728:                ENG_deletesprite(onsprite);
                    729:           }
                    730:           break;
                    731:      case SPR_STIMPACKTAG:
                    732:           if (ACT_getHealth(snum) < playerMaxHealth) {
                    733:                j=ACT_getHealth(onsprite);
                    734:                if (j <= 0) {
                    735:                     j=playerMaxHealth>>3;
                    736:                }
                    737:                ACT_healActor(snum,j);
                    738:                ENG_deletesprite(onsprite);
                    739:           }
                    740:           break;
                    741:      case SPR_MEDIKITTAG:
                    742:           if (ACT_getHealth(snum) < playerMaxHealth) {
                    743:                j=ACT_getHealth(onsprite);
                    744:                if (j <= 0) {
                    745:                     j=playerMaxHealth>>2;
                    746:                }
                    747:                ACT_healActor(snum,j);
                    748:                ENG_deletesprite(onsprite);
                    749:           }
                    750:           break;
                    751:      case SPR_SOULSPHERETAG:
                    752:           if (ACT_getHealth(snum) < (playerMaxHealth<<1)) {
                    753:                j=ACT_getHealth(onsprite);
                    754:                if (j <= 0) {
                    755:                     j=playerMaxHealth<<1;
                    756:                }
                    757:                ACT_healActor(snum,j);
                    758:                ENG_deletesprite(onsprite);
                    759:           }
                    760:           break;
                    761:      case SPR_HEALTHPOTIONTAG:
                    762:           j=ACT_getHealth(onsprite);
                    763:           if (j <= 0) {
                    764:                j=playerMaxHealth/100;
                    765:           }
                    766:           ACT_healActor(snum,j);
                    767:           ENG_deletesprite(onsprite);
                    768:           break;
                    769:      case SPR_SPIRITARMORTAG:
                    770:      case SPR_GREENARMORTAG:
                    771:      case SPR_BLUEARMORTAG:
                    772:      case SPR_INVULNERABILITYTAG:
                    773:      case SPR_BERSERKTAG:
                    774:      case SPR_INVISIBILITYTAG:
                    775:      case SPR_RADIATIONSUITTAG:
                    776:      case SPR_COMPUTERMAPTAG:
                    777:      case SPR_LIGHTAMPLIFICATIONTAG:
                    778:           break;
                    779:      case SPR_BOXOFROCKETSTAG:
                    780:           i=WEAPON_MISSILE;
                    781:           if (WEP_getAmmo(snum,i) < WEP_getMaxAmmo(snum,i)) {
                    782:                WEP_adjAmmo(snum,i,25);
                    783:                ENG_deletesprite(onsprite);
                    784:           }
                    785:           break;
                    786:      case SPR_CELLCHARGETAG:
                    787:           i=WEAPON_ENERGY;
                    788:           if (WEP_getAmmo(snum,i) < WEP_getMaxAmmo(snum,i)) {
                    789:                WEP_adjAmmo(snum,i,50);
                    790:                ENG_deletesprite(onsprite);
                    791:           }
                    792:           break;
                    793:      case SPR_BOXOFAMMOTAG:
                    794:           i=WEAPON_BULLET;
                    795:           if (WEP_getAmmo(snum,i) < WEP_getMaxAmmo(snum,i)) {
                    796:                WEP_adjAmmo(snum,i,100);
                    797:                ENG_deletesprite(onsprite);
                    798:           }
                    799:           break;
                    800:      case SPR_BOXOFSHELLSTAG:
                    801:           i=WEAPON_SHELL;
                    802:           if (WEP_getAmmo(snum,i) < WEP_getMaxAmmo(snum,i)) {
                    803:                WEP_adjAmmo(snum,i,25);
                    804:                ENG_deletesprite(onsprite);
                    805:           }
                    806:           break;
                    807:      }
                    808: }
                    809: 
                    810: void
                    811: EFF_notify(long bcolor,char *fmt,...)
                    812: {
                    813:      va_list argptr;
                    814: 
                    815:      va_start(argptr,fmt);
                    816:      vsprintf(tempbuf,fmt,argptr);
                    817:      va_end(argptr);
                    818:      if (qsetmode == 0L) {
                    819:           lprintf("%s\n",tempbuf);
                    820:      }
                    821:      else if (qsetmode == 200L) {
                    822:           clearview(0L);
                    823:           if (gotpic[backgroundPic>>3]&(1<<(backgroundPic&7)) == 0) {
                    824:                loadtile(backgroundPic);
                    825:           }
                    826:           rotatesprite(320L<<15,200L<<15,65536L,0,
                    827:                        backgroundPic,0,0,2+8+64+128,
                    828:                        0L,0L,xdim-1L,ydim-1L);
                    829:           printext256((xdim >> 1) - (strlen(tempbuf) << 2), ydim >> 1,
                    830:                       P256COLOR, -1, tempbuf, 0);
                    831:           nextpage();
                    832:           GFX_fadeIn(255);
                    833:      }
                    834:      else if (editorEnabledFlag) {
                    835:           printmessage16(tempbuf);
                    836:      }
                    837: }
                    838: 
                    839: void
                    840: EFF_computeSectorCenter(short i)
                    841: {
                    842:      int  w;
                    843:      long cx,
                    844:           cy,
                    845:           endwall,
                    846:           startwall,
                    847:           walls;
                    848:      struct sectorCenters *sectx;
                    849:      sectortype *sect;
                    850:      
                    851:      sect=sectorPtr[i];
                    852:      sectx=sectorCenterPtr[i];
                    853:      cx=0L;
                    854:      cy=0L;
                    855:      startwall=sect->wallptr;
                    856:      endwall=sect->wallptr+sect->wallnum;
                    857:      walls=endwall-startwall;
                    858:      for (w=startwall ; w < endwall ; w++) {
                    859:           cx+=wallPtr[w]->x;
                    860:           cy+=wallPtr[w]->y;
                    861:      }
                    862:      sectx->centerx=cx/walls;
                    863:      sectx->centery=cy/walls;
                    864:      sectx->centerz=(sect->ceilingz+sect->floorz)>>1;
                    865: }
                    866: 
                    867: void
                    868: EFF_computeSectorCenters(void)
                    869: {
                    870:      int  i;
                    871: 
                    872:      if (qsetmode == 200L) {
                    873:           EFF_notify(0L,"COMPUTING %d SECTORS",numsectors);
                    874:      }
                    875:      for (i = 0; i < numsectors; i++) {
                    876:           if (qsetmode != 200L) {
                    877:                EFF_notify(0L,"COMPUTING SECTOR %d",i);
                    878:           }
                    879:           EFF_computeSectorCenter(i);
                    880:      }
                    881: }
                    882: 
                    883: int
                    884: EFF_isDoor(short s)
                    885: {
                    886:      switch (sectorPtr[s]->lotag) {
                    887:      case SEC_DOORUPTAG:
                    888:      case SEC_DOORUPONCETAG:
                    889:      case SEC_DOORDOWNTAG:
                    890:      case SEC_DOORDOWNONCETAG:
                    891:      case SEC_DOORHSPLITTAG:
                    892:      case SEC_DOORHSPLITONCETAG:
                    893:      case SEC_DOORSLIDECENTERTAG:
                    894:      case SEC_ROTATESECTORTAG:     // these are here because we use the
                    895:      case SEC_BONUSSECTORTAG:      // ..doorData structure array
                    896:           return(1);
                    897:      }
                    898:      return(0);
                    899: }
                    900: 
                    901: int
                    902: EFF_isElevator(short s)
                    903: {
                    904:      switch (sectorPtr[s]->lotag) {
                    905:      case SEC_PLATFORMDOWNTAG:
                    906:      case SEC_PLATFORMELEVATORTAG:
                    907:      case SEC_PLATFORMUPTAG:
                    908:           return(1);
                    909:      }
                    910:      return(0);
                    911: }
                    912: 
                    913: int
                    914: EFF_operatableSector(short s)
                    915: {
                    916:      if (EFF_isDoor(s) || EFF_isElevator(s)) {
                    917:           return(1);
                    918:      }
                    919:      return(0);
                    920: }
                    921: 
                    922: void
                    923: EFF_blockDoorWalls(short s)
                    924: {
                    925:      short w,wall1,wall2;
                    926:      long floorz2;
                    927: 
                    928:      if (EFF_isDoor(s)) {
                    929:           wall1=sectorPtr[s]->wallptr;
                    930:           wall2=wall1+sectorPtr[s]->wallnum;
                    931:           for (w=wall1 ; w < wall2 ; w++) {
                    932:                if (wallPtr[w]->nextwall != -1) {
                    933:                     wallPtr[wallPtr[w]->nextwall]->cstat|=1;
                    934:                }
                    935:           }
                    936:      }
                    937: #if 0
                    938:      else if (EFF_isElevator(s)) {
                    939:           wall1=sectorPtr[s]->wallptr;
                    940:           wall2=wall1+sectorPtr[s]->wallnum;
                    941:           for (w=wall1 ; w < wall2 ; w++) {
                    942:                if (wallPtr[w]->nextsector != -1) {
                    943:                     if (wallPtr[w]->nextwall == -1) {
                    944:                          continue;
                    945:                     }
                    946:                     floorz2=sectorPtr[wallPtr[w]->nextsector]->floorz;
                    947:                     if (labs(sectorPtr[s]->floorz-floorz2) >=
                    948:                         (defaultPlayerHeight<<8)) {
                    949:                          wallPtr[wallPtr[w]->nextwall]->cstat|=WALC_BLOCKING;
                    950:                     }
                    951:                }
                    952:           }
                    953:      }
                    954: #endif
                    955: }
                    956: 
                    957: void
                    958: EFF_unblockDoorWalls(short s)
                    959: {
                    960:      short w,wall1,wall2;
                    961: 
                    962:      wall1=sectorPtr[s]->wallptr;
                    963:      wall2=wall1+sectorPtr[s]->wallnum;
                    964:      for (w=wall1 ; w < wall2 ; w++) {
                    965:           if (wallPtr[w]->nextwall != -1) {
                    966:                wallPtr[wallPtr[w]->nextwall]->cstat&=~WALC_BLOCKING;
                    967:           }
                    968:      }
                    969: }
                    970: 
                    971: void
                    972: EFF_buildHitagIndex(void)
                    973: {
                    974:      int  i,j;
                    975: 
                    976:      for (i=0,j=0 ; i < MAXSPRITES ; i++) {
                    977:           if (spritePtr[i]->statnum >= MAXSTATUS) {
                    978:                continue;
                    979:           }
                    980:           if (EFF_isSpriteSwitch(i) || EFF_isMovingSectorMarker(i)) {
                    981:                if (EFF_getSpriteKey(i) < 0) {
                    982:                     EFF_setSpriteKey(i,0);
                    983:                }
                    984:                hitagSpriteIndex[j++]=i;
                    985:           }
                    986:      }
                    987:      hitagSpriteIndex[j]=-1;
                    988:      for (i=0,j=0 ; i < numwalls ; i++) {
                    989:           if (EFF_isWallSwitch(i) || EFF_isWallTrigger(i)) {
                    990:                if (EFF_getWallKey(i) < 0) {
                    991:                     EFF_setWallKey(i,0);
                    992:                }
                    993:                hitagWallIndex[j++]=i;
                    994:           }
                    995:      }
                    996:      hitagWallIndex[j]=-1;
                    997: }
                    998: 
                    999: void
                   1000: EFF_scanSprite(short i)
                   1001: {
                   1002:      short j;
                   1003:      spritetype *spr;
                   1004:      struct sectorEffect *si;
                   1005: 
                   1006:      spr=spritePtr[i];
                   1007:      if (spr->statnum < MAXSTATUS) {
                   1008:           if (ACT_isActor(i)) {
                   1009:                return;
                   1010:           }
                   1011:           switch (spr->lotag) {
                   1012:           case SPR_PANCEILTAG:
                   1013:                if ((j=EFF_addSectorEffect(spr->sectnum,SEC_PANCEILTAG)) >= 0) {
                   1014:                     si=&sectorEffectStruct[j];
                   1015:                     si->speed=spr->extra;
                   1016:                     si->ang=spr->ang;
                   1017:                }
                   1018:                ENG_deletesprite(i);
                   1019:                break;
                   1020:           case SPR_PANFLOORTAG:
                   1021:                if ((j=EFF_addSectorEffect(spr->sectnum,SEC_PANFLOORTAG)) >= 0) {
                   1022:                     si=&sectorEffectStruct[j];
                   1023:                     if (spr->extra < 0) {
                   1024:                          spr->extra=5;
                   1025:                     }
                   1026:                     si->speed=spr->extra;
                   1027:                     si->ang=spr->ang;
                   1028:                }
                   1029:                ENG_deletesprite(i);
                   1030:                break;
                   1031:           case SPR_BLUEKEYTAG:
                   1032:           case SPR_YELLOWKEYTAG:
                   1033:           case SPR_BACKPACKTAG:
                   1034:           case SPR_REDKEYTAG:
                   1035:           case SPR_CELLCHARGEPACKTAG:
                   1036:           case SPR_REDSKULLKEYTAG:
                   1037:           case SPR_YELLOWSKULLKEYTAG:
                   1038:           case SPR_BLUESKULLKEYTAG:
                   1039:           case SPR_DOUBLESHOTGUNTAG:
                   1040:           case SPR_MEGASPHERETAG:
                   1041:           case SPR_SHOTGUNTAG:
                   1042:           case SPR_CHAINGUNTAG:
                   1043:           case SPR_ROCKETLAUNCHERTAG:
                   1044:           case SPR_PLASMAGUNTAG:
                   1045:           case SPR_CHAINSAWTAG:
                   1046:           case SPR_BFG9000TAG:
                   1047:           case SPR_AMMOCLIPTAG:
                   1048:           case SPR_SHOTGUNSHELLSTAG:
                   1049:           case SPR_ROCKETTAG:
                   1050:           case SPR_STIMPACKTAG:
                   1051:           case SPR_MEDIKITTAG:
                   1052:           case SPR_SOULSPHERETAG:
                   1053:           case SPR_HEALTHPOTIONTAG:
                   1054:           case SPR_SPIRITARMORTAG:
                   1055:           case SPR_GREENARMORTAG:
                   1056:           case SPR_BLUEARMORTAG:
                   1057:           case SPR_INVULNERABILITYTAG:
                   1058:           case SPR_BERSERKTAG:
                   1059:           case SPR_INVISIBILITYTAG:
                   1060:           case SPR_RADIATIONSUITTAG:
                   1061:           case SPR_COMPUTERMAPTAG:
                   1062:           case SPR_LIGHTAMPLIFICATIONTAG:
                   1063:           case SPR_BOXOFROCKETSTAG:
                   1064:           case SPR_CELLCHARGETAG:
                   1065:           case SPR_BOXOFAMMOTAG:
                   1066:           case SPR_BOXOFSHELLSTAG:
                   1067:                spr->cstat|=SPRC_BLOCKING;
                   1068:                break;
                   1069:           case SPR_MOVINGSECTORTAG:
                   1070:                if (spr->statnum == STAT_NONE) {
                   1071:                     changespritestat(i,STAT_MOVINGSECTORMARKER);
                   1072:                     spr->cstat&=~(SPRC_BLOCKING|SPRC_BLOCKINGH);
                   1073:                     spr->cstat|=SPRC_INVISIBLE;
                   1074:                }
                   1075:                break;
                   1076:           }
                   1077:      }
                   1078: }
                   1079: 
                   1080: void
                   1081: EFF_scanSectorEffects(short s)
                   1082: {
                   1083:      short endwall,i,j,startwall,w,wto;
                   1084:      long areax1,areax2,areay1,areay2;
                   1085:      walltype *wal;
                   1086: 
                   1087:      startwall=sectorPtr[s]->wallptr;
                   1088:      endwall=startwall+sectorPtr[s]->wallnum;
                   1089:      for (w=startwall ; w < endwall ; w++) {
                   1090:           wal=wallPtr[w];
                   1091:           switch (wal->lotag) {
                   1092:           case WAL_WARPTAG:
                   1093:                wto=EFF_getWarpDestination(w);
                   1094:                for (j=0 ; j < MAXSPRITES ; j++) {
                   1095:                     if (spritePtr[j]->statnum >= MAXSTATUS) {
                   1096:                          continue;
                   1097:                     }
                   1098:                     if (spritePtr[j]->lotag != SPR_TELEPORTTAG) {
                   1099:                          continue;
                   1100:                     }
                   1101:                     if (EFF_getWarpSpriteTag(j) == wto) {
                   1102:                          EFF_setWarpDestination(w,j);
                   1103:                          break;
                   1104:                     }
                   1105:                }
                   1106:                break;
                   1107:           case WAL_W1LIGHTSOFFTAG:
                   1108:           case WAL_WRLIGHTSOFFTAG:
                   1109:           case WAL_SRLIGHTSOFFTAG:
                   1110:           case WAL_W1LIGHTSONFULLTAG:
                   1111:           case WAL_WRLIGHTSONFULLTAG:
                   1112:           case WAL_SRLIGHTSONFULLTAG:
                   1113:                for (j=0 ; j < MAXLIGHTEFFECTS ; j++) {
                   1114:                     if (lightWallIndex[j] == -1) {
                   1115:                          lightWallIndex[j]=w;
                   1116:                          break;
                   1117:                     }
                   1118:                }
                   1119:                break;
                   1120:           case WAL_MRMDOOROPENCLOSETAG:
                   1121:                if (sectorPtr[s]->lotag != SEC_DOORUPTAG) {
                   1122:                     sectorPtr[s]->lotag=SEC_DOORUPTAG;
                   1123:                     EFF_setDoorSpeed(s,DEFAULTDOORSPEED);
                   1124:                     EFF_setDoorLock(s,0);
                   1125:                     j=nextsectorneighborz(s,sectorPtr[s]->ceilingz,-1,-1);
                   1126:                     sectorPtr[s]->ceilingz=sectorPtr[j]->ceilingz;
                   1127:                }
                   1128:                wal->lotag=WAL_NORMAL;
                   1129:                break;
                   1130:           case WAL_MRMBLUEDOOROPENCLOSETAG:
                   1131:                if (sectorPtr[s]->lotag != SEC_DOORUPTAG) {
                   1132:                     sectorPtr[s]->lotag=SEC_DOORUPTAG;
                   1133:                     EFF_setDoorSpeed(s,DEFAULTDOORSPEED);
                   1134:                     EFF_setDoorLock(s,125+INV_BLUEKEY);
                   1135:                     j=nextsectorneighborz(s,sectorPtr[s]->ceilingz,-1,-1);
                   1136:                     sectorPtr[s]->ceilingz=sectorPtr[j]->ceilingz;
                   1137:                }
                   1138:                wal->lotag=WAL_NORMAL;
                   1139:                break;
                   1140:           case WAL_MRMYELLOWDOOROPENCLOSETAG:
                   1141:                if (sectorPtr[s]->lotag != SEC_DOORUPTAG) {
                   1142:                     sectorPtr[s]->lotag=SEC_DOORUPTAG;
                   1143:                     EFF_setDoorSpeed(s,DEFAULTDOORSPEED);
                   1144:                     EFF_setDoorLock(s,125+INV_YELLOWKEY);
                   1145:                     j=nextsectorneighborz(s,sectorPtr[s]->ceilingz,-1,-1);
                   1146:                     sectorPtr[s]->ceilingz=sectorPtr[j]->ceilingz;
                   1147:                }
                   1148:                wal->lotag=WAL_NORMAL;
                   1149:                break;
                   1150:           case WAL_MRMREDDOOROPENCLOSETAG:
                   1151:                if (sectorPtr[s]->lotag != SEC_DOORUPTAG) {
                   1152:                     sectorPtr[s]->lotag=SEC_DOORUPTAG;
                   1153:                     EFF_setDoorSpeed(s,DEFAULTDOORSPEED);
                   1154:                     EFF_setDoorLock(s,125+INV_REDKEY);
                   1155:                     j=nextsectorneighborz(s,sectorPtr[s]->ceilingz,-1,-1);
                   1156:                     sectorPtr[s]->ceilingz=sectorPtr[j]->ceilingz;
                   1157:                }
                   1158:                wal->lotag=WAL_NORMAL;
                   1159:                break;
                   1160:           case WAL_M1MDOOROPENSTAYTAG:
                   1161:                if (sectorPtr[s]->lotag != SEC_DOORUPONCETAG) {
                   1162:                     sectorPtr[s]->lotag=SEC_DOORUPONCETAG;
                   1163:                     EFF_setDoorSpeed(s,DEFAULTDOORSPEED);
                   1164:                     EFF_setDoorLock(s,0);
                   1165:                     j=nextsectorneighborz(s,sectorPtr[s]->ceilingz,-1,-1);
                   1166:                     sectorPtr[s]->ceilingz=sectorPtr[j]->ceilingz;
                   1167:                }
                   1168:                wal->lotag=WAL_NORMAL;
                   1169:                break;
                   1170:           case WAL_M1MBLUEDOOROPENSTAYTAG:
                   1171:                if (sectorPtr[s]->lotag != SEC_DOORUPONCETAG) {
                   1172:                     sectorPtr[s]->lotag=SEC_DOORUPONCETAG;
                   1173:                     EFF_setDoorSpeed(s,DEFAULTDOORSPEED);
                   1174:                     EFF_setDoorLock(s,125+INV_BLUEKEY);
                   1175:                     j=nextsectorneighborz(s,sectorPtr[s]->ceilingz,-1,-1);
                   1176:                     sectorPtr[s]->ceilingz=sectorPtr[j]->ceilingz;
                   1177:                }
                   1178:                wal->lotag=WAL_NORMAL;
                   1179:                break;
                   1180:           case WAL_M1MREDDOOROPENSTAYTAG:
                   1181:                if (sectorPtr[s]->lotag != SEC_DOORUPONCETAG) {
                   1182:                     sectorPtr[s]->lotag=SEC_DOORUPONCETAG;
                   1183:                     EFF_setDoorSpeed(s,DEFAULTDOORSPEED);
                   1184:                     EFF_setDoorLock(s,125+INV_REDKEY);
                   1185:                     j=nextsectorneighborz(s,sectorPtr[s]->ceilingz,-1,-1);
                   1186:                     sectorPtr[s]->ceilingz=sectorPtr[j]->ceilingz;
                   1187:                }
                   1188:                wal->lotag=WAL_NORMAL;
                   1189:                break;
                   1190:           case WAL_M1MYELLOWDOOROPENSTAYTAG:
                   1191:                if (sectorPtr[s]->lotag != SEC_DOORUPONCETAG) {
                   1192:                     sectorPtr[s]->lotag=SEC_DOORUPONCETAG;
                   1193:                     EFF_setDoorSpeed(s,DEFAULTDOORSPEED);
                   1194:                     EFF_setDoorLock(s,125+INV_YELLOWKEY);
                   1195:                     j=nextsectorneighborz(s,sectorPtr[s]->ceilingz,-1,-1);
                   1196:                     sectorPtr[s]->ceilingz=sectorPtr[j]->ceilingz;
                   1197:                }
                   1198:                wal->lotag=WAL_NORMAL;
                   1199:                break;
                   1200:           case WAL_MRTDOOROPENCLOSETAG:
                   1201:                if (sectorPtr[s]->lotag != SEC_DOORUPTAG) {
                   1202:                     sectorPtr[s]->lotag=SEC_DOORUPTAG;
                   1203:                     EFF_setDoorSpeed(s,50<<4);
                   1204:                     EFF_setDoorLock(s,0);
                   1205:                     j=nextsectorneighborz(s,sectorPtr[s]->ceilingz,-1,-1);
                   1206:                     sectorPtr[s]->ceilingz=sectorPtr[j]->ceilingz;
                   1207:                }
                   1208:                wal->lotag=WAL_NORMAL;
                   1209:                break;
                   1210:           case WAL_M1TDOOROPENSTAYTAG:
                   1211:                if (sectorPtr[s]->lotag != SEC_DOORUPONCETAG) {
                   1212:                     sectorPtr[s]->lotag=SEC_DOORUPONCETAG;
                   1213:                     EFF_setDoorSpeed(s,50<<4);
                   1214:                     EFF_setDoorLock(s,0);
                   1215:                     j=nextsectorneighborz(s,sectorPtr[s]->ceilingz,-1,-1);
                   1216:                     sectorPtr[s]->ceilingz=sectorPtr[j]->ceilingz;
                   1217:                }
                   1218:                wal->lotag=WAL_NORMAL;
                   1219:                break;
                   1220:           }
                   1221:      }
                   1222:      switch (sectorPtr[s]->lotag) {
                   1223:      case SEC_BLINKOFFTAG:
                   1224:      case SEC_BLINKONTAG:
                   1225:      case SEC_BLINKON1STAG:
                   1226:      case SEC_HIDAMAGEBLINKTAG:
                   1227:      case SEC_OSCILLATETAG:
                   1228:      case SEC_SYNCBLINKONTAG:
                   1229:      case SEC_SYNCBLINKOFFTAG:
                   1230:      case SEC_FLICKERTAG:
                   1231:           EFF_addSectorEffect(s,sectorPtr[s]->lotag);
                   1232:           break;
                   1233:      case SEC_ABOVEWATERTAG:
                   1234:           startwall=sectorPtr[s]->wallptr;
                   1235:           endwall=startwall+sectorPtr[s]->wallnum;
                   1236:           areax1=0L;
                   1237:           areay1=0L;
                   1238:           for (j=startwall ; j < endwall ; j++) {
                   1239:                areax1+=wallPtr[wallPtr[j]->point2]->x-wallPtr[j]->x;
                   1240:                areay1+=wallPtr[wallPtr[j]->point2]->y-wallPtr[j]->y;
                   1241:           }
                   1242:           belowWaterIndex[s]=-1;
                   1243:           for (j=0 ; j < numsectors && belowWaterIndex[s] == -1 ; j++) {
                   1244:                switch (sectorPtr[j]->lotag) {
                   1245:                case SEC_BELOWWATERTAG:
                   1246:                     endwall=sectorPtr[j]->wallnum;
                   1247:                     if (endwall != sectorPtr[s]->wallnum) {
                   1248:                          break;
                   1249:                     }
                   1250:                     startwall=sectorPtr[j]->wallptr;
                   1251:                     endwall+=startwall;
                   1252:                     areax2=0L;
                   1253:                     areay2=0L;
                   1254:                     for (i=startwall ; i < endwall ; i++) {
                   1255:                          areax2+=wallPtr[wallPtr[i]->point2]->x-wallPtr[i]->x;
                   1256:                          areay2+=wallPtr[wallPtr[i]->point2]->y-wallPtr[i]->y;
                   1257:                     }
                   1258:                     if (areax1 == areax2 && areay1 == areay2) {
                   1259:                          belowWaterIndex[s]=j;
                   1260:                          belowWaterIndex[j]=s;
                   1261:                     }
                   1262:                     break;
                   1263:                }
                   1264:           }
                   1265:           break;
                   1266:      }
                   1267: }
                   1268: 
                   1269: short
                   1270: EFF_getNextDoorIndex(void)
                   1271: {
                   1272:      short i;
                   1273: 
                   1274:      if (numDoors >= MAXDOORS) {
                   1275:           crash("EFF_getNextDoorIndex: Too many doors (max=%d)",MAXDOORS);
                   1276:      }
                   1277:      i=numDoors++;
                   1278:      return(i);
                   1279: }
                   1280: 
                   1281: //**
                   1282: //** Moving sector code
                   1283: //**
                   1284: 
                   1285: int
                   1286: EFF_isMovingSectorMarker(short s)
                   1287: {
                   1288:      if (spritePtr[s]->statnum == STAT_MOVINGSECTORMARKER) {
                   1289:           return(1);
                   1290:      }
                   1291:      return(0);
                   1292: }
                   1293: 
                   1294: int
                   1295: EFF_isAutoMovingSector(short s)
                   1296: {
                   1297:      switch (sectorPtr[s]->lotag) {
                   1298:      case SEC_AUTOMOVINGSECTORTAG:
                   1299:      case SEC_AUTOMOVINGSECTORFIXEDTAG:
                   1300:           return(1);
                   1301:      }
                   1302:      return(0);
                   1303: }
                   1304: 
                   1305: int
                   1306: EFF_isMovingSector(short s)
                   1307: {
                   1308:      switch (sectorPtr[s]->lotag) {
                   1309:      case SEC_MOVINGSECTORTAG:
                   1310:      case SEC_AUTOMOVINGSECTORTAG:
                   1311:      case SEC_MOVINGSECTORFIXEDTAG:
                   1312:      case SEC_AUTOMOVINGSECTORFIXEDTAG:
                   1313:           return(1);
                   1314:      }
                   1315:      return(0);
                   1316: }
                   1317: 
                   1318: short
                   1319: EFF_getNextMovingSectorIndex(void)
                   1320: {
                   1321:      short i;
                   1322: 
                   1323:      if (numMovingSectors >= MAXMOVINGSECTORS) {
                   1324:           crash("EFF_getNextMovingSectorIndex: Too many moving sectors "
                   1325:                 "(max=%d)",MAXMOVINGSECTORS);
                   1326:      }
                   1327:      i=numMovingSectors++;
                   1328:      return(i);
                   1329: }
                   1330: 
                   1331: int
                   1332: EFF_insideSector(long x,long y,short sectnum)
                   1333: {
                   1334:      short endwall,startwall,w;
                   1335:      long lox,loy,hix,hiy;
                   1336: 
                   1337:      lox=0x7FFFFFFFL;
                   1338:      loy=0x7FFFFFFFL;
                   1339:      hix=0x80000000L;
                   1340:      hiy=0x80000000L;
                   1341:      startwall=sectorPtr[sectnum]->wallptr;
                   1342:      endwall=startwall+sectorPtr[sectnum]->wallnum;
                   1343:      for (w=startwall ; w < endwall ; w++) {
                   1344:           if (wallPtr[w]->x < lox) {
                   1345:                lox=wallPtr[w]->x;
                   1346:           }
                   1347:           if (wallPtr[w]->x > hix) {
                   1348:                hix=wallPtr[w]->x;
                   1349:           }
                   1350:           if (wallPtr[w]->y < loy) {
                   1351:                loy=wallPtr[w]->y;
                   1352:           }
                   1353:           if (wallPtr[w]->y > hiy) {
                   1354:                hiy=wallPtr[w]->y;
                   1355:           }
                   1356:      }
                   1357:      if (x >= lox && x <= hix && y >= loy && y <= hiy) {
                   1358:           return(1);
                   1359:      }
                   1360:      return(0);
                   1361: }
                   1362: 
                   1363: void
                   1364: EFF_addMovingSector(short sectnum)
                   1365: {
                   1366:      short endwall,i,s,skip,startwall,w;
                   1367:      long deltax,deltay;
                   1368:      struct movingSectorData *mptr;
                   1369:      sectortype *sect;
                   1370:      walltype *wal;
                   1371: 
                   1372:      sect=sectorPtr[sectnum];
                   1373:      i=EFF_getNextMovingSectorIndex();
                   1374:      movingSectorIndex[sectnum]=i;
                   1375:      mptr=movingSectorPtr[i];
                   1376:      mptr->active=0;
                   1377:      mptr->numSectors=0;
                   1378:      mptr->pivotSprite=-1;
                   1379:      mptr->targetSprite=-1;
                   1380:      mptr->sectnum=sectnum;
                   1381:      mptr->delay=0;
                   1382:      mptr->maxSpeed=EFF_getDoorSpeed(sectnum);
                   1383:      if (mptr->maxSpeed <= 0) {
                   1384:           crash("EFF_addMovingSector: Speed is 0 (hitag=%d)",sect->hitag);
                   1385:      }
                   1386:      for (s=0 ; s < numsectors ; s++) {
                   1387:           startwall=sectorPtr[s]->wallptr;
                   1388:           endwall=startwall+sectorPtr[s]->wallnum;
                   1389:           skip=0;
                   1390:           for (w=startwall ; w < endwall ; w++) {
                   1391:                wal=wallPtr[w];
                   1392:                if (EFF_insideSector(wal->x,wal->y,sectnum) == 0) {
                   1393:                     skip=1;
                   1394:                     break;
                   1395:                }
                   1396:           }
                   1397:           if (!skip) {
                   1398:                if (mptr->numSectors >= MAXMOVINGSECTORSECTORS) {
                   1399:                     crash("EFF_addMovingSector: More than %d sectors (hitag=%d)",
                   1400:                           MAXMOVINGSECTORSECTORS,sect->hitag);
                   1401:                }
                   1402:                mptr->sector[mptr->numSectors++]=s;
                   1403:                if (EFF_operatableSector(s)) {
                   1404:                     doorPtr[doorIndex[s]]->movingSectorFlag=1;
                   1405:                }
                   1406:                if (mptr->pivotSprite >= 0) {
                   1407:                     continue;
                   1408:                }
                   1409:                for (i=headspritesect[s] ; i >= 0 ; i=nextspritesect[i]) {
                   1410:                     if (spritePtr[i]->lotag == SPR_MOVINGSECTORTAG) {
                   1411:                          spritePtr[i]->cstat&=(SPRC_BLOCKING|SPRC_BLOCKINGH);
                   1412:                          spritePtr[i]->cstat|=SPRC_INVISIBLE;
                   1413:                          changespritestat(i,STAT_LASTSTAT);
                   1414:                          mptr->pivotSprite=i;
                   1415:                          break;
                   1416:                     }
                   1417:                }
                   1418:           }
                   1419:      }
                   1420:      if (mptr->pivotSprite == -1) {
                   1421:           crash("EFF_addMovingSector: Pivot sprite missing (hitag=%d)",
                   1422:                 sect->hitag);
                   1423:      }
                   1424:      for (s=0,i=0 ; s < mptr->numSectors ; s++) {
                   1425:           startwall=sectorPtr[mptr->sector[s]]->wallptr;
                   1426:           endwall=startwall+sectorPtr[mptr->sector[s]]->wallnum;
                   1427:           for (w=startwall ; w < endwall ; w++) {
                   1428:                if (i >= MAXMOVINGSECTORPOINTS) {
                   1429:                     crash("EFF_addMovingSector: More than %d points for "
                   1430:                           "moving sector (hitag=%d)",
                   1431:                           MAXMOVINGSECTORPOINTS,sect->hitag);
                   1432:                }
                   1433:                deltax=spritePtr[mptr->pivotSprite]->x-wallPtr[w]->x;
                   1434:                mptr->pointDeltaX[i]=deltax;
                   1435:                deltay=spritePtr[mptr->pivotSprite]->y-wallPtr[w]->y;
                   1436:                mptr->pointDeltaY[i]=deltay;
                   1437:                i++;
                   1438:           }
                   1439:      }
                   1440:      if (EFF_isAutoMovingSector(sectnum)) {
                   1441:           mptr->active=1;
                   1442:           mptr->goalSpeed=mptr->maxSpeed;
                   1443:      }
                   1444: }
                   1445: 
                   1446: void
                   1447: EFF_addMovingDoor(short d,struct doorData *dptr)
                   1448: {
                   1449:      short i;
                   1450: 
                   1451:      if (dptr->movingDoorIndex != -1) {
                   1452:           return;
                   1453:      }     
                   1454:      if (numMovingDoors < MAXMOVINGDOORS) {
                   1455:           dptr->movingDoorIndex=numMovingDoors;
                   1456:           movingDoor[numMovingDoors]=d;
                   1457:           numMovingDoors++;
                   1458:      }
                   1459: }
                   1460: 
                   1461: void
                   1462: EFF_removeMovingDoor(short d,struct doorData *dptr)
                   1463: {
                   1464:      short i,n;
                   1465:      
                   1466:      if (numMovingDoors > 0) {
                   1467:           numMovingDoors--;
                   1468:           i=dptr->movingDoorIndex;
                   1469:           if (i < numMovingDoors) {
                   1470:                n=movingDoor[numMovingDoors];
                   1471:                movingDoor[i]=n;
                   1472:                doorPtr[n]->movingDoorIndex=i;
                   1473:           }
                   1474:      }
                   1475:      dptr->movingDoorIndex=-1;
                   1476: }
                   1477: 
                   1478: void
                   1479: EFF_scanMap(void)
                   1480: {
                   1481:      short i,j,n,s,w;
                   1482:      short endwall,startwall;
                   1483:      long x,y;
                   1484: 
                   1485:      memset(&numDoors,0,sizeof(numDoors));
                   1486:      memset(&numMovingSectors,0,sizeof(numMovingSectors));
                   1487:      memset(&numMovingDoors,0,sizeof(numMovingDoors));
                   1488:      memset(movingSectorIndex,-1,sizeof(movingSectorIndex));
                   1489:      memset(lightWallIndex,-1,sizeof(lightWallIndex));
                   1490:      memset(sectorEffectIndex,-1,sizeof(sectorEffectIndex));
                   1491:      memset(goreSprite,-1,sizeof(goreSprite));
                   1492:      memset(spriteSwitchStatus,0,sizeof(spriteSwitchStatus));
                   1493:      memset(wallSwitchStatus,0,sizeof(wallSwitchStatus));
                   1494:      for (i=0 ; i < MAXDOORS ; i++) {
                   1495:           doorPtr[i]->movingSectorFlag=0;
                   1496:           doorPtr[i]->sectorIndex=-1;
                   1497:           doorPtr[i]->movingDoorIndex=-1;
                   1498:           for (j=0 ; j < MAXSECTORPOINTS ; j++) {
                   1499:                doorPtr[i]->wallIndex[j]=-1;
                   1500:                doorPtr[i]->wallx[j]=-1;
                   1501:                doorPtr[i]->wally[j]=-1;
                   1502:           }
                   1503:      }
                   1504:      for (i=0 ; i < numsectors ; i++) {
                   1505:           ENG_checksumSector(i);
                   1506:           EFF_scanSectorEffects(i);
                   1507:           switch (sectorPtr[i]->lotag) {
                   1508:           case SEC_DOORUPTAG:
                   1509:           case SEC_DOORUPONCETAG:
                   1510:           case SEC_DOORDOWNTAG:
                   1511:           case SEC_DOORDOWNONCETAG:
                   1512:                n=EFF_getNextDoorIndex();
                   1513:                doorIndex[i]=n;
                   1514:                doorPtr[n]->sectorIndex=i;
                   1515:                doorPtr[n]->hiz=sectorPtr[i]->ceilingz;
                   1516:                doorPtr[n]->loz=sectorPtr[i]->floorz;
                   1517:                doorPtr[n]->speed=EFF_getDoorSpeed(i)<<4;
                   1518:                if (doorPtr[n]->speed <= 0) {
                   1519:                     doorPtr[n]->speed=DEFAULTDOORSPEED;
                   1520:                }
                   1521:                switch (sectorPtr[i]->lotag) {
                   1522:                case SEC_DOORUPTAG:
                   1523:                case SEC_DOORUPONCETAG:
                   1524:                     sectorPtr[i]->ceilingz=sectorPtr[i]->floorz;
                   1525:                     break;
                   1526:                case SEC_DOORDOWNTAG:
                   1527:                case SEC_DOORDOWNONCETAG:
                   1528:                     sectorPtr[i]->floorz=sectorPtr[i]->ceilingz;
                   1529:                     break;
                   1530:                }
                   1531:                EFF_blockDoorWalls(i);
                   1532:                break;
                   1533:           case SEC_PLATFORMDOWNTAG:
                   1534:           case SEC_PLATFORMELEVATORTAG:
                   1535:                n=EFF_getNextDoorIndex();
                   1536:                doorIndex[i]=n;
                   1537:                doorPtr[n]->sectorIndex=i;
                   1538:                doorPtr[n]->hiz=sectorPtr[i]->floorz;
                   1539:                s=nextsectorneighborz(i,sectorPtr[i]->floorz,1,1);
                   1540:                if (s == -1) {
                   1541:                     s=nextsectorneighborz(i,sectorPtr[i]->floorz,1,-1);
                   1542:                     if (s == -1) {
                   1543:                          crash("EFF_scanMap: No adjacent floor for "
                   1544:                                "elevator (sector=%d)",i);
                   1545:                     }
                   1546:                }
                   1547:                doorPtr[n]->loz=sectorPtr[s]->floorz;
                   1548:                doorPtr[n]->speed=EFF_getDoorSpeed(i)<<4;
                   1549:                doorPtr[n]->height=sectorPtr[i]->floorz-sectorPtr[i]->ceilingz;
                   1550:                if (doorPtr[n]->speed <= 0) {
                   1551:                     doorPtr[n]->speed=DEFAULTDOORSPEED;
                   1552:                }
                   1553:                EFF_blockDoorWalls(i);
                   1554:                break;
                   1555:           case SEC_PLATFORMUPTAG:
                   1556:                n=EFF_getNextDoorIndex();
                   1557:                doorIndex[i]=n;
                   1558:                doorPtr[n]->sectorIndex=i;
                   1559:                doorPtr[n]->loz=sectorPtr[i]->floorz;
                   1560:                s=nextsectorneighborz(i,sectorPtr[i]->floorz,1,-1);
                   1561:                if (s == -1) {
                   1562:                     s=nextsectorneighborz(i,sectorPtr[i]->floorz,1,1);
                   1563:                     if (s == -1) {
                   1564:                          crash("EFF_scanMap: No adjacent floor for platform "
                   1565:                                "(sector=%d)",i);
                   1566:                     }
                   1567:                }
                   1568:                doorPtr[n]->hiz=sectorPtr[s]->floorz;
                   1569:                doorPtr[n]->speed=EFF_getDoorSpeed(i)<<4;
                   1570:                doorPtr[n]->height=sectorPtr[i]->floorz-sectorPtr[i]->ceilingz;
                   1571:                if (doorPtr[n]->speed <= 0) {
                   1572:                     doorPtr[n]->speed=DEFAULTDOORSPEED;
                   1573:                }
                   1574:                EFF_blockDoorWalls(i);
                   1575:                break;
                   1576:           case SEC_DOORHSPLITTAG:
                   1577:           case SEC_DOORHSPLITONCETAG:
                   1578:                n=EFF_getNextDoorIndex();
                   1579:                doorIndex[i]=n;
                   1580:                doorPtr[n]->sectorIndex=i;
                   1581:                doorPtr[n]->hiz=sectorPtr[i]->ceilingz;
                   1582:                doorPtr[n]->loz=sectorPtr[i]->floorz;
                   1583:                doorPtr[n]->speed=EFF_getDoorSpeed(i)<<4;
                   1584:                if (doorPtr[n]->speed <= 0) {
                   1585:                     doorPtr[n]->speed=DEFAULTDOORSPEED;
                   1586:                }
                   1587:                sectorPtr[i]->ceilingz=sectorCenterPtr[i]->centerz;
                   1588:                sectorPtr[i]->floorz=sectorCenterPtr[i]->centerz;
                   1589:                EFF_blockDoorWalls(i);
                   1590:                break;
                   1591:           case SEC_DOORSLIDECENTERTAG:
                   1592:                n=EFF_getNextDoorIndex();
                   1593:                doorIndex[i]=n;
                   1594:                doorPtr[n]->sectorIndex=i;
                   1595:                doorPtr[n]->speed=EFF_getDoorSpeed(i);
                   1596:                if (doorPtr[n]->speed <= 0) {
                   1597:                     doorPtr[n]->speed=DEFAULTDOORSPEED;
                   1598:                }
                   1599:                startwall=sectorPtr[i]->wallptr;
                   1600:                endwall=startwall+sectorPtr[i]->wallnum;
                   1601:                for (w=startwall ; w < endwall ; w++) {
                   1602:                     if (wallPtr[w]->lotag == WAL_DOORSEARCHTAG) {
                   1603:                          if (doorPtr[n]->wallIndex[0] == -1) {
                   1604:                               for (j=0 ; j < 6 ; j++) {
                   1605:                                    x=wallPtr[(w-2)+j]->x;
                   1606:                                    y=wallPtr[(w-2)+j]->y;
                   1607:                                    doorPtr[n]->wallx[j]=x;
                   1608:                                    doorPtr[n]->wally[j]=y;
                   1609:                                    doorPtr[n]->wallIndex[j]=(w-2)+j;
                   1610:                               }
                   1611:                          }
                   1612:                          else {
                   1613:                               for (j=0 ; j < 6 ; j++) {
                   1614:                                    x=wallPtr[(w-2)+j]->x;
                   1615:                                    y=wallPtr[(w-2)+j]->y;
                   1616:                                    doorPtr[n]->wallx[j+6]=x;
                   1617:                                    doorPtr[n]->wally[j+6]=y;
                   1618:                                    doorPtr[n]->wallIndex[j+6]=(w-2)+j;
                   1619:                               }
                   1620:                          }
                   1621:                     }
                   1622:                }
                   1623:                break;
                   1624:           case SEC_ROTATESECTORTAG:
                   1625:           case SEC_BONUSSECTORTAG:
                   1626:                n=EFF_getNextDoorIndex();
                   1627:                doorIndex[i]=n;
                   1628:                doorPtr[n]->sectorIndex=i;
                   1629:                doorPtr[n]->speed=EFF_getDoorSpeed(i);
                   1630:                startwall=sectorPtr[i]->wallptr;
                   1631:                endwall=startwall+sectorPtr[i]->wallnum;
                   1632:                for (w=startwall,j=0 ; w < endwall ; j++,w++) {
                   1633:                     if (j >= MAXSECTORPOINTS) {
                   1634:                          crash("EFF_scanMap: Too many points for rotating"
                   1635:                                " sector (max=%d)",MAXSECTORPOINTS);
                   1636:                     }
                   1637:                     doorPtr[n]->wallIndex[j]=w;
                   1638:                     doorPtr[n]->wallx[j]=wallPtr[w]->x;
                   1639:                     doorPtr[n]->wally[j]=wallPtr[w]->y;
                   1640:                }
                   1641:                doorPtr[n]->state=DOORSTATE_OPEN;
                   1642:                EFF_addMovingDoor(n,doorPtr[n]);
                   1643:                break;
                   1644:           }
                   1645:           if (EFF_operatableSector(i)) {
                   1646:                if (EFF_getDoorLock(i) < 0) {
                   1647:                     EFF_setDoorLock(i,0);
                   1648:                }
                   1649:           }
                   1650:      }
                   1651: //** this must be after the door setup code
                   1652:      for (i=0 ; i < numsectors ; i++) {
                   1653:           switch (sectorPtr[i]->lotag) {
                   1654:           case SEC_MOVINGSECTORTAG:
                   1655:           case SEC_AUTOMOVINGSECTORTAG:
                   1656:           case SEC_MOVINGSECTORFIXEDTAG:
                   1657:           case SEC_AUTOMOVINGSECTORFIXEDTAG:
                   1658:                EFF_addMovingSector(i);
                   1659:                break;
                   1660:           }
                   1661:      }
                   1662:      for (i=0 ; i < MAXSPRITES ; i++) {
                   1663:           EFF_scanSprite(i);
                   1664:      }
                   1665: }
                   1666: 
                   1667: //**
                   1668: //** Door & elevator code
                   1669: //**
                   1670: 
                   1671: int
                   1672: EFF_isDoorClosed(short s)
                   1673: {
                   1674:      short d;
                   1675: 
                   1676:      if ((d=doorIndex[s]) == -1) {
                   1677:           return(0);
                   1678:      }
                   1679:      switch (doorPtr[d]->state) {
                   1680:      case DOORSTATE_IDLE:
                   1681:      case DOORSTATE_CLOSE:
                   1682:      case DOORSTATE_CLOSED:
                   1683:           return(1);
                   1684:      }
                   1685:      return(0);
                   1686: }
                   1687: 
                   1688: int
                   1689: EFF_isDoorOpened(short s)
                   1690: {
                   1691:      short d;
                   1692: 
                   1693:      if ((d=doorIndex[s]) == -1) {
                   1694:           return(0);
                   1695:      }
                   1696:      switch (doorPtr[d]->state) {
                   1697:      case DOORSTATE_OPENED:
                   1698:      case DOORSTATE_WAITING:
                   1699:           return(1);
                   1700:      }
                   1701:      return(0);
                   1702: }
                   1703: 
                   1704: int
                   1705: EFF_moveSectorCeiling(short s,sectortype *sect,long delta,long goalz)
                   1706: {
                   1707:      int  retval=0;
                   1708:      long z;
                   1709:      
                   1710:      if (delta != 0L) {
                   1711:           z=sect->ceilingz;
                   1712:           if (z < goalz) {
                   1713:                z+=delta;
                   1714:                if (z >= goalz) {
                   1715:                     z=goalz;
                   1716:                     retval=1;
                   1717:                }
                   1718:           }
                   1719:           else {
                   1720:                z-=delta;
                   1721:                if (z <= goalz) {
                   1722:                     z=goalz;
                   1723:                     retval=1;
                   1724:                }
                   1725:           }
                   1726:           sect->ceilingz=z;
                   1727:           return(retval);
                   1728:      }
                   1729:      return(0);
                   1730: }
                   1731: 
                   1732: int
                   1733: EFF_moveSectorFloor(short s,sectortype *sect,long delta,long goalz)
                   1734: {
                   1735:      int  retval=0;
                   1736:      long z;
                   1737:      
                   1738:      if (delta != 0L) {
                   1739:           z=sect->floorz;
                   1740:           if (z < goalz) {
                   1741:                z+=delta;
                   1742:                if (z >= goalz) {
                   1743:                     z=goalz;
                   1744:                     retval=1;
                   1745:                }
                   1746:           }
                   1747:           else {
                   1748:                z-=delta;
                   1749:                if (z <= goalz) {
                   1750:                     z=goalz;
                   1751:                     retval=1;
                   1752:                }
                   1753:           }
                   1754:           sect->floorz=z;
                   1755:           return(retval);
                   1756:      }
                   1757:      return(0);
                   1758: }
                   1759: 
                   1760: int
                   1761: EFF_slideDoorOpen(short d)
                   1762: {
                   1763:      short i,retval=0,w[12];
                   1764:      long delta,dx,sx[12],sy[12],x[12],y[12];
                   1765:      struct doorData *dptr;
                   1766: 
                   1767:      dptr=doorPtr[d];
                   1768:      delta=dptr->speed;
                   1769:      for (i=0 ; i < 12 ; i++) {
                   1770:           w[i]=dptr->wallIndex[i];
                   1771:           x[i]=wallPtr[w[i]]->x;
                   1772:           y[i]=wallPtr[w[i]]->y;
                   1773:           sx[i]=dptr->wallx[i];
                   1774:           sy[i]=dptr->wally[i];
                   1775:      }
                   1776:      if (sy[1] == sy[0]) {
                   1777:           dx=x[0];
                   1778:           if (x[1] > dx) {
                   1779:                x[1]=kmax(x[1]-delta,dx);
                   1780:           }
                   1781:           else if (x[1] < dx) {
                   1782:                x[1]=kmin(x[1]+delta,dx);
                   1783:           }
                   1784:           x[2]=x[1]+(sx[2]-sx[1]);
                   1785:           if (x[1] == dx) {
                   1786:                retval|=1;
                   1787:           }
                   1788:           dx=x[5];
                   1789:           if (x[4] > dx) {
                   1790:                x[4]=kmax(x[4]-delta,dx);
                   1791:           }
                   1792:           else if (x[4] < dx) {
                   1793:                x[4]=kmin(x[4]+delta,dx);
                   1794:           }
                   1795:           x[3]=x[4]+(sx[3]-sx[4]);
                   1796:           if (x[4] == dx) {
                   1797:                retval|=2;
                   1798:           }
                   1799:           dx=x[6];
                   1800:           if (x[7] > dx) {
                   1801:                x[7]=kmax(x[7]-delta,dx);
                   1802:           }
                   1803:           else if (x[7] < dx) {
                   1804:                x[7]=kmin(x[7]+delta,dx);
                   1805:           }
                   1806:           x[8]=x[7]+(sx[8]-sx[7]);
                   1807:           if (x[7] == dx) {
                   1808:                retval|=4;
                   1809:           }
                   1810:           dx=x[11];
                   1811:           if (x[10] > dx) {
                   1812:                x[10]=kmax(x[10]-delta,dx);
                   1813:           }
                   1814:           else if (x[10] < dx) {
                   1815:                x[10]=kmin(x[10]+delta,dx);
                   1816:           }
                   1817:           x[9]=x[10]+(sx[9]-sx[10]);
                   1818:           if (x[10] == dx) {
                   1819:                retval|=8;
                   1820:           }
                   1821:      }
                   1822:      else {
                   1823:           dx=y[0];
                   1824:           if (y[1] > dx) {
                   1825:                y[1]=kmax(y[1]-delta,dx);
                   1826:           }
                   1827:           else if (y[1] < dx) {
                   1828:                y[1]=kmin(y[1]+delta,dx);
                   1829:           }
                   1830:           y[2]=y[1]+(sy[2]-sy[1]);
                   1831:           if (y[1] == dx) {
                   1832:                retval|=1;
                   1833:           }
                   1834:           dx=y[5];
                   1835:           if (y[4] > dx) {
                   1836:                y[4]=kmax(y[4]-delta,dx);
                   1837:           }
                   1838:           else if (y[4] < dx) {
                   1839:                y[4]=kmin(y[4]+delta,dx);
                   1840:           }
                   1841:           y[3]=y[4]+(sy[3]-sy[4]);
                   1842:           if (y[4] == dx) {
                   1843:                retval|=2;
                   1844:           }
                   1845:           dx=y[6];
                   1846:           if (y[7] > dx) {
                   1847:                y[7]=kmax(y[7]-delta,dx);
                   1848:           }
                   1849:           else if (y[7] < dx) {
                   1850:                y[7]=kmin(y[7]+delta,dx);
                   1851:           }
                   1852:           y[8]=y[7]+(sy[8]-sy[7]);
                   1853:           if (y[7] == dx) {
                   1854:                retval|=4;
                   1855:           }
                   1856:           dx=y[11];
                   1857:           if (y[10] > dx) {
                   1858:                y[10]=kmax(y[10]-delta,dx);
                   1859:           }
                   1860:           else if (y[10] < dx) {
                   1861:                y[10]=kmin(y[10]+delta,dx);
                   1862:           }
                   1863:           y[9]=y[10]+(sy[9]-sy[10]);
                   1864:           if (y[10] == dx) {
                   1865:                retval|=8;
                   1866:           }
                   1867:      }
                   1868:      dragpoint(w[1],x[1],y[1]);
                   1869:      dragpoint(w[2],x[2],y[2]);
                   1870:      dragpoint(w[3],x[3],y[3]);
                   1871:      dragpoint(w[4],x[4],y[4]);
                   1872:      dragpoint(w[7],x[7],y[7]);
                   1873:      dragpoint(w[8],x[8],y[8]);
                   1874:      dragpoint(w[9],x[9],y[9]);
                   1875:      dragpoint(w[10],x[10],y[10]);
                   1876:      if (retval == (1|2|4|8)) {
                   1877:           return(1);
                   1878:      }
                   1879:      return(0);
                   1880: }
                   1881: 
                   1882: int
                   1883: EFF_slideDoorClose(short d)
                   1884: {
                   1885:      short i,retval=0,w[12];
                   1886:      long delta,dx,sx[12],sy[12],x[12],y[12];
                   1887:      struct doorData *dptr;
                   1888: 
                   1889:      dptr=doorPtr[d];
                   1890:      delta=dptr->speed;
                   1891:      for (i=0 ; i < 12 ; i++) {
                   1892:           w[i]=dptr->wallIndex[i];
                   1893:           x[i]=wallPtr[w[i]]->x;
                   1894:           y[i]=wallPtr[w[i]]->y;
                   1895:           sx[i]=dptr->wallx[i];
                   1896:           sy[i]=dptr->wally[i];
                   1897:      }
                   1898:      if (sy[1] == sy[0]) {
                   1899:           dx=sx[1];
                   1900:           if (x[1] > dx) {
                   1901:                x[1]=kmax(x[1]-delta,dx);
                   1902:           }
                   1903:           else if (x[1] < dx) {
                   1904:                x[1]=kmin(x[1]+delta,dx);
                   1905:           }
                   1906:           x[2]=x[1]+(sx[2]-sx[1]);
                   1907:           if (x[1] == dx) {
                   1908:                retval|=1;
                   1909:           }
                   1910:           dx=sx[4];
                   1911:           if (x[4] > dx) {
                   1912:                x[4]=kmax(x[4]-delta,dx);
                   1913:           }
                   1914:           else if (x[4] < dx) {
                   1915:                x[4]=kmin(x[4]+delta,dx);
                   1916:           }
                   1917:           x[3]=x[4]+(sx[3]-sx[4]);
                   1918:           if (x[4] == dx) {
                   1919:                retval|=2;
                   1920:           }
                   1921:           dx=sx[7];
                   1922:           if (x[7] > dx) {
                   1923:                x[7]=kmax(x[7]-delta,dx);
                   1924:           }
                   1925:           else if (x[7] < dx) {
                   1926:                x[7]=kmin(x[7]+delta,dx);
                   1927:           }
                   1928:           x[8]=x[7]+(sx[8]-sx[7]);
                   1929:           if (x[7] == dx) {
                   1930:                retval|=4;
                   1931:           }
                   1932:           dx=sx[10];
                   1933:           if (x[10] > dx) {
                   1934:                x[10]=kmax(x[10]-delta,dx);
                   1935:           }
                   1936:           else if (x[10] < dx) {
                   1937:                x[10]=kmin(x[10]-delta,dx);
                   1938:           }
                   1939:           x[9]=x[10]+(sx[9]-sx[10]);
                   1940:           if (x[10] == dx) {
                   1941:                retval|=8;
                   1942:           }
                   1943:      }
                   1944:      else {
                   1945:           dx=sy[1];
                   1946:           if (y[1] > dx) {
                   1947:                y[1]=kmax(y[1]-delta,dx);
                   1948:           }
                   1949:           else if (y[1] < dx) {
                   1950:                y[1]=kmin(y[1]+delta,dx);
                   1951:           }
                   1952:           y[2]=y[1]+(sy[2]-sy[1]);
                   1953:           if (y[1] == dx) {
                   1954:                retval|=1;
                   1955:           }
                   1956:           dx=sy[4];
                   1957:           if (y[4] > dx) {
                   1958:                y[4]=kmax(y[4]-delta,dx);
                   1959:           }
                   1960:           else if (y[4] < dx) {
                   1961:                y[4]=kmin(y[4]+delta,dx);
                   1962:           }
                   1963:           y[3]=y[4]+(sy[3]-sy[4]);
                   1964:           if (y[4] == dx) {
                   1965:                retval|=2;
                   1966:           }
                   1967:           dx=sy[7];
                   1968:           if (y[7] > dx) {
                   1969:                y[7]=kmax(y[7]-delta,dx);
                   1970:           }
                   1971:           else if (y[7] < dx) {
                   1972:                y[7]=kmin(y[7]+delta,dx);
                   1973:           }
                   1974:           y[8]=y[7]+(sy[8]-sy[7]);
                   1975:           if (y[7] == dx) {
                   1976:                retval|=4;
                   1977:           }
                   1978:           dx=sy[10];
                   1979:           if (y[10] > dx) {
                   1980:                y[10]=kmax(y[10]-delta,dx);
                   1981:           }
                   1982:           else if (y[10] < dx) {
                   1983:                y[10]=kmin(y[10]+delta,dx);
                   1984:           }
                   1985:           y[9]=y[10]+(sy[9]-sy[10]);
                   1986:           if (y[10] == dx) {
                   1987:                retval|=8;
                   1988:           }
                   1989:      }
                   1990:      dragpoint(w[1],x[1],y[1]);
                   1991:      dragpoint(w[2],x[2],y[2]);
                   1992:      dragpoint(w[3],x[3],y[3]);
                   1993:      dragpoint(w[4],x[4],y[4]);
                   1994:      dragpoint(w[7],x[7],y[7]);
                   1995:      dragpoint(w[8],x[8],y[8]);
                   1996:      dragpoint(w[9],x[9],y[9]);
                   1997:      dragpoint(w[10],x[10],y[10]);
                   1998:      if (retval == (1|2|4|8)) {
                   1999:           return(1);
                   2000:      }
                   2001:      return(0);
                   2002: }
                   2003: 
                   2004: int
                   2005: EFF_liveActorInSector(short s)
                   2006: {
                   2007:      short i,j;
                   2008:      
                   2009:      i=headspritesect[s];
                   2010:      while (i != -1) {   // check for living objects in door sector
                   2011:           j=nextspritesect[i];
                   2012:           if (ACT_getHealth(i) > 0) {
                   2013:                return(1);
                   2014:           }
                   2015:           i=j;
                   2016:      }
                   2017:      return(0);
                   2018: }
                   2019: 
                   2020: void
                   2021: EFF_moveDoor(short d,struct doorData *dptr)
                   2022: {
                   2023:      int  i,j,rotang,s;
                   2024:      long beforez,goalz,deltaz,newx,newy,speed;
                   2025:      sectortype *sect;
                   2026:      spritetype *spr;
                   2027: 
                   2028:      s=dptr->sectorIndex;
                   2029:      sect=sectorPtr[s];
                   2030:      speed=dptr->speed*TICWAITPERFRAME;
                   2031:      switch (sect->lotag) {
                   2032:      case SEC_DOORUPTAG:
                   2033:      case SEC_DOORUPONCETAG:
                   2034:           switch (dptr->state) {
                   2035:           case DOORSTATE_OPEN:
                   2036:                if (EFF_moveSectorCeiling(s,sect,speed,dptr->hiz)) {
                   2037:                     dptr->state=DOORSTATE_OPENED;
                   2038:                }
                   2039:                break;
                   2040:           case DOORSTATE_CLOSE:
                   2041:                if (EFF_moveSectorCeiling(s,sect,speed,dptr->loz)) {
                   2042:                     dptr->state=DOORSTATE_CLOSED;
                   2043:                }
                   2044:                break;
                   2045:           }
                   2046:           break;
                   2047:      case SEC_DOORDOWNTAG:
                   2048:      case SEC_DOORDOWNONCETAG:
                   2049:      case SEC_PLATFORMDOWNTAG:
                   2050:      case SEC_PLATFORMELEVATORTAG:
                   2051:           switch (dptr->state) {
                   2052:           case DOORSTATE_OPEN:
                   2053:                beforez=sect->floorz;
                   2054:                if (EFF_moveSectorFloor(s,sect,speed,dptr->loz)) {
                   2055:                     dptr->state=DOORSTATE_OPENED;
                   2056:                }
                   2057:                if (EFF_isElevator(s)) {
                   2058:                     deltaz=sect->floorz-beforez;
                   2059:                     for (i=headspritesect[s] ; i >= 0 ; i=j) {
                   2060:                          j=nextspritesect[i];
                   2061:                          spr=spritePtr[i];
                   2062:                          if (GAM_isOnGround(i)) {
                   2063:                               spr->z+=deltaz;
                   2064:                               setsprite(i,spr->x,spr->y,spr->z);
                   2065:                          }
                   2066:                     }
                   2067:                     if (sect->lotag == SEC_PLATFORMELEVATORTAG) {
                   2068:                          sect->ceilingz=sect->floorz-dptr->height;
                   2069:                     }
                   2070:                }
                   2071:                break;
                   2072:           case DOORSTATE_CLOSE:
                   2073:                beforez=sect->floorz;
                   2074:                if (EFF_moveSectorFloor(s,sect,speed,dptr->hiz)) {
                   2075:                     dptr->state=DOORSTATE_CLOSED;
                   2076:                }
                   2077:                if (EFF_isElevator(s)) {
                   2078:                     deltaz=sect->floorz-beforez;
                   2079:                     for (i=headspritesect[s] ; i >= 0 ; i=j) {
                   2080:                          j=nextspritesect[i];
                   2081:                          spr=spritePtr[i];
                   2082:                          if (GAM_isOnGround(i)) {
                   2083:                               spr->z+=deltaz;
                   2084:                               setsprite(i,spr->x,spr->y,spr->z);
                   2085:                          }
                   2086:                     }
                   2087:                     if (sect->lotag == SEC_PLATFORMELEVATORTAG) {
                   2088:                          sect->ceilingz=sect->floorz-dptr->height;
                   2089:                     }
                   2090:                }
                   2091:                break;
                   2092:           }
                   2093:           break;
                   2094:      case SEC_PLATFORMUPTAG:
                   2095:           switch (dptr->state) {
                   2096:           case DOORSTATE_OPEN:
                   2097:                beforez=sect->floorz;
                   2098:                if (EFF_moveSectorFloor(s,sect,speed,dptr->hiz)) {
                   2099:                     dptr->state=DOORSTATE_OPENED;
                   2100:                }
                   2101:                deltaz=sect->floorz-beforez;
                   2102:                for (i=headspritesect[s] ; i >= 0 ; i=j) {
                   2103:                     j=nextspritesect[i];
                   2104:                     spr=spritePtr[i];
                   2105:                     if (GAM_isOnGround(i)) {
                   2106:                          spr->z+=deltaz;
                   2107:                          setsprite(i,spr->x,spr->y,spr->z);
                   2108:                     }
                   2109:                }
                   2110:                break;
                   2111:           case DOORSTATE_CLOSE:
                   2112:                beforez=sect->floorz;
                   2113:                if (EFF_moveSectorFloor(s,sect,speed,dptr->loz)) {
                   2114:                     dptr->state=DOORSTATE_CLOSED;
                   2115:                }
                   2116:                deltaz=sect->floorz-beforez;
                   2117:                for (i=headspritesect[s] ; i >= 0 ; i=j) {
                   2118:                     j=nextspritesect[i];
                   2119:                     spr=spritePtr[i];
                   2120:                     if (GAM_isOnGround(i)) {
                   2121:                          spr->z+=deltaz;
                   2122:                          setsprite(i,spr->x,spr->y,spr->z);
                   2123:                     }
                   2124:                }
                   2125:                break;
                   2126:           }
                   2127:           break;
                   2128:      case SEC_DOORHSPLITTAG:
                   2129:      case SEC_DOORHSPLITONCETAG:
                   2130:           switch (dptr->state) {
                   2131:           case DOORSTATE_OPEN:
                   2132:                i=0;
                   2133:                if (EFF_moveSectorCeiling(s,sect,speed,dptr->hiz)) {
                   2134:                     i=1;
                   2135:                }
                   2136:                if (EFF_moveSectorFloor(s,sect,speed,dptr->loz)) {
                   2137:                     i|=2;
                   2138:                }
                   2139:                if (i == 3) {
                   2140:                     dptr->state=DOORSTATE_OPENED;
                   2141:                }
                   2142:                break;
                   2143:           case DOORSTATE_CLOSE:
                   2144:                goalz=sectorCenterPtr[s]->centerz;
                   2145:                i=0;
                   2146:                if (EFF_moveSectorCeiling(s,sect,speed,goalz)) {
                   2147:                     i=1;
                   2148:                }
                   2149:                if (EFF_moveSectorFloor(s,sect,speed,goalz)) {
                   2150:                     i|=2;
                   2151:                }
                   2152:                if (i == 3) {
                   2153:                     dptr->state=DOORSTATE_CLOSED;
                   2154:                }
                   2155:                break;
                   2156:           }
                   2157:           break;
                   2158:      case SEC_DOORSLIDECENTERTAG:
                   2159:           switch (dptr->state) {
                   2160:           case DOORSTATE_OPEN:
                   2161:                if (EFF_slideDoorOpen(d)) {
                   2162:                     dptr->state=DOORSTATE_OPENED;
                   2163:                }
                   2164:                break;
                   2165:           case DOORSTATE_CLOSE:
                   2166:                if (EFF_slideDoorClose(d)) {
                   2167:                     dptr->state=DOORSTATE_CLOSED;
                   2168:                }
                   2169:                break;
                   2170:           }
                   2171:           break;
                   2172:      case SEC_ROTATESECTORTAG:
                   2173:      case SEC_BONUSSECTORTAG:
                   2174:           i=0;
                   2175:           rotang=dptr->hiz-dptr->loz;
                   2176:           dptr->loz=dptr->hiz;
                   2177:           while ((j=dptr->wallIndex[i]) >= 0) {
                   2178:                rotatepoint(sectorCenterPtr[s]->centerx,
                   2179:                            sectorCenterPtr[s]->centery,
                   2180:                            dptr->wallx[i],dptr->wally[i],
                   2181:                            dptr->loz,&newx,&newy);
                   2182:                dragpoint(j,newx,newy);
                   2183:                i++;
                   2184:           }
                   2185:           for (i=headspritesect[s] ; i >= 0 ; i=j) {
                   2186:                j=nextspritesect[i];
                   2187:                if (!GAM_isOnGround(i)) {
                   2188:                     continue;
                   2189:                }
                   2190:                if (rotang != 0) {
                   2191:                     spritePtr[i]->ang=(spritePtr[i]->ang+rotang)&2047;
                   2192:                     rotatepoint(sectorCenterPtr[s]->centerx,
                   2193:                                 sectorCenterPtr[s]->centery,
                   2194:                                 spritePtr[i]->x,spritePtr[i]->y,
                   2195:                                 rotang&2047,&newx,&newy);
                   2196:                     setsprite(i,newx,newy,spritePtr[i]->z);
                   2197:                }
                   2198:           }
                   2199:           dptr->hiz=(dptr->hiz+dptr->speed)&2047;
                   2200:           break;
                   2201:      }
                   2202: //** play sounds here
                   2203:      switch (dptr->state) {
                   2204:      case DOORSTATE_OPEN:
                   2205:      case DOORSTATE_CLOSE:
                   2206:           SND_playSectorMovingSound(s,1);
                   2207:           if (EFF_isDoor(s) && EFF_liveActorInSector(s)) {
                   2208:                dptr->state=DOORSTATE_OPEN;
                   2209:           }
                   2210:           break;
                   2211:      case DOORSTATE_OPENED:
                   2212:           switch (sect->lotag) {
                   2213:           case SEC_DOORUPONCETAG:
                   2214:           case SEC_DOORDOWNONCETAG:
                   2215:           case SEC_DOORHSPLITONCETAG:
                   2216:                dptr->state=DOORSTATE_IDLE;
                   2217:                EFF_removeMovingDoor(d,dptr);
                   2218:                break;
                   2219:           default:
                   2220:                dptr->state=DOORSTATE_WAITING;
                   2221:                dptr->delay=TMR_getSecondTics(4);
                   2222:                break;
                   2223:           }
                   2224:           SND_playSectorMovingSound(s,0);
                   2225:           SND_playSectorStopSound(s);
                   2226:           break;
                   2227:      case DOORSTATE_CLOSED:
                   2228:           dptr->state=DOORSTATE_IDLE;
                   2229:           EFF_removeMovingDoor(d,dptr);
                   2230:           EFF_blockDoorWalls(s);
                   2231:           SND_playSectorMovingSound(s,0);
                   2232:           SND_playSectorStopSound(s);
                   2233:           break;
                   2234:      case DOORSTATE_WAITING:
                   2235:           if (dptr->movingSectorFlag == 0) {
                   2236:                dptr->delay-=TICWAITPERFRAME;
                   2237:                if (dptr->delay <= 0) {
                   2238:                     dptr->delay=0;
                   2239:                     if (EFF_isDoor(s) && EFF_liveActorInSector(s)) {
                   2240:                          break;
                   2241:                     }
                   2242:                     dptr->state=DOORSTATE_CLOSE;
                   2243:                     EFF_turnSwitchesOff(sect->hitag);
                   2244:                     SND_playSectorMovingSound(s,0);
                   2245:                     SND_playSectorCloseSound(s);
                   2246:                }
                   2247:           }
                   2248:           break;
                   2249:      }
                   2250: }
                   2251: 
                   2252: void
                   2253: EFF_doMoveDoors(void)
                   2254: {
                   2255:      short d,i,n;
                   2256: 
                   2257:      n=numMovingDoors;
                   2258:      for (i=0 ; i < n ; i++) {
                   2259:           d=movingDoor[i];
                   2260:           if (d >= 0) {
                   2261:                EFF_moveDoor(d,doorPtr[d]);
                   2262:           }
                   2263:      }
                   2264: }
                   2265: 
                   2266: void
                   2267: EFF_openDoor(short s)
                   2268: {
                   2269:      short d;
                   2270:      struct doorData *dptr;
                   2271:      
                   2272:      if ((d=doorIndex[s]) == -1) {
                   2273:           return;
                   2274:      }
                   2275:      dptr=doorPtr[d];
                   2276:      EFF_addMovingDoor(d,dptr);
                   2277:      dptr->state=DOORSTATE_OPEN;
                   2278:      EFF_unblockDoorWalls(s);
                   2279:      SND_playSectorOpenSound(s);
                   2280: }
                   2281: 
                   2282: void
                   2283: EFF_closeDoor(short s)
                   2284: {
                   2285:      short d;
                   2286:      struct doorData *dptr;
                   2287:      
                   2288:      if ((d=doorIndex[s]) == -1) {
                   2289:           return;
                   2290:      }
                   2291:      dptr=doorPtr[d];
                   2292:      EFF_addMovingDoor(d,dptr);
                   2293:      dptr->state=DOORSTATE_CLOSE;
                   2294:      EFF_blockDoorWalls(s);
                   2295:      SND_playSectorCloseSound(s);
                   2296: }
                   2297: 
                   2298: void
                   2299: EFF_operateDoor(short s)
                   2300: {
                   2301:      short d,key;
                   2302: 
                   2303:      if ((d=doorIndex[s]) == -1) {
                   2304:           return;
                   2305:      }
                   2306:      switch (sectorPtr[s]->lotag) {
                   2307:      case SEC_ROTATESECTORTAG:
                   2308:      case SEC_BONUSSECTORTAG:
                   2309:           return;
                   2310:      }
                   2311:      switch (doorPtr[d]->state) {
                   2312:      case DOORSTATE_IDLE:
                   2313:      case DOORSTATE_CLOSE:
                   2314:      case DOORSTATE_CLOSED:
                   2315:           if (EFF_checkSwitches(sectorPtr[s]->hitag,&key)) {
                   2316:                if (key == EFF_getDoorLock(s)) {
                   2317:                     EFF_openDoor(s);
                   2318:                }
                   2319:           }
                   2320:           break;
                   2321:      case DOORSTATE_OPEN:
                   2322:      case DOORSTATE_OPENED:
                   2323:      case DOORSTATE_WAITING:
                   2324:           EFF_closeDoor(s);
                   2325:           break;
                   2326:      }
                   2327: }
                   2328: 
                   2329: void
                   2330: EFF_openMovingSectorDoors(short s)
                   2331: {
                   2332:      short i,sectnum;
                   2333:      struct movingSectorData *mptr;
                   2334: 
                   2335:      mptr=movingSectorPtr[movingSectorIndex[s]];
                   2336:      for (i=0 ; i < mptr->numSectors ; i++) {
                   2337:           sectnum=mptr->sector[i];
                   2338:           if (EFF_operatableSector(sectnum)) {
                   2339:                EFF_openDoor(sectnum);
                   2340:           }
                   2341:      }
                   2342: }
                   2343: 
                   2344: void
                   2345: EFF_closeMovingSectorDoors(short s)
                   2346: {
                   2347:      short i,sectnum;
                   2348:      struct movingSectorData *mptr;
                   2349: 
                   2350:      mptr=movingSectorPtr[movingSectorIndex[s]];
                   2351:      for (i=0 ; i < mptr->numSectors ; i++) {
                   2352:           sectnum=mptr->sector[i];
                   2353:           if (EFF_operatableSector(sectnum)) {
                   2354:                EFF_closeDoor(sectnum);
                   2355:           }
                   2356:      }
                   2357: }
                   2358: 
                   2359: void
                   2360: EFF_operateMovingSector(short s)
                   2361: {
                   2362:      short i;
                   2363:      struct movingSectorData *mptr;
                   2364: 
                   2365:      if ((i=movingSectorIndex[s]) == -1) {
                   2366:           return;
                   2367:      }
                   2368:      mptr=movingSectorPtr[i];
                   2369:      if (mptr->active) {
                   2370:           mptr->goalSpeed=0;
                   2371:           EFF_openMovingSectorDoors(s);
                   2372:      }
                   2373:      else {
                   2374:           mptr->active=1;
                   2375:           mptr->goalSpeed=mptr->maxSpeed;
                   2376:           EFF_turnSwitchesOn(sectorPtr[s]->hitag);
                   2377:           EFF_closeMovingSectorDoors(s);
                   2378:      }
                   2379: }
                   2380: 
                   2381: void
                   2382: EFF_operateSector(short s)
                   2383: {
                   2384:      short lo;
                   2385: 
                   2386:      lo=sectorPtr[s]->lotag;
                   2387:      if (lo > 0) {
                   2388:           if (EFF_operatableSector(s)) {
                   2389:                EFF_operateDoor(s);
                   2390:           }
                   2391:           else if (EFF_isMovingSector(s)) {
                   2392:                EFF_operateMovingSector(s);
                   2393:           }
                   2394:      }
                   2395: }
                   2396: 
                   2397: //**
                   2398: //** Miscellaneous routines code
                   2399: //**
                   2400: 
                   2401: void
                   2402: EFF_showMessages(void)
                   2403: {
                   2404:      int  i,j;
                   2405:      static int cycle;
                   2406:      struct message *msg;
                   2407:      
                   2408:      j=0;
                   2409:      for (i=0 ; i < MAXMESSAGES ; i++) {
                   2410:           if (messagePtr[i]->delay <= 0) {
                   2411:                continue;
                   2412:           }
                   2413:           msg=messagePtr[j];
                   2414:           if (i != j) {
                   2415:                memmove(msg,messagePtr[i],sizeof(struct message));
                   2416:                messagePtr[i]->delay=0;
                   2417:           }
                   2418:           msg->delay-=TICWAITPERFRAME;
                   2419:           if (msg->delay > 0) {
                   2420:                if (qsetmode == 200L) {
                   2421:                     printext256(windowx1,windowy2-((j+1)<<3),
                   2422:                                 PMSGCOLOR-(cycle&15)-i,
                   2423:                                 -1,msg->buf,0);
                   2424:                }
                   2425:           }
                   2426:           j++;
                   2427:      }
                   2428:      cycle++;
                   2429: }
                   2430: 
                   2431: void
                   2432: EFF_displayMessage(char *fmt,...)
                   2433: {
                   2434:      int  nextMessage;
                   2435:      char locbuf[MESSAGESIZE];
                   2436:      va_list argptr;
                   2437: 
                   2438:      for (nextMessage=0 ; nextMessage <= MAXMESSAGES-1 ; nextMessage++) {
                   2439:           if (messagePtr[nextMessage]->delay <= 0) {
                   2440:                break;
                   2441:           }
                   2442:      }
                   2443:      if (nextMessage == MAXMESSAGES) {
                   2444:           for (nextMessage=1 ; nextMessage < MAXMESSAGES ; nextMessage++) {
                   2445:                memmove(messagePtr[nextMessage-1],messagePtr[nextMessage],
                   2446:                        sizeof(struct message));
                   2447:           }
                   2448:           nextMessage=MAXMESSAGES-1;
                   2449:      }
                   2450:      va_start(argptr,fmt);
                   2451:      vsprintf(locbuf,fmt,argptr);
                   2452:      va_end(argptr);
                   2453:      strncpy(messagePtr[nextMessage]->buf,locbuf,MESSAGESIZE-1);
                   2454:      messagePtr[nextMessage]->delay=TMR_getSecondTics(4);
                   2455: }
                   2456: 
                   2457: //**
                   2458: //** Sprite & wall switches code
                   2459: //**
                   2460: 
                   2461: void
                   2462: EFF_spriteSwitchOff(short s)
                   2463: {
                   2464:      if (EFF_getSpriteSwitchStatus(s)) {
                   2465:           EFF_setSpriteSwitchStatus(s,SWITCH_OFF);
                   2466:           spritePtr[s]->picnum--;
                   2467:      }
                   2468: }
                   2469: 
                   2470: void
                   2471: EFF_spriteSwitchOn(short s)
                   2472: {
                   2473:      if (!EFF_getSpriteSwitchStatus(s)) {
                   2474:           EFF_setSpriteSwitchStatus(s,SWITCH_ON);
                   2475:           spritePtr[s]->picnum++;
                   2476:      }
                   2477: }
                   2478: 
                   2479: void
                   2480: EFF_wallSwitchOff(short w)
                   2481: {
                   2482:      if (EFF_getWallSwitchStatus(w)) {
                   2483:           EFF_setWallSwitchStatus(w,SWITCH_OFF);
                   2484:           wallPtr[w]->picnum--;
                   2485:      }
                   2486: }
                   2487: 
                   2488: void
                   2489: EFF_wallSwitchOn(short w)
                   2490: {
                   2491:      if (!EFF_getWallSwitchStatus(w)) {
                   2492:           EFF_setWallSwitchStatus(w,SWITCH_ON);
                   2493:           wallPtr[w]->picnum++;
                   2494:      }
                   2495: }
                   2496: 
                   2497: void
                   2498: EFF_turnSwitchesOn(short hitag)
                   2499: {
                   2500:      short i,s,w;
                   2501: 
                   2502:      i=0;
                   2503:      while ((w=hitagWallIndex[i++]) >= 0) {
                   2504:           if (EFF_isWallSwitch(w)) {
                   2505:                if (wallPtr[w]->hitag == hitag) {
                   2506:                     EFF_wallSwitchOn(w);
                   2507:                }
                   2508:           }
                   2509:      }
                   2510:      i=0;
                   2511:      while ((s=hitagSpriteIndex[i++]) >= 0) {
                   2512:           if (EFF_isSpriteSwitch(s)) {
                   2513:                if (spritePtr[s]->hitag == hitag) {
                   2514:                     EFF_spriteSwitchOn(s);
                   2515:                }
                   2516:           }
                   2517:      }
                   2518: }
                   2519: 
                   2520: void
                   2521: EFF_turnSwitchesOff(short hitag)
                   2522: {
                   2523:      short i,s,w;
                   2524: 
                   2525:      i=0;
                   2526:      while ((w=hitagWallIndex[i++]) >= 0) {
                   2527:           if (EFF_isWallSwitch(w)) {
                   2528:                if (wallPtr[w]->hitag == hitag) {
                   2529:                     EFF_wallSwitchOff(w);
                   2530:                }
                   2531:           }
                   2532:      }
                   2533:      i=0;
                   2534:      while ((s=hitagSpriteIndex[i++]) >= 0) {
                   2535:           if (EFF_isSpriteSwitch(s)) {
                   2536:                if (spritePtr[s]->hitag == hitag) {
                   2537:                     EFF_spriteSwitchOff(s);
                   2538:                }
                   2539:           }
                   2540:      }
                   2541: }
                   2542: 
                   2543: void
                   2544: EFF_operateWalkthruWallTags(short w)
                   2545: {
                   2546:      short s;
                   2547: 
                   2548:      s=sectorofwall(w);
                   2549:      switch (wallPtr[w]->lotag) {
                   2550:      case WAL_W1LIGHTSOFFTAG:
                   2551:           EFF_sectorLightsOff(s);
                   2552:           EFF_turnSwitchesOff(wallPtr[w]->hitag);
                   2553:           wallPtr[w]->lotag=0;
                   2554:           break;
                   2555:      case WAL_WRLIGHTSOFFTAG:
                   2556:           EFF_sectorLightsOff(s);
                   2557:           EFF_turnSwitchesOff(wallPtr[w]->hitag);
                   2558:           break;
                   2559:      case WAL_W1LIGHTSONFULLTAG:
                   2560:           EFF_sectorLightsOn(s);
                   2561:           EFF_turnSwitchesOn(wallPtr[w]->hitag);
                   2562:           wallPtr[w]->lotag=0;
                   2563:           break;
                   2564:      case WAL_WRLIGHTSONFULLTAG:
                   2565:           EFF_sectorLightsOn(s);
                   2566:           EFF_turnSwitchesOn(wallPtr[w]->hitag);
                   2567:           break;
                   2568:      }
                   2569: }
                   2570: 
                   2571: void
                   2572: EFF_operateSwitchedWallTags(short w)
                   2573: {
                   2574:      short s;
                   2575: 
                   2576:      s=sectorofwall(w);
                   2577:      switch (wallPtr[w]->lotag) {
                   2578:      case WAL_SRLIGHTSOFFTAG:
                   2579:           EFF_sectorLightsOff(s);
                   2580:           EFF_turnSwitchesOff(wallPtr[w]->hitag);
                   2581:           break;
                   2582:      case WAL_SRLIGHTSONFULLTAG:
                   2583:           EFF_sectorLightsOn(s);
                   2584:           EFF_turnSwitchesOn(wallPtr[w]->hitag);
                   2585:           break;
                   2586:      }
                   2587: }
                   2588: 
                   2589: void
                   2590: EFF_operateThings(short hitag)
                   2591: {
                   2592:      short i,w;
                   2593: 
                   2594:      for (i=0 ; i < numsectors ; i++) {
                   2595:           if (sectorPtr[i]->hitag == hitag) {
                   2596:                EFF_operateSector(i);
                   2597:           }
                   2598:      }
                   2599:      for (i=0 ; i < MAXLIGHTEFFECTS ; i++) {
                   2600:           if ((w=lightWallIndex[i]) == -1) {
                   2601:                break;
                   2602:           }
                   2603:           if (wallPtr[w]->hitag != hitag) {
                   2604:                continue;
                   2605:           }
                   2606:           EFF_operateSwitchedWallTags(w);
                   2607:      }
                   2608: }
                   2609: 
                   2610: void
                   2611: EFF_operateSprite(short s)
                   2612: {
                   2613:      short hi;
                   2614:      spritetype *spr;
                   2615: 
                   2616:      spr=spritePtr[s];
                   2617:      switch (spr->lotag) {
                   2618:      case SPR_SWITCHTAG:
                   2619:           hi=spr->hitag;
                   2620:           if (hi > 0) {
                   2621:                if (EFF_getSpriteSwitchStatus(s)) {
                   2622:                     EFF_spriteSwitchOff(s);
                   2623:                     SND_playSwitchOffSound(s);
                   2624:                }
                   2625:                else {
                   2626:                     EFF_spriteSwitchOn(s);
                   2627:                     SND_playSwitchOnSound(s);
                   2628:                }
                   2629:                if (hi == SWITCH_NEXTLEVEL) {
                   2630:                     if (editorEnabledFlag) {
                   2631:                          EFF_displayMessage("NO LEVEL CHANGE WHILE EDITING");
                   2632:                     }
                   2633:                     else {
                   2634:                          GAM_nextLevel();
                   2635:                     }
                   2636:                }
                   2637:                else {
                   2638:                     EFF_operateThings(hi);
                   2639:                }
                   2640:           }
                   2641:           break;
                   2642:      }
                   2643: }
                   2644: 
                   2645: void
                   2646: EFF_operateWall(short w)
                   2647: {
                   2648:      short hi,i;
                   2649:      walltype *wal;
                   2650: 
                   2651:      wal=wallPtr[w];
                   2652:      switch (wal->lotag) {
                   2653:      case WAL_SWITCHTAG:
                   2654:           hi=wal->hitag;
                   2655:           if (hi > 0) {
                   2656:                if (EFF_getWallSwitchStatus(w)) {
                   2657:                     EFF_wallSwitchOff(w);
                   2658:                     SND_playWallSwitchOffSound(w);
                   2659:                }
                   2660:                else {
                   2661:                     EFF_wallSwitchOn(w);
                   2662:                     SND_playWallSwitchOnSound(w);
                   2663:                }
                   2664:                if (hi == SWITCH_NEXTLEVEL) {
                   2665:                     if (editorEnabledFlag) {
                   2666:                          EFF_displayMessage("NO LEVEL CHANGE WHILE EDITING");
                   2667:                     }
                   2668:                     else {
                   2669:                          GAM_nextLevel();
                   2670:                     }
                   2671:                }
                   2672:                else {
                   2673:                     for (i=0 ; i < numsectors ; i++) {
                   2674:                          if (sectorPtr[i]->hitag == hi) {
                   2675:                               EFF_operateSector(i);
                   2676:                          }
                   2677:                     }
                   2678:                }
                   2679:           }
                   2680:           break;
                   2681:      }
                   2682: }
                   2683: 
                   2684: void
                   2685: EFF_doEnterSectorTags(short snum,short *s,short *ang,long *x,long *y,long *z)
                   2686: {
                   2687:      short clipdist,endwall,playerHeight,startwall,w;
                   2688:      sectortype *sect;
                   2689:      spritetype *spr;
                   2690: 
                   2691:      spr=spritePtr[snum];
                   2692:      sect=sectorPtr[*s];
                   2693:      startwall=sect->wallptr;
                   2694:      endwall=startwall+sect->wallnum;
                   2695:      playerHeight=ACT_getActorViewHeight(spr);
                   2696:      clipdist=ACT_getActorClipDist(spr);
                   2697:      for (w=startwall ; w < endwall ; w++) {
                   2698:           switch (wallPtr[w]->lotag) {
                   2699:           case WAL_TRIGGERTAG:
                   2700:                EFF_operateThings(wallPtr[w]->hitag);
                   2701:                break;
                   2702:           case WAL_WARPTAG:
                   2703:                EFF_warpSprite(w,snum,ang,s,x,y,z);
                   2704:                *z-=playerHeight;
                   2705:                spr->cstat&=~(SPRC_BLOCKING);
                   2706:                getzrange(*x,*y,*z,*s,&globhiz,&globhihit,&globloz,
                   2707:                          &globlohit,clipdist,0);
                   2708:                spr->cstat|=(SPRC_BLOCKING);
                   2709:                break;
                   2710:           default:
                   2711:                if (wallPtr[w]->lotag > 0) {
                   2712:                     EFF_operateWalkthruWallTags(w);
                   2713:                }
                   2714:                break;
                   2715:           }
                   2716:      }
                   2717:      if (PLR_isPlayer(spr,-1)) {
                   2718:           switch (sect->lotag) {
                   2719:           case SEC_SECRETTAG:
                   2720:                sect->lotag=SEC_NORMAL;
                   2721:                if (GAM_isViewSprite(snum)) {
                   2722:                     EFF_displayMessage("SECRET ROOM");
                   2723:                }
                   2724:                break;
                   2725:           }
                   2726:      }
                   2727: }
                   2728: 
                   2729: void
                   2730: EFF_doLeaveSectorTags(short snum,short *s,short *ang,long *x,long *y,long *z)
                   2731: {
                   2732: }
                   2733: 
                   2734: void
                   2735: EFF_spawnBlood(short s,short shooter,short damage)
                   2736: {
                   2737:      short i,j,n;
                   2738:      spritetype *spr,*src,*trg;
                   2739: 
                   2740:      if (bloodCount >= MAXBLOODCOUNT) {
                   2741:           return;
                   2742:      }
                   2743:      trg=spritePtr[s];
                   2744:      src=spritePtr[shooter];
                   2745:      n=((damage>>8)+1)&7;
                   2746:      for (i=0 ; i < n ; i++) {
                   2747:           if ((j=goreSprite[goreCount]) >= 0) {
                   2748:                if (spritePtr[j]->statnum == STAT_NONE) {
                   2749:                     changespritestat(j,STAT_BLOOD);
                   2750:                }
                   2751:                else {
                   2752:                     continue;
                   2753:                }
                   2754:           }
                   2755:           else {
                   2756:                j=ENG_insertsprite(trg->sectnum,STAT_BLOOD);
                   2757:                goreSprite[goreCount]=j;
                   2758:           }
                   2759:           goreCount=(goreCount+1)&(MAXGORECOUNT-1);
                   2760:           spr=spritePtr[j];
                   2761:           GAM_onGround(j,0);
                   2762:           spr->picnum=goreChunksBegPic+(krand()%
                   2763:                       ((goreChunksEndPic-goreChunksBegPic)+1));
                   2764:           spr->x=trg->x;
                   2765:           spr->y=trg->y;
                   2766:           spr->z=trg->z-(trg->yrepeat<<7);
                   2767:           spr->xrepeat=48;
                   2768:           spr->yrepeat=48;
                   2769:           spr->clipdist=2;
                   2770:           spr->ang=getangle(trg->x-src->x,trg->y-src->y);
                   2771:           if (krand()&1) {
                   2772:                spr->ang-=(krand()&255);
                   2773:           }
                   2774:           else {
                   2775:                spr->ang+=(krand()&255);
                   2776:           }
                   2777:           spr->xvel=(krand()&127);
                   2778:           spr->yvel=(krand()&127);
                   2779:           spr->zvel=-(krand()&2047);
                   2780:           spr->owner=s;
                   2781:           switch (GAM_getGoreLevel()) {
                   2782:           case 0:
                   2783:                spr->cstat|=SPRC_INVISIBLE;
                   2784:                break;
                   2785:           }
                   2786:           bloodCount++;
                   2787:      }
                   2788: }
                   2789: 
                   2790: //**
                   2791: //** Status code
                   2792: //**
                   2793: 
                   2794: void
                   2795: EFF_doStatusBlinkOff(short i,short s)
                   2796: {
                   2797:      struct sectorEffect *si;
                   2798: 
                   2799:      si=&sectorEffectStruct[i];
                   2800:      si->clock-=TICWAITPERFRAME;
                   2801:      if (si->clock > 0) {
                   2802:           return;
                   2803:      }
                   2804:      switch (si->status) {
                   2805:      case 1:
                   2806:           si->clock+=TMR_getSecondFraction(TICS_ONEHALF);
                   2807:           EFF_sectorLightsOn(s);
                   2808:           break;
                   2809:      default:
                   2810:           si->clock+=TMR_getSecondFraction(TICS_ONEEIGHTH);
                   2811:           EFF_sectorLightsOff(s);
                   2812:           break;
                   2813:      }
                   2814:      si->status^=1;
                   2815: }
                   2816: 
                   2817: void
                   2818: EFF_doStatusBlinkOn(short i,short s)
                   2819: {
                   2820:      struct sectorEffect *si;
                   2821: 
                   2822:      si=&sectorEffectStruct[i];
                   2823:      si->clock-=TICWAITPERFRAME;
                   2824:      if (si->clock > 0) {
                   2825:           return;
                   2826:      }
                   2827:      switch (si->status) {
                   2828:      case 1:
                   2829:           si->clock+=TMR_getSecondFraction(TICS_ONEHALF);
                   2830:           EFF_sectorLightsOff(s);
                   2831:           break;
                   2832:      default:
                   2833:           si->clock+=TMR_getSecondFraction(TICS_ONEEIGHTH);
                   2834:           EFF_sectorLightsOn(s);
                   2835:           break;
                   2836:      }
                   2837:      si->status^=1;
                   2838: }
                   2839: 
                   2840: void
                   2841: EFF_doStatusBlinkOn1s(short i,short s)
                   2842: {
                   2843:      struct sectorEffect *si;
                   2844: 
                   2845:      si=&sectorEffectStruct[i];
                   2846:      si->clock-=TICWAITPERFRAME;
                   2847:      if (si->clock > 0) {
                   2848:           return;
                   2849:      }
                   2850:      switch (si->status) {
                   2851:      case 1:
                   2852:           si->clock+=TMR_getSecondTics(1);
                   2853:           EFF_sectorLightsOff(s);
                   2854:           break;
                   2855:      default:
                   2856:           si->clock+=TMR_getSecondFraction(TICS_ONEEIGHTH);
                   2857:           EFF_sectorLightsOn(s);
                   2858:           break;
                   2859:      }
                   2860:      si->status^=1;
                   2861: }
                   2862: 
                   2863: void
                   2864: EFF_doStatusOscillate(short i,short s)
                   2865: {
                   2866:      struct sectorEffect *si;
                   2867: 
                   2868:      si=&sectorEffectStruct[i];
                   2869:      switch (si->status) {
                   2870:      default:
                   2871:           if (EFF_adjSectorLight(s,TICWAITPERFRAME) >= 239) {
                   2872:                EFF_setSectorLight(s,239);
                   2873:                si->status^=1;
                   2874:           }
                   2875:           break;
                   2876:      case 1:
                   2877:           if (EFF_adjSectorLight(s,-TICWAITPERFRAME) <= 0) {
                   2878:                EFF_setSectorLight(s,0);
                   2879:                si->status^=1;
                   2880:           }
                   2881:           break;
                   2882:      }
                   2883: }
                   2884: 
                   2885: void
                   2886: EFF_doStatusSyncBlinkOn(short i,short s)
                   2887: {
                   2888:      struct sectorEffect *si;
                   2889: 
                   2890:      si=&sectorEffectStruct[i];
                   2891:      if (totalclock < si->clock) {
                   2892:           return;
                   2893:      }
                   2894:      switch (si->status) {
                   2895:      case 1:
                   2896:           si->clock=totalclock+TMR_getSecondFraction(TICS_ONEHALF);
                   2897:           EFF_sectorLightsOff(s);
                   2898:           break;
                   2899:      default:
                   2900:           si->clock=totalclock+TMR_getSecondFraction(TICS_ONEEIGHTH);
                   2901:           EFF_sectorLightsOn(s);
                   2902:           break;
                   2903:      }
                   2904:      si->status^=1;
                   2905: }
                   2906: 
                   2907: void
                   2908: EFF_doStatusSyncBlinkOff(short i,short s)
                   2909: {
                   2910:      struct sectorEffect *si;
                   2911: 
                   2912:      si=&sectorEffectStruct[i];
                   2913:      if (totalclock < si->clock) {
                   2914:           return;
                   2915:      }
                   2916:      switch (si->status) {
                   2917:      case 1:
                   2918:           si->clock=totalclock+TMR_getSecondFraction(TICS_ONEHALF);
                   2919:           EFF_sectorLightsOn(s);
                   2920:           break;
                   2921:      default:
                   2922:           si->clock=totalclock+TMR_getSecondFraction(TICS_ONEEIGHTH);
                   2923:           EFF_sectorLightsOff(s);
                   2924:           break;
                   2925:      }
                   2926:      si->status^=1;
                   2927: }
                   2928: 
                   2929: void
                   2930: EFF_doStatusFlicker(short i,short s)
                   2931: {
                   2932:      struct sectorEffect *si;
                   2933: 
                   2934:      si=&sectorEffectStruct[i];
                   2935:      si->clock-=TICWAITPERFRAME;
                   2936:      if (si->clock > 0) {
                   2937:           return;
                   2938:      }
                   2939:      switch (si->status) {
                   2940:      case 1:
                   2941:           si->clock+=krand()%TMR_getSecondFraction(TICS_ONEEIGHTH);
                   2942:           EFF_sectorLightsOff(s);
                   2943:           break;
                   2944:      default:
                   2945:           si->clock+=krand()%TMR_getSecondFraction(TICS_ONEEIGHTH);
                   2946:           EFF_sectorLightsOn(s);
                   2947:           break;
                   2948:      }
                   2949:      si->status=krand()&1;
                   2950: }
                   2951: 
                   2952: void
                   2953: EFF_doStatusPanCeil(short i,short s)
                   2954: {
                   2955:      long xvect,yvect;
                   2956:      struct sectorEffect *si;
                   2957: 
                   2958:      si=&sectorEffectStruct[i];
                   2959:      xvect=mulscale12(si->speed,sintable[(si->ang+512)&2047]);
                   2960:      yvect=mulscale12(si->speed,sintable[si->ang]);
                   2961:      sectorPtr[s]->ceilingxpanning-=xvect;
                   2962:      sectorPtr[s]->ceilingypanning+=yvect;
                   2963: }
                   2964: 
                   2965: void
                   2966: EFF_doStatusPanFloor(short i,short s)
                   2967: {
                   2968:      short oldsect,snum;
                   2969:      long deltaz,oldloz,xvect,yvect;
                   2970:      struct sectorEffect *si;
                   2971:      spritetype *spr;
                   2972:      sectortype *sectPtr;
                   2973: 
                   2974:      si=&sectorEffectStruct[i];
                   2975:      xvect=(si->speed*sintable[(si->ang+512)&2047]);
                   2976:      yvect=(si->speed*sintable[si->ang]);
                   2977:      sectPtr=sectorPtr[s];
                   2978:      sectPtr->floorxpanning-=(xvect>>12);
                   2979:      sectPtr->floorypanning+=(yvect>>12);
                   2980:      for (snum=headspritesect[s] ; snum >= 0 ; snum=nextspritesect[snum]) {
                   2981:           if (GAM_isOnGround(snum)) {
                   2982:                spr=spritePtr[snum];
                   2983:                oldsect=spr->sectnum;
                   2984:                oldloz=getflorzofslope(oldsect,spr->x,spr->y);
                   2985:                movesprite(snum,xvect<<4,yvect<<4,0L,4L<<8,4L<<8,0);
                   2986:                if (spr->sectnum != oldsect) {
                   2987:                     ACT_newSector(snum,&oldsect,&spr->sectnum,&spr->ang,
                   2988:                                   &spr->x,&spr->y,&spr->z);
                   2989:                }
                   2990:                deltaz=getflorzofslope(spr->sectnum,spr->x,spr->y)-oldloz;
                   2991:                if (deltaz != 0L) {
                   2992:                     spr->z+=deltaz;
                   2993:                }
                   2994:                setsprite(snum,spr->x,spr->y,spr->z);
                   2995:           }
                   2996:      }
                   2997: }
                   2998: 
                   2999: void
                   3000: EFF_doStatusEffects(void)
                   3001: {
                   3002:      short i,s;
                   3003:      struct sectorEffect *si;
                   3004: 
                   3005:      i=0;
                   3006:      while ((s=sectorEffectIndex[i]) >= 0) {
                   3007:           si=&sectorEffectStruct[i];
                   3008:           switch (si->effectTag) {
                   3009:           case SEC_BLINKOFFTAG:
                   3010:                EFF_doStatusBlinkOff(i,s);
                   3011:                break;
                   3012:           case SEC_BLINKONTAG:
                   3013:           case SEC_HIDAMAGEBLINKTAG:
                   3014:                EFF_doStatusBlinkOn(i,s);
                   3015:                break;
                   3016:           case SEC_BLINKON1STAG:
                   3017:                EFF_doStatusBlinkOn1s(i,s);
                   3018:                break;
                   3019:           case SEC_OSCILLATETAG:
                   3020:                EFF_doStatusOscillate(i,s);
                   3021:                break;
                   3022:           case SEC_SYNCBLINKONTAG:
                   3023:                EFF_doStatusSyncBlinkOn(i,s);
                   3024:                break;
                   3025:           case SEC_SYNCBLINKOFFTAG:
                   3026:                EFF_doStatusSyncBlinkOff(i,s);
                   3027:                break;
                   3028:           case SEC_FLICKERTAG:
                   3029:                EFF_doStatusFlicker(i,s);
                   3030:                break;
                   3031:           case SEC_PANCEILTAG:
                   3032:                EFF_doStatusPanCeil(i,s);
                   3033:                break;
                   3034:           case SEC_PANFLOORTAG:
                   3035:                EFF_doStatusPanFloor(i,s);
                   3036:                break;
                   3037:           }
                   3038:           i++;
                   3039:      }
                   3040:      if (lastDamageClock > 0) {
                   3041:           lastDamageClock-=TICWAITPERFRAME;
                   3042:      }
                   3043:      else {
                   3044:           lastDamageClock=TMR_getSecondTics(1);
                   3045:      }
                   3046: }
                   3047: 
                   3048: void
                   3049: EFF_doStatusDieAnim(short i)
                   3050: {
                   3051:      long locloz;
                   3052:      spritetype *spr;
                   3053: 
                   3054:      spr=spritePtr[i];
                   3055:      if ((sectorPtr[spr->sectnum]->floorstat&0x02) != 0) {
                   3056:           locloz=getflorzofslope(spr->sectnum,spr->x,spr->y);
                   3057:      }
                   3058:      else {
                   3059:           locloz=sectorPtr[spr->sectnum]->floorz;
                   3060:      }
                   3061:      if (spr->z < locloz) {
                   3062:           spr->zvel+=gravityConstant;
                   3063:           spr->z+=spr->zvel;
                   3064:      }
                   3065:      if (spr->z >= locloz) {
                   3066:           spr->z=locloz;
                   3067:           spr->zvel=0;
                   3068:      }
                   3069:      if (spr->zvel == 0 && frames[i] == 0) {
                   3070:           changespritestat(i,STAT_NONE);
                   3071:      }
                   3072:      setsprite(i,spr->x,spr->y,spr->z);
                   3073:      frameDelay[i]-=TICWAITPERFRAME;
                   3074:      if (frameDelay[i] <= 0) {
                   3075:           frameDelay[i]=frameDelayReset[i];
                   3076:           if (frames[i] > 0) {
                   3077:                frames[i]--;
                   3078:                spr->picnum++;
                   3079:           }
                   3080:      }
                   3081: }
                   3082: 
                   3083: void
                   3084: EFF_doStatusBlood(short i)
                   3085: {
                   3086:      int  o;
                   3087:      long dax,day,daz;
                   3088:      spritetype *spr;
                   3089: 
                   3090:      spr=spritePtr[i];
                   3091:      dax=spr->xvel*sintable[(spr->ang+512)&2047];
                   3092:      day=spr->yvel*sintable[spr->ang];
                   3093:      daz=spr->zvel;
                   3094:      if ((spr->cstat&SPRC_WALLSPRITE) != 0) {
                   3095:           daz>>=2;
                   3096:      }
                   3097:      o=movesprite(i,dax,day,daz,spr->yrepeat<<4,spr->yrepeat<<4,0);
                   3098:      if ((o&32768) == 32768) {
                   3099:           spr->cstat|=SPRC_WALLSPRITE;
                   3100:           spr->xvel=0;
                   3101:           spr->yvel=0;
                   3102:      }
                   3103:      if ((o&16384) != 16384) {
                   3104:           daz=spr->zvel+gravityConstant;
                   3105:           if (daz > 32767L) {
                   3106:                daz=32767L;
                   3107:           }
                   3108:           spr->zvel=daz;
                   3109:      }
                   3110:      else {
                   3111:           GAM_onGround(i,1);
                   3112:           spr->z=globloz;
                   3113:           spr->xvel=0;
                   3114:           spr->yvel=0;
                   3115:           spr->zvel=0;
                   3116:           if ((spr->cstat&SPRC_WALLSPRITE) == 0) {
                   3117:                spr->cstat|=SPRC_FLOORSPRITE;
                   3118:           }
                   3119:           changespritestat(i,STAT_NONE);
                   3120:           bloodCount--;
                   3121:      }
                   3122:      setsprite(i,spr->x,spr->y,spr->z);
                   3123: }
                   3124: 
                   3125: void
                   3126: EFF_doStatusAnims(void)
                   3127: {
                   3128:      short i,nexti;
                   3129: 
                   3130:      for (i=headspritestat[STAT_DIEANIM] ; i >= 0 ; i=nexti) {
                   3131:           nexti=nextspritestat[i];
                   3132:           EFF_doStatusDieAnim(i);
                   3133:      }
                   3134:      for (i=headspritestat[STAT_BLOOD] ; i >= 0 ; i=nexti) {
                   3135:           nexti=nextspritestat[i];
                   3136:           EFF_doStatusBlood(i);
                   3137:      }
                   3138: }
                   3139: 
                   3140: void
                   3141: EFF_doStatusMovingSectors(void)
                   3142: {
                   3143:      short endwall,i,j,n,nexts,rotang=0,s,sectnum,snum,startwall,w;
                   3144:      long dx,rotx,roty,rx,ry,x,xvect,y,yvect;
                   3145:      struct movingSectorData *mptr;
                   3146:      spritetype *spr,*spr2;
                   3147:      sectortype *sect;
                   3148: 
                   3149:      for (i=0 ; i < numMovingSectors ; i++) {
                   3150:           mptr=movingSectorPtr[i];
                   3151:           snum=mptr->pivotSprite;
                   3152:           spr=spritePtr[snum];
                   3153:           if (mptr->active) {
                   3154:                if (mptr->speed < mptr->goalSpeed) {
                   3155:                     mptr->speed++;
                   3156:                }
                   3157:                else if (mptr->speed > mptr->goalSpeed) {
                   3158:                     mptr->speed--;
                   3159:                }
                   3160:                if (mptr->targetSprite >= 0) {
                   3161:                     spr2=spritePtr[mptr->targetSprite];
                   3162:                     dx=WEP_getDistance(spr,spr2);
                   3163:                     if (spr2->picnum == STOPSIGNPIC) {
                   3164:                          s=kmax(dx>>8,4);
                   3165:                          if (s < mptr->speed) {
                   3166:                               mptr->speed=s;
                   3167:                               mptr->goalSpeed=s;
                   3168:                          }
                   3169:                          if (dx <= 32) {
                   3170:                               mptr->speed=0;
                   3171:                               mptr->goalSpeed=0;
                   3172:                               mptr->targetSprite=-1;
                   3173:                               rotang=(spr2->ang-spr->ang);
                   3174:                               if (rotang != 0) {
                   3175:                                    rotx=spr->x;
                   3176:                                    roty=spr->y;
                   3177:                                    spr->ang=(spr->ang+rotang)&2047;
                   3178:                               }
                   3179:                               if (spr2->hitag > 0) {
                   3180:                                    EFF_operateThings(spr2->hitag);
                   3181:                               }
                   3182:                          }
                   3183:                          else {
                   3184:                               rotang=getangle(spr2->x-spr->x,spr2->y-spr->y)-spr->ang;
                   3185:                               if (rotang != 0) {
                   3186:                                    rotx=spr->x;
                   3187:                                    roty=spr->y;
                   3188:                                    spr->ang=(spr->ang+rotang)&2047;
                   3189:                               }
                   3190:                          }
                   3191:                     }
                   3192:                     else if ((dx>>8) <= 0) {
                   3193:                          mptr->targetSprite=-1;
                   3194:                          rotang=spr2->ang-spr->ang;
                   3195:                          if (rotang != 0) {
                   3196:                               rotx=spr->x;
                   3197:                               roty=spr->y;
                   3198:                               spr->ang=(spr->ang+rotang)&2047;
                   3199:                          }
                   3200:                     }
                   3201:                     else {
                   3202:                          rotang=getangle(spr2->x-spr->x,spr2->y-spr->y)-spr->ang;
                   3203:                          if (rotang != 0) {
                   3204:                               rotx=spr->x;
                   3205:                               roty=spr->y;
                   3206:                               spr->ang=(spr->ang+rotang)&2047;
                   3207:                          }
                   3208:                     }
                   3209:                }
                   3210:           }
                   3211:           if (mptr->speed > 0) {
                   3212:                xvect=mulscale10(sintable[(spr->ang+512)&2047],mptr->speed);
                   3213:                yvect=mulscale10(sintable[spr->ang],mptr->speed);
                   3214:                x=spr->x+xvect;
                   3215:                y=spr->y+yvect;
                   3216:                setsprite(snum,x,y,spr->z);
                   3217:                for (j=0,n=0 ; j < mptr->numSectors ; j++) {
                   3218:                     sectnum=mptr->sector[j];
                   3219:                     sect=sectorPtr[sectnum];
                   3220:                     startwall=sect->wallptr;
                   3221:                     endwall=startwall+sect->wallnum;
                   3222:                     for (w=startwall ; w < endwall ; w++) {
                   3223:                          x=spr->x-mptr->pointDeltaX[n];
                   3224:                          y=spr->y-mptr->pointDeltaY[n];
                   3225:                          switch (sectorPtr[mptr->sectnum]->lotag) {
                   3226:                          case SEC_MOVINGSECTORTAG:
                   3227:                          case SEC_AUTOMOVINGSECTORTAG:
                   3228:                               rotatepoint(spr->x,spr->y,x,y,spr->ang,&rx,&ry);
                   3229:                               break;
                   3230:                          case SEC_MOVINGSECTORFIXEDTAG:
                   3231:                          case SEC_AUTOMOVINGSECTORFIXEDTAG:
                   3232:                               rx=x;
                   3233:                               ry=y;
                   3234:                               break;
                   3235:                          }
                   3236:                          dragpoint(w,rx,ry);
                   3237:                          n++;
                   3238:                     }
                   3239:                     for (s=headspritesect[sectnum] ; s >= 0 ; s=nexts) {
                   3240:                          nexts=nextspritesect[s];
                   3241:                          if (s != snum) {
                   3242:                               spr2=spritePtr[s];
                   3243:                               if (rotang != 0) {
                   3244:                                    spr2->ang=(spr2->ang+rotang)&2047;
                   3245:                                    rotatepoint(rotx,roty,spr2->x,spr2->y,
                   3246:                                                rotang&2047,&x,&y);
                   3247:                                    setsprite(s,x,y,spr2->z);
                   3248:                               }
                   3249:                               x=spr2->x+xvect;
                   3250:                               y=spr2->y+yvect;
                   3251:                               setsprite(s,x,y,spr2->z);
                   3252:                          }
                   3253:                     }
                   3254:                }
                   3255:                if (mptr->targetSprite < 0) {
                   3256:                     dx=0x7FFFFFFF;
                   3257:                     s=headspritestat[STAT_MOVINGSECTORMARKER];
                   3258:                     while (s >= 0) {
                   3259:                          nexts=nextspritestat[s];
                   3260:                          spr2=spritePtr[s];
                   3261:                          if (WEP_canSeeRange(spr,spr2,512,dx)) {
                   3262:                               mptr->targetSprite=s;
                   3263:                               dx=WEP_getDistance(spr,spr2);
                   3264:                          }
                   3265:                          s=nexts;
                   3266:                     }
                   3267:                }
                   3268:           }
                   3269:           else if (mptr->active) {
                   3270:                if (mptr->delay <= 0) {
                   3271:                     mptr->active=0;
                   3272:                     switch (sectorPtr[mptr->sectnum]->lotag) {
                   3273:                     case SEC_AUTOMOVINGSECTORTAG:
                   3274:                     case SEC_AUTOMOVINGSECTORFIXEDTAG:
                   3275:                          mptr->delay=TMR_getSecondTics(8);
                   3276:                          break;
                   3277:                     default:
                   3278:                          EFF_turnSwitchesOff(sectorPtr[mptr->sectnum]->hitag);
                   3279:                          break;
                   3280:                     }
                   3281:                }
                   3282:           }
                   3283:           else if (mptr->delay > 0) {
                   3284:                mptr->delay-=TICWAITPERFRAME;
                   3285:                if (mptr->delay <= 0) {
                   3286:                     mptr->delay=0;
                   3287:                     mptr->active=1;
                   3288:                     mptr->goalSpeed=mptr->maxSpeed;
                   3289:                     EFF_closeMovingSectorDoors(mptr->sectnum);
                   3290:                }
                   3291:           }
                   3292:      }
                   3293: }
                   3294: 
                   3295: void
                   3296: EFF_doStatusCode(void)
                   3297: {
                   3298:      EFF_doMoveDoors();
                   3299:      EFF_doStatusEffects();
                   3300:      EFF_doStatusAnims();
                   3301:      EFF_doStatusMovingSectors();
                   3302: }
                   3303: 
                   3304: //**
                   3305: //** Load/Save game code
                   3306: //**
                   3307: 
                   3308: void
                   3309: EFF_saveGame(FILE *fp)
                   3310: {
                   3311:      short i,k;
                   3312: 
                   3313:      GAM_fwrite(&numDoors,sizeof(short),1,fp);
                   3314:      for (i=0 ; i < numDoors ; i++) {
                   3315:           GAM_fwrite(doorPtr[i],sizeof(struct doorData),1,fp);
                   3316:      }
                   3317:      GAM_fwrite(&numMovingSectors,sizeof(short),1,fp);
                   3318:      for (i=0 ; i < numMovingSectors ; i++) {
                   3319:           GAM_fwrite(movingSectorPtr[i],sizeof(struct movingSectorData),1,fp);
                   3320:      }
                   3321:      GAM_fwrite(movingSectorIndex,sizeof(short),MAXSECTORS,fp);
                   3322:      GAM_fwrite(lightWallIndex,sizeof(short),MAXLIGHTEFFECTS,fp);
                   3323:      GAM_fwrite(sectorEffectIndex,sizeof(short),MAXSECTOREFFECTS,fp);
                   3324:      for (i=0 ; i < MAXSECTOREFFECTS ; i++) {
                   3325:           if (sectorEffectIndex[i] >= 0) {
                   3326:                GAM_fwrite(&sectorEffectStruct[i],sizeof(struct sectorEffect),
                   3327:                           1,fp);
                   3328:           }
                   3329:      }
                   3330:      GAM_fwrite(&lastDamageClock,sizeof(short),1,fp);
                   3331:      for (k=STAT_HITSCANEXPLODE ; k <= STAT_DIEANIM ; k++) {
                   3332:           for (i=headspritestat[k] ; i >= 0 ; i=nextspritestat[i]) {
                   3333:                GAM_fwrite(&frames[i],sizeof(short),1,fp);
                   3334:                GAM_fwrite(&frameDelay[i],sizeof(short),1,fp);
                   3335:                GAM_fwrite(&frameDelayReset[i],sizeof(short),1,fp);
                   3336:           }
                   3337:      }
                   3338:      GAM_fwrite(&bloodCount,sizeof(short),1,fp);
                   3339:      GAM_fwrite(&goreCount,sizeof(short),1,fp);
                   3340:      GAM_fwrite(goreSprite,sizeof(short),MAXGORECOUNT,fp);
                   3341:      GAM_fwrite(wallSwitchStatus,sizeof(char),MAXWALLS>>3,fp);
                   3342:      GAM_fwrite(spriteSwitchStatus,sizeof(char),MAXSPRITES>>3,fp);
                   3343: }
                   3344: 
                   3345: void
                   3346: EFF_loadGame(FILE *fp)
                   3347: {
                   3348:      short i,k;
                   3349: 
                   3350:      GAM_fread(&numDoors,sizeof(short),1,fp);
                   3351:      for (i=0 ; i < numDoors ; i++) {
                   3352:           GAM_fread(doorPtr[i],sizeof(struct doorData),1,fp);
                   3353:           doorIndex[doorPtr[i]->sectorIndex]=i;
                   3354:      }
                   3355:      GAM_fread(&numMovingSectors,sizeof(short),1,fp);
                   3356:      for (i=0 ; i < numMovingSectors ; i++) {
                   3357:           GAM_fread(movingSectorPtr[i],sizeof(struct movingSectorData),1,fp);
                   3358:      }
                   3359:      GAM_fread(movingSectorIndex,sizeof(short),MAXSECTORS,fp);
                   3360:      GAM_fread(lightWallIndex,sizeof(short),MAXLIGHTEFFECTS,fp);
                   3361:      GAM_fread(sectorEffectIndex,sizeof(short),MAXSECTOREFFECTS,fp);
                   3362:      for (i=0 ; i < MAXSECTOREFFECTS ; i++) {
                   3363:           if (sectorEffectIndex[i] >= 0) {
                   3364:                GAM_fread(&sectorEffectStruct[i],sizeof(struct sectorEffect),
                   3365:                          1,fp);
                   3366:           }
                   3367:      }
                   3368:      GAM_fread(&lastDamageClock,sizeof(short),1,fp);
                   3369:      for (k=STAT_HITSCANEXPLODE ; k <= STAT_DIEANIM ; k++) {
                   3370:           for (i=headspritestat[k] ; i >= 0 ; i=nextspritestat[i]) {
                   3371:                GAM_fread(&frames[i],sizeof(short),1,fp);
                   3372:                GAM_fread(&frameDelay[i],sizeof(short),1,fp);
                   3373:                GAM_fread(&frameDelayReset[i],sizeof(short),1,fp);
                   3374:           }
                   3375:      }
                   3376:      GAM_fread(&bloodCount,sizeof(short),1,fp);
                   3377:      GAM_fread(&goreCount,sizeof(short),1,fp);
                   3378:      GAM_fread(goreSprite,sizeof(short),MAXGORECOUNT,fp);
                   3379:      GAM_fread(wallSwitchStatus,sizeof(char),MAXWALLS>>3,fp);
                   3380:      GAM_fread(spriteSwitchStatus,sizeof(char),MAXSPRITES>>3,fp);
                   3381: }
                   3382: 
                   3383: void
                   3384: EFF_debug(void)
                   3385: {
                   3386:      int  i;
                   3387:      char num[8];
                   3388: 
                   3389:      sprintf(tempbuf,"MOVINGDOORS(%d): ",numMovingDoors);
                   3390:      for (i=0 ; i < numMovingDoors ; i++) {
                   3391:           sprintf(num,"%d ",movingDoor[i]);
                   3392:           strcat(tempbuf,num);
                   3393:      }
                   3394:      debugOut(windowx1,windowy1,tempbuf);
                   3395: }
                   3396: 

unix.superglobalmegacorp.com