code:
/***************************************************************************
 *   TEKGUN.C  - Tekwar specific code for shooting                         *
 *                                                                         *
 *                                                                         *
 ***************************************************************************/

#include "build.h"
#include "names.h"
#include "pragmas.h"
#include "mmulti.h"

#include "tekwar.h"

#define   NUMWEAPONS               8

#define   FORCEPROJECTILESTAT      710
#define   DARTPROJECTILESTAT       712
#define   BOMBPROJECTILESTAT       714
#define   BOMBPROJECTILESTAT2      716
#define   ROCKETPROJECTILESTAT     718
#define   MATRIXPROJECTILESTAT     720
#define   MOVEBODYPARTSSTAT        900
#define   VANISH                   999

#define   DRAWWEAPSPEED       4

int       goreflag;
int       fireseq[MAXPLAYERS];
int       oneshot[MAXPLAYERS];
short     ammo0[MAXPLAYERS];
short     ammo1[MAXPLAYERS];
short     ammo2[MAXPLAYERS];
short     ammo3[MAXPLAYERS];
short     ammo4[MAXPLAYERS];
short     ammo5[MAXPLAYERS];
short     ammo6[MAXPLAYERS];
short     ammo7[MAXPLAYERS];
short     ammo8[MAXPLAYERS];
int      weapons[MAXPLAYERS];          // flags for weapons onself
int      firedonetics[MAXPLAYERS];
int      lastgun[MAXPLAYERS];
int       drawweap[MAXPLAYERS];

struct guntype {
     short pic;               // gun frame when carrying weapon
     short firepic;           // 1st gun frame when firing weapon
     short endfirepic;        // last gun frame when firing weapon
     char rep;                // 1=automatic weapon, 0=semi-automatic
     char action[8];          // 8 frame action bytes - 1=shootgun()
     char pos;                // position on screen 0=center, 1=left, 2=right
     short tics;              // tics to delay for each frame
} guntype[NUMWEAPONS]={
     //   pic         firepic    endfirepic rep /             \ pos  tics/frame
     {GUN07READY,GUN07FIRESTART,GUN07FIREEND,0,{0,1,0,0,0,0,0,0},2,TICSPERFRAME*8},
     {GUN04READY,GUN04FIRESTART,GUN04FIREEND,1,{0,1,0,0,0,0,0,0},2,TICSPERFRAME*4},
     {GUN01READY,GUN01FIRESTART,GUN01FIREEND,1,{0,1,0,0,0,0,0,0},2,TICSPERFRAME*4},
     {GUN03READY,GUN03FIRESTART,GUN03FIREEND,1,{0,1,0,0,0,0,0,0},2,TICSPERFRAME*2},
     {GUN02READY,GUN02FIRESTART,GUN02FIREEND,1,{0,1,0,0,0,0,0,0},2,TICSPERFRAME*2},
     {GUN08READY,GUN08FIRESTART,GUN08FIREEND,1,{0,1,0,0,0,0,0,0},2,TICSPERFRAME*2},
     {GUN05READY,GUN05FIRESTART,GUN05FIREEND,0,{0,1,1,0,0,0,0,0},2,TICSPERFRAME*8},
     // matrix hand
     {      3980,          3981,        3984,1,{0,1,0,0,0,0,0,0},2,TICSPERFRAME*3}
};

int  gunbobx[10]={0,2,4,6,8,8,8,6,4,2};
int  gunboby[10]={0,2,4,6,8,10,8,6,4,2};
int  gunbob,bobtics;

short
maxdamage[NUMWEAPONS]={ 10, 100, 500, 500, 20, 500, 500, 1000 };
short
mindamage[NUMWEAPONS]={ 1,   1,  10,  50,   1,  10,  50,  10,  };

int
validplayer(int snum)
{
     int       j;

     for( j=connecthead ; j >= 0 ; j=connectpoint2[j] ) {
          if( j == snum ) {
               return(1);
          }
     }
     return(0);
}

void
restockammo(int snum)
{
     ammo1[snum]=MAXAMMO;
     ammo2[snum]=MAXAMMO>>1;
     ammo3[snum]=20;
     ammo4[snum]=0;
     ammo5[snum]=MAXAMMO;
     ammo6[snum]=0;
     ammo7[snum]=0;
     ammo8[snum]=0;
}

int
tekgunrep(int gun)                // is "gun" an automatic weapon?
{
     return(guntype[gun+1].rep);
}

int
tekgundamage(int gun,int UNUSED(x),int UNUSED(y),int UNUSED(z),int UNUSED(hitsprite))
{
     int       damage;

     switch( gun ) {
     case 1:  damage= 2; break;
     case 4:  damage=20; break;
     default: damage= 2; break;
     }
     switch( difficulty ) {
     case 0:
     case 1:  damage+=4; break;
     case 2:  damage+=4; break;
     case 3:
     default:  damage+=10; break;
     }

     return(damage);
}

int
hasammo(int gun,short p)     // does player[p] have ammo for "gun"?
{
     switch (gun+1) {
     case GUN1FLAG:
          if( ammo1[p] > 0 ) {
               return(1);
          }
          break;
     case GUN2FLAG:
          if( ammo2[p] > 0 ) {
               return(1);
          }
          break;
     case GUN3FLAG:
          if( ammo3[p] > 0 ) {
               return(1);
          }
          break;
     case GUN4FLAG:
          if( ammo4[p] > 0 ) {
               return(1);
          }
          break;
     case GUN5FLAG:
          if( ammo5[p] > 0 ) {
               return(1);
          }
          break;
     case GUN6FLAG:
          if( ammo6[p] > 0 ) {
               return(1);
          }
          break;
     case GUN7FLAG:
          if( ammo7[p] > 0 ) {
               return(1);
          }
          break;
     case GUN8FLAG:
          if( ammo8[p] > 0 ) {
               return(1);
          }
          break;
     }
     return(0);
}

void
tekfiregun(int gun,short p)  // this kicks off an animation sequence
{
     if( fireseq[p] != 0 ) {
          return;
     }
     if( tekgunrep(gun) || ((oflags[p]&2048) == 0) ) {
//          if( hasammo(gun,p) ) {
               fireseq[p]=1;
               oneshot[p]=0;
//          }
     }
}

void
playerwoundplayer(short plrhit, short plr, char guntype)
{
     int       killed=0,damage=0,score=0;

     if( !validplayer(plrhit) || !validplayer(plr) ) {
          return;
     }

     switch( guntype ) {
     case 2:  score=5;  damage=48;   break;
     case 3:  score=10; damage=192;  break;
     case 4:  score=10; damage=512;  break;
     case 5:  score=15; damage=1024; break;
     case 6:  score=10; damage=24;   break;
     case 7:  score=10; damage=512;  break;
     default: score=5;  damage=32;   break;
     }

     killed=changehealth(plrhit,-damage);

     if( killed ) {
          changescore(plr, (score<<1));
     }
     else {
          changescore(plr, score);
     }
}

void
killscore(short hs, short snum, char guntype)
{
     int       ext=sprptr[hs]->extra;
     short     score;

     if( !validplayer(snum) ) {
          return;
     }
     if( !validext(ext) ) {
          return;
     }

     if( isanandroid(hs) ) {
          score=200;
     }
     else if( isahologram(hs) ) {
          score=100;
     }
     else {
          switch( sprXTptr[ext]->classification) {
          case CLASS_NULL:
               return;
          case CLASS_FCIAGENT:
               score=-500;
               break;
          case CLASS_CIVILLIAN:
               score=-500;
               break;
          case CLASS_SPIDERDROID:
               score=50;
               break;
          case CLASS_COP:
               score=-500;
               break;
          case CLASS_MECHCOP:
               score=-50;
               break;
          case CLASS_TEKBURNOUT:
               score=100;
               break;
          case CLASS_TEKGOON:
               score=200;
               break;
          case CLASS_ASSASSINDROID:
               score=300;
               break;
          case CLASS_SECURITYDROID:
               score=100;
               break;
          case CLASS_TEKBOSS:
               score=300;
               break;
          case CLASS_TEKLORD:
               score=500;
               break;
          }
          switch( guntype ) {
          case 0:
          case 1:
               if( score < 0 ) {
                    score=0;
               }
               else {
                    score+=(score<<1);
               }
               break;
          }
     }

     if( option[4] != 0 ) {
          score>>=4;
     }
     changescore(snum, score);
}

void
playerpainsound(int p)
{
     if( !validplayer(p) ) {
          crash("playerpainsnd: bad plr num");
     }

     if( krand_intercept(" GUN 341") < 1024 ) {
          playsound(S_PAIN1+(krand_intercept(" GUN 342")&1),posx[p],posy[p],0,ST_NOUPDATE);
     }
}

void
shootgun(short snum,int x,int y,int z,short daang,int dahoriz,
     short dasectnum,char guntype)
{
    vec3_t pos;
     hitdata_t hitinfo;
     hitdata_t bloodhitinfo;
     short daang2;
     int  cx,cy,i,j,daz2,xydist,zdist;
     int   rv,pnum;

     if( health[snum] <= 0 ) {
          return;
     }

     guntype+=1;
     switch (guntype) {
     case GUN1FLAG:
          cx=x+(sintable[(daang+2560+128)&2047]>>6);
          cy=y+(sintable[(daang+2048+128)&2047]>>6);
          j=jsinsertsprite(dasectnum, FORCEPROJECTILESTAT);
          if( j != -1 ) {
               fillsprite(j,cx,cy,z,128+2,-16,0,12,16,16,0,0,FORCEBALLPIC,daang,
                          sintable[(daang+2560-11)&2047]>>5, // -17 = travel 3 degrees left
                          sintable[(daang+2048-11)&2047]>>5, // -17 = travel 3 degrees left
                          100-dahoriz,snum+MAXSPRITES,dasectnum,FORCEPROJECTILESTAT,0,0,-1);
          }
          break;
     case GUN2FLAG:
          ammo2[snum]--;
          if( ammo2[snum] < 0 ) {
               ammo2[snum]=0;
               break;
          }
          daang2=daang;
          daz2=(100-dahoriz)*2000;

          pos.x = x; pos.y = y; pos.z = z;
          hitscan(&pos,dasectnum,sintable[(daang2+2560)&2047],
                  sintable[(daang2+2048)&2047],daz2,
                  &hitinfo,CLIPMASK1);

          x = pos.x; y = pos.y; z = pos.z;

          if( (hitinfo.sprite >= 0) && (sprptr[hitinfo.sprite]->statnum < MAXSTATUS)) {
               if( playerhit(hitinfo.sprite, &pnum) ) {
                    playerpainsound(pnum);
                    playerwoundplayer(pnum,snum,2);
               }
               else {
                    switch( sprptr[hitinfo.sprite]->picnum ) {
                    default:
                         rv=damagesprite(hitinfo.sprite,tekgundamage(guntype,x,y,z, hitinfo.sprite));
                         if( (rv == 1) && (goreflag) ) {
                              if( spewblood(hitinfo.sprite, hitinfo.z, daang) != 0 ) {
                                   sprptr[hitinfo.sprite]->cstat&=0xFEFE;  // non hitscan and non block
                                   // must preserve values from previous hitscan call,
                                   // thus the bloodxhitx, bloodwall, etc...

                                   vec3_t pos;
                                   pos.x = x; pos.y = y; pos.z = z;

                                   hitscan(&pos,dasectnum,sintable[(daang2+2560)&2047],
                                           sintable[(daang2+2048)&2047],daz2, &bloodhitinfo,CLIPMASK1);

                                   x = pos.x; y = pos.y; z = pos.z;

                                   if(bloodhitinfo.wall != -1 ) {
                                        bloodonwall(bloodhitinfo.wall,sprptr[hitinfo.sprite]->x,sprptr[hitinfo.sprite]->y,sprptr[hitinfo.sprite]->z,
                                                    sprptr[hitinfo.sprite]->sectnum,daang2, bloodhitinfo.x, bloodhitinfo.y, bloodhitinfo.z);
                                   }
                              }
                         }
                         if( rv == 1 ) {
                              killscore(hitinfo.sprite,snum,guntype);
                         }
                    break;
               }
               }
          }
          if(hitinfo.wall >= 0 ) {
               j=jsinsertsprite(hitinfo.sect, 3);
               if( j != -1 ) {
                    fillsprite(j,hitinfo.x,hitinfo.y,hitinfo.z+(8<<8),2,0,0,32,22,22,0,0,
                               EXPLOSION,daang,0,0,0,snum+MAXSPRITES,hitinfo.sect,3,63,0,-1);
                    movesprite((short)j,
                               -(((int)sintable[(512+daang)&2047]*TICSPERFRAME)<<4),
                               -(((int)sintable[daang]*TICSPERFRAME)<<4),0L,4L<<8,4L<<8,1);
                    playsound(S_RIC1, hitinfo.x, hitinfo.y,0,ST_NOUPDATE);
               }
          }
          break;
     case GUN3FLAG:
          ammo3[snum]--;
          if( ammo3[snum] < 0 ) {
               ammo3[snum]=0;
               break;
          }
          cx=x+(sintable[(daang+2560+256)&2047]>>6);
          cy=y+(sintable[(daang+2048+256)&2047]>>6);
          if( invaccutrak[snum] > 0 ) {
               j=jsinsertsprite(dasectnum, BOMBPROJECTILESTAT);
               if( j != -1 ) {
                    fillsprite(j,cx,cy,z+(4<<8),128,-16,0,32,16,16,0,0,BOMBPIC,daang,
                         sintable[(daang+2560-11)&2047]>>5, // -17 = travel 3 degrees left
                         sintable[(daang+2048-11)&2047]>>5, // -17 = travel 3 degrees left
                         100-dahoriz,snum,dasectnum,BOMBPROJECTILESTAT,0,0,-1);
                    sprptr[j]->owner=snum;
               }
          }
          else {
               j=jsinsertsprite(dasectnum, BOMBPROJECTILESTAT2);
               if( j != -1 ) {
                    fillsprite(j,cx,cy,z+(4<<8),128,-16,0,32,16,16,0,0,BOMBPIC,daang,
                         sintable[(daang+2560-11)&2047]>>5, // -17 = travel 3 degrees left
                         sintable[(daang+2048-11)&2047]>>5, // -17 = travel 3 degrees left
                         100-dahoriz,snum,dasectnum,BOMBPROJECTILESTAT2,0,0,-1);
                    sprptr[j]->owner=snum;
               }
          }
          break;
     case GUN4FLAG:
          ammo4[snum]--;
          if( ammo4[snum] < 0 ) {
               ammo4[snum]=0;
               break;
          }
          cx=x+(sintable[(daang+2560+128)&2047]>>6);
          cy=y+(sintable[(daang+2048+128)&2047]>>6);
          j=jsinsertsprite(dasectnum, DARTPROJECTILESTAT);
          if( j != -1 ) {
               fillsprite(j,cx,cy,z+(5<<8),128,-35,0,12,16,16,0,0, 338 ,daang,
                    sintable[(daang+2560-6)&2047]>>5, // -17 = travel 3 degrees left
                    sintable[(daang+2048-6)&2047]>>5, // -17 = travel 3 degrees left
                    100-dahoriz,snum,dasectnum,DARTPROJECTILESTAT,0,0,-1);
               sprptr[j]->owner=snum;
               playsound(S_RIC1,cx,cy,0,ST_NOUPDATE);

          }
          break;
     case GUN5FLAG:
          daang2=daang;
          daz2=(100-dahoriz)*2000;

          pos.x = x; pos.y = y; pos.z = z;

          hitscan(&pos,dasectnum,sintable[(daang2+2560)&2047],
                  sintable[(daang2+2048)&2047],daz2,
                  &hitinfo,CLIPMASK1);

          x = pos.x; y = pos.y; z = pos.z;

          if( (hitinfo.sprite >= 0) && (sprptr[hitinfo.sprite]->statnum < MAXSTATUS)) {
               xydist=klabs(posx[snum]-sprptr[hitinfo.sprite]->x)+klabs(posy[snum]-sprptr[hitinfo.sprite]->y);
               zdist=klabs( (posz[snum]>>8)-((sprptr[hitinfo.sprite]->z>>8)-(tilesiz[sprptr[hitinfo.sprite]->picnum].y>>1)) );
               if( (xydist > 768) || (zdist > 50) ) {
                    break;
               }
               if( playerhit(hitinfo.sprite, &pnum) ) {
                    playerpainsound(pnum);
                    playerwoundplayer(pnum,snum,5);
               }
               else {
                    rv=damagesprite(hitinfo.sprite,tekgundamage(guntype,x,y,z, hitinfo.sprite));
                    if( rv == 1 ) {
                         killscore(hitinfo.sprite, snum, guntype);
                    }
               }
          }
          break;
     case GUN6FLAG:
          ammo6[snum]--;
          if( ammo6[snum] < 0 ) {
               ammo6[snum]=0;
               break;
          }
          daang2=daang;
          daz2=(100-dahoriz)*2000;

          pos.x = x; pos.y = y; pos.z = z;
          hitscan(&pos,dasectnum,sintable[(daang2+2560)&2047], sintable[(daang2+2048)&2047],daz2, &hitinfo,CLIPMASK1);

          x = pos.x; y = pos.y; z = pos.z;

          if( (hitinfo.sprite >= 0) && (sprptr[hitinfo.sprite]->statnum < MAXSTATUS)) {
               xydist=klabs(posx[snum]-sprptr[hitinfo.sprite]->x)+klabs(posy[snum]-sprptr[hitinfo.sprite]->y);
               zdist=klabs( (posz[snum]>>8)-((sprptr[hitinfo.sprite]->z>>8)-(tilesiz[sprptr[hitinfo.sprite]->picnum].y>>1)) );
               if( (xydist > 2560) || (zdist > 576) ) {
                    break;
               }
               if( playerhit(hitinfo.sprite, &pnum) ) {
                    if( playervirus(pnum, FIREPIC) ) {
                         playerwoundplayer(pnum,snum,6);
                    }
               }
               else {
                    attachvirus(hitinfo.sprite, FIREPIC);
               }
          }
          break;
     case GUN7FLAG:
          ammo7[snum]--;
          if( ammo7[snum] < 0 ) {
               ammo7[snum]=0;
               break;
          }
          for (i=0 ; i < 3 ; i++) {
               cx=x+(sintable[(daang+2560+256)&2047]>>6);
               cy=y+(sintable[(daang+2048+256)&2047]>>6);
               j=jsinsertsprite(dasectnum,ROCKETPROJECTILESTAT);
               if (j != -1) {
                    fillsprite(j,cx,cy,z+(4<<8),128,-24,0,12,16,16,0,0,335,daang,
                         sintable[(daang+2560-11)&2047]>>(2+i),
                         sintable[(daang+2048-11)&2047]>>(2+i),
                         (100-dahoriz)-(i<<2),
                         snum,dasectnum,ROCKETPROJECTILESTAT,0,0,-1);
               sprptr[j]->owner=snum;
               }
          }
          break;
     case GUN8FLAG:
          ammo8[snum]--;
          if( ammo8[snum] < 0 ) {
               ammo8[snum]=0;
               break;
          }
          cx=x+(sintable[(daang+2560)&2047]>>6);
          cy=y+(sintable[(daang+2048)&2047]>>6);
          j=jsinsertsprite(dasectnum, MATRIXPROJECTILESTAT);
          if( j != -1 ) {
               fillsprite(j,cx,cy,z+(5<<8),128,-35,0,12,16,16,0,0,3765,daang,
                    sintable[(daang+2560)&2047]>>5,
                    sintable[(daang+2048)&2047]>>5,
                    100-dahoriz,snum,dasectnum,MATRIXPROJECTILESTAT,0,0,-1);
               sprptr[j]->owner=snum;
          }
          break;
     default:
          break;
    }

    if( guntype != GUN1FLAG )
          playergunshot(snum);
}

#define   DIEFRAMETIME   (160/(JAKETWITCHPIC-JAKEDEATHPIC))

short dieframe[MAXPLAYERS],
     firepicdelay[MAXPLAYERS];

void
tekanimweap(int gun,short p)
{
     int  ammo,firekey,fseq,seq,tics;
     int usegun;
     struct guntype *gunptr;

     if (gun < 0 || gun >= NUMWEAPONS) {
          crash("gun589: Invalid gun number (%d,p=%d)",gun,p);
     }
     if (option[4] != 0) {
          if (health[p] < 0 && dieframe[p] == 0) {
               dieframe[p]=TICSPERFRAME;
          }
          else if (dieframe[p] > 0) {
               sprptr[playersprite[p]]->picnum=
                    JAKEDEATHPIC+(dieframe[p]/DIEFRAMETIME);
               dieframe[p]+=TICSPERFRAME;
               return;
          }
          else {
               if ((syncbits[p]&2048) && firepicdelay[p] == 0) {
                    sprptr[playersprite[p]]->picnum=JAKEATTACKPIC;
                    firepicdelay[p]=16;
               }
               else if (firepicdelay[p] > 0) {
                    firepicdelay[p]--;
                    if (firepicdelay[p] <= 0) {
                         firepicdelay[p]=0;
                         sprptr[playersprite[p]]->picnum=JAKEWALKPIC;
                    }
               }
               if (firepicdelay[p] == 0 && syncvel[p] == 0 && syncsvel[p] == 0) {
                    sprptr[playersprite[p]]->picnum=JAKESTANDPIC;
               }
          }
     }
     if ((seq=fireseq[p]) == 0) {
          lastgun[p]=gun;
          return;
     }
     usegun=lastgun[p];
     if (usegun != gun) {
          gunptr=&guntype[usegun];
          fseq=gunptr->firepic-gunptr->pic;
          if (firedonetics[p] >= 0) {
               firedonetics[p]=2;
          }
          firekey=0;
     }
     else {
          firekey=(syncbits[p]&2048);
          if (firekey != 0) {
               drawweap[p]=1;
          }
     }
     if( (firekey == 0) && ((syncbits[p]&128) != 0) && firedonetics[p] == 1) {
//         ((firedonetics[p] == 1) || !hasammo(usegun,p)) ) {
          firedonetics[p]=2;
     }
     if (firedonetics[p] == 2) {
          firedonetics[p]=-1;
          drawweap[p]=0;
          if (firedonetics[p] <= 0) {
               gunptr=&guntype[usegun];
               fseq=gunptr->firepic-gunptr->pic;
               fireseq[p]=fseq;
          }
     }
     gunptr=&guntype[usegun];
     fseq=gunptr->firepic-gunptr->pic;
     if (seq-1 >= fseq) {
          tics=gunptr->tics;
     }
     else {
          tics=DRAWWEAPSPEED;
     }
     if (lockclock >= lastchaingun[p]+tics) {
          lastchaingun[p]=lockclock;
          ammo=hasammo(usegun,p);
          if (seq-1 >= fseq && ammo) {
               if (gunptr->action[seq-fseq-1]) {
                    switch( gun+1 ) {
//jsa friday
                         case 1:
                              if(option[4] != 0)
                                   playsound(S_WEAPON1 ,posx[p],posy[p],0,ST_NOUPDATE);
                              else
                                   playsound(S_WEAPON1 ,0,0,0,ST_IMMEDIATE);
                              break;
                         case 2:
                              if(option[4] != 0)
                                   playsound(S_WEAPON2 ,posx[p],posy[p],0,ST_NOUPDATE);
                              else
                                   playsound(S_WEAPON2 ,0,0,0,ST_IMMEDIATE);
                              break;
                         case 3:
                              if(option[4] != 0)
                                   playsound(S_WEAPON3 ,posx[p],posy[p],0,ST_NOUPDATE);
                              else
                                   playsound(S_WEAPON3 ,0,0,0,ST_IMMEDIATE);
                              break;
                         case 4:
                              if(option[4] != 0)
                                   playsound(S_WEAPON4 ,posx[p],posy[p],0,ST_NOUPDATE);
                              else
                                   playsound(S_WEAPON4 ,0,0,0,ST_IMMEDIATE);
                              break;
                         case 5:
                              if(option[4] != 0)
                                   playsound(S_WEAPON5 ,posx[p],posy[p],0,ST_NOUPDATE);
                              else
                                   playsound(S_WEAPON5 ,0,0,0,ST_IMMEDIATE);
                              break;
                         case 6:
                              if(option[4] != 0)
                                   playsound(S_WEAPON6 ,posx[p],posy[p],0,ST_NOUPDATE);
                              else
                                   playsound(S_WEAPON6 ,0,0,0,ST_IMMEDIATE);
                              break;
                         case 7:
                              if(option[4] != 0)
                                   playsound(S_WEAPON7 ,posx[p],posy[p],0,ST_NOUPDATE);
                              else
                                   playsound(S_WEAPON7 ,0,0,0,ST_IMMEDIATE);
                              break;
                         case 8:
                              playsound(S_WEAPON8 ,0,0,0,ST_IMMEDIATE);
                              break;
                         default:
                              break;

                    }
                    shootgun(p,posx[p],posy[p],posz[p],ang[p],horiz[p],
                              cursectnum[p],usegun);
                    if (option[4] != 0) {
                         sprptr[playersprite[p]]->picnum=JAKEATTACKPIC+1;
                         firepicdelay[p]=8;
                    }
               }
               if (seq-1 >= gunptr->endfirepic-gunptr->pic) {
                    fireseq[p]=fseq+1;
                    return;
               }
               if (firekey == 0) {
                    firedonetics[p]=1;
                    fireseq[p]=fseq;
                    return;
               }
               else {
                    firedonetics[p]=0;
               }
          }
          if (drawweap[p] != 0) {
               if (ammo || seq < fseq) {
                    seq++;
               }
               else {
                    if (firekey == 0) {
                         firedonetics[p]=1;
                    }
               }
          }
          else if (firedonetics[p] < 0) {
               seq--;
          }
          fireseq[p]=seq;
     }
}

int
tekexplodebody(int i)
{
     int  j,k,r,ext;

     ext=sprptr[i]->extra;
     if( (!validext(ext)) || (goreflag == 0) ) {
          return(0);
     }
     switch( sprXTptr[ext]->basepic ) {
     case RUBWALKPIC:
     case JAKEWALKPIC:
     case COP1WALKPIC:
     case ANTWALKPIC:
     case SARAHWALKPIC:
     case MAWALKPIC:
     case DIWALKPIC:
     case ERWALKPIC:
     case SAMWALKPIC:
     case FRGWALKPIC:
     case SUNGWALKPIC:
     case COWWALKPIC:
     case COPBWALKPIC:
     case NIKAWALKPIC:
     case REBRWALKPIC:
     case TRENWALKPIC:
     case WINGWALKPIC:
     case HALTWALKPIC:
     case REDHWALKPIC:
     case ORANWALKPIC:
     case BLKSWALKPIC:
     case SFROWALKPIC:
     case SSALWALKPIC:
     case SGOLWALKPIC:
     case SWATWALKPIC:
          break;
     default:
          return(0);
     }

     r=(krand_intercept(" GUN 787")%72)+8;
     for (k=0 ; k < r ; k++) {
          j=jsinsertsprite(sprptr[i]->sectnum,MOVEBODYPARTSSTAT);
          sprptr[j]->x=sprptr[i]->x;
          sprptr[j]->y=sprptr[i]->y;
          sprptr[j]->z=sprptr[i]->z+(8<<8);
          sprptr[j]->cstat=0;
          sprptr[j]->shade=0;
          sprptr[j]->pal=0;
          sprptr[j]->xrepeat=24;
          sprptr[j]->yrepeat=24;
          sprptr[j]->ang=sprptr[i]->ang;
          sprptr[j]->xvel=(krand_intercept(" GUN 799")&511)-256;
          sprptr[j]->yvel=(krand_intercept(" GUN 800")&511)-256;
          sprptr[j]->zvel=-((krand_intercept(" GUN 801")&8191)+4096);
          sprptr[j]->owner=sprptr[i]->owner;
          sprptr[j]->clipdist=32;
          sprptr[j]->lotag=360;
          sprptr[j]->hitag=0;
          switch (k) {
          case 0:
               sprptr[j]->picnum=GOREHEAD;
               break;
          case 1:
          case 10:
               sprptr[j]->picnum=GOREARM;
               break;
          case 5:
          case 15:
               sprptr[j]->picnum=GORELEG;
               break;
          default:
               sprptr[j]->picnum=GOREBLOOD;
               break;
          }
     }
     playsound(S_GORE1+(krand_intercept(" GUN 823")%2), sprptr[i]->x,sprptr[i]->y, 0, ST_NOUPDATE);

     return(1);
}

void
gunstatuslistcode(void)
{
     short     hitobject,hitsprite,ext;
     int      i,nexti,dax,day,daz,j;
     int       pnum,rv;

     i=headspritestat[FORCEPROJECTILESTAT];   //moving force ball
     while (i >= 0) {
          nexti=nextspritestat[i];
          dax=((((int)sprptr[i]->xvel)*TICSPERFRAME)<<11);
          day=((((int)sprptr[i]->yvel)*TICSPERFRAME)<<11);
          daz=((((int)sprptr[i]->zvel)*TICSPERFRAME)<<3);
          hitobject=movesprite((short)i,dax,day,daz,4<<8,4<<8,1);
          if( (hitobject&0xC000) == 49152 ) {  // hit a sprite
               hitsprite=hitobject&0x0FFF;
               ext=sprptr[hitsprite]->extra;
               if( validext(ext) ) {
                    switch( sprXTptr[ext]->walkpic ) {
                    case RUBWALKPIC:
                    case FRGWALKPIC:
                    case COP1WALKPIC:
                    case ANTWALKPIC:
                    case SARAHWALKPIC:
                    case MAWALKPIC:
                    case DIWALKPIC:
                    case ERWALKPIC:
                    case SAMWALKPIC:
                    case SUNGWALKPIC:
                    case COWWALKPIC:
                    case COPBWALKPIC:
                    case NIKAWALKPIC:
                    case REBRWALKPIC:
                    case TRENWALKPIC:
                    case WINGWALKPIC:
                    case HALTWALKPIC:
                    case REDHWALKPIC:
                    case ORANWALKPIC:
                    case BLKSWALKPIC:
                    case SFROWALKPIC:
                    case SSALWALKPIC:
                    case SGOLWALKPIC:
                    case SWATWALKPIC:
                         attachvirus(hitsprite, FORCEBALLPIC);
                         break;
                    default:
                         forceexplosion(i);
                         break;
                    }
                    jsdeletesprite(( short)i);
               }
               else {
                    forceexplosion(i);
                    jsdeletesprite((short)i);
               }
          }
          else if( hitobject != 0 ) {
               forceexplosion(i);
               jsdeletesprite((short)i);
          }

          i=nexti;
     }

     i=headspritestat[ROCKETPROJECTILESTAT];
     while (i >= 0) {
          nexti=nextspritestat[i];

          dax=((((int)sprptr[i]->xvel)*TICSPERFRAME)<<10);
          day=((((int)sprptr[i]->yvel)*TICSPERFRAME)<<10);
          daz=((((int)sprptr[i]->zvel)*TICSPERFRAME)<<3);

          hitobject=movesprite((short)i,dax,day,daz,4<<8,4<<8,1);
          if( (hitobject&0xC000) == 49152 ) {  // hit a sprite
               hitsprite=hitobject&0x0FFF;
               if( playerhit(hitsprite, &pnum) ) {
                    playerpainsound(pnum);
                    playerwoundplayer(pnum,sprptr[i]->owner,7);
               }
               else if( sprptr[i]->picnum != sprptr[hitsprite]->picnum ) {
                    if( isahologram(hitsprite) ) {
                         showmessage("WAS A HOLOGRAM");
                         killscore(hitsprite, sprptr[i]->owner, 3);
                         changespritestat(hitsprite, VANISH);
                         //jsdeletesprite(hitsprite);
                    }
                    else if( isanandroid(hitsprite) ) {
                         showmessage("WAS AN ANDROID");
                         killscore(hitsprite, sprptr[i]->owner, 3);
                         androidexplosion(hitsprite);
                         changespritestat(hitsprite, VANISH);
                         //jsdeletesprite(hitsprite);
                    }
                    else {
                         blastmark(hitsprite);
                         rv=damagesprite(hitsprite, 500);
                         if( rv == 1 ) {
                              killscore(hitsprite,sprptr[i]->owner,3);
                         }
                    }
               }
          }
          if( hitobject != 0 ) {
               bombexplosion(i);
               jsdeletesprite((short)i);
          }

          i=nexti;
     }

     i=headspritestat[MATRIXPROJECTILESTAT];
     while (i >= 0) {
          nexti=nextspritestat[i];

          dax=((((int)sprptr[i]->xvel)*TICSPERFRAME)<<12);
          day=((((int)sprptr[i]->yvel)*TICSPERFRAME)<<12);
          daz=((((int)sprptr[i]->zvel)*TICSPERFRAME)<<4);

          hitobject=movesprite((short)i,dax,day,daz,4<<8,4<<8,1);
          if( (hitobject&0xC000) == 49152 ) {  // hit a sprite
               hitsprite=hitobject&0x0FFF;
               if( !playerhit(hitsprite, &pnum) ) {
                    rv=damagesprite(hitsprite, 500);
                    if( rv == 1 ) {
                         killscore(hitsprite,sprptr[i]->owner,8);
                    }
               }
          }
          if( hitobject != 0 ) {
               jsdeletesprite((short)i);
          }

          i=nexti;
     }

     i=headspritestat[BOMBPROJECTILESTAT];
     while (i >= 0) {
          nexti=nextspritestat[i];

          dax=((((int)sprptr[i]->xvel)*TICSPERFRAME)<<12);
          day=((((int)sprptr[i]->yvel)*TICSPERFRAME)<<12);
          daz=((((int)sprptr[i]->zvel)*TICSPERFRAME)<<4);

          hitobject=movesprite((short)i,dax,day,daz,4<<8,4<<8,1);
          if( (hitobject&0xC000) == 49152 ) {  // hit a sprite
               hitsprite=hitobject&0x0FFF;
               if( playerhit(hitsprite, &pnum) ) {
                    playerpainsound(pnum);
                    playerwoundplayer(pnum,sprptr[i]->owner,3);
               }
               else if( sprptr[i]->picnum != sprptr[hitsprite]->picnum ) {
                    if( isahologram(hitsprite) ) {
                         showmessage("WAS A HOLOGRAM");
                         killscore(hitsprite, sprptr[i]->owner, 3);
                         changespritestat(hitsprite, VANISH);
                         //jsdeletesprite(hitsprite);
                    }
                    else if( isanandroid(hitsprite) ) {
                         showmessage("WAS AN ANDROID");
                         killscore(hitsprite, sprptr[i]->owner, 3);
                         androidexplosion(hitsprite);
                         changespritestat(hitsprite, VANISH);
                         //jsdeletesprite(hitsprite);
                    }
                    else {
                         blastmark(hitsprite);
                         rv=damagesprite(hitsprite, 500);
                         if( rv == 1 ) {
                              killscore(hitsprite,sprptr[i]->owner,3);
                         }
                    }
               }
          }
          if( hitobject != 0 ) {
               bombexplosion(i);
               jsdeletesprite((short)i);
          }

          i=nexti;
     }

     i=headspritestat[BOMBPROJECTILESTAT2];
     while (i >= 0) {
          nexti=nextspritestat[i];

          sprptr[i]->xvel+=( ((krand_intercept(" GUN1025")&64)-32)>>1 );
          sprptr[i]->yvel+=( ((krand_intercept(" GUN1026")&64)-32)>>1 );
          sprptr[i]->zvel+=( ((krand_intercept(" GUN1027")&31)-16)>>1 );

          dax=((((int)sprptr[i]->xvel)*TICSPERFRAME)<<12);
          day=((((int)sprptr[i]->yvel)*TICSPERFRAME)<<12);
          daz=((((int)sprptr[i]->zvel)*TICSPERFRAME)<<4);

          hitobject=movesprite((short)i,dax,day,daz,4<<8,4<<8,1);
          if( (hitobject&0xC000) == 49152 ) {  // hit a sprite
               hitsprite=hitobject&0x0FFF;
               if( playerhit(hitsprite, &pnum) ) {
                    playerpainsound(pnum);
                    playerwoundplayer(pnum,sprptr[i]->owner,3);
               }
               else if( sprptr[i]->picnum != sprptr[hitsprite]->picnum ) {
                    if( isahologram(hitsprite) ) {
                         showmessage("WAS A HOLOGRAM");
                         killscore(hitsprite, sprptr[i]->owner, 3);
                         changespritestat(hitsprite, VANISH);
                         //jsdeletesprite(hitsprite);
                    }
                    else if( isanandroid(hitsprite) ) {
                         showmessage("WAS AN ANDROID");
                         killscore(hitsprite, sprptr[i]->owner, 3);
                         androidexplosion(hitsprite);
                         changespritestat(hitsprite, VANISH);
                         //jsdeletesprite(hitsprite);
                    }
                    else {
                         blastmark(hitsprite);
                         rv=damagesprite(hitsprite, 500);
                         if( rv == 1 ) {
                              killscore(hitsprite,sprptr[i]->owner,3);
                         }
                    }
               }
          }
          if( hitobject != 0 ) {
               bombexplosion(i);
               jsdeletesprite((short)i);
          }

          i=nexti;
     }

     i=headspritestat[DARTPROJECTILESTAT];
     while (i >= 0) {
          nexti=nextspritestat[i];
          dax=((((int)sprptr[i]->xvel)*TICSPERFRAME)<<13);
          day=((((int)sprptr[i]->yvel)*TICSPERFRAME)<<13);
          daz=((((int)sprptr[i]->zvel)*TICSPERFRAME)<<5);

          hitobject=movesprite((short)i,dax,day,daz,4<<8,4<<8,1);
          if( (hitobject&0xC000) == 49152 ) {  // hit a sprite
               hitsprite=hitobject&0x0FFF;
               if( playerhit(hitsprite, &pnum) ) {
                    playerpainsound(pnum);
                    playerwoundplayer(pnum,sprptr[i]->owner,4);
               }
               else if( sprptr[i]->picnum != sprptr[hitsprite]->picnum ) {
                    if( isahologram(hitsprite) ) {
                         showmessage("WAS A HOLOGRAM");
                         killscore(hitsprite, sprptr[i]->owner, 4);
                         changespritestat(hitsprite, VANISH);
                         //jsdeletesprite(hitsprite);
                    }
                    else if( isanandroid(hitsprite) ) {
                         showmessage("WAS AN ANDROID");
                         killscore(hitsprite, sprptr[i]->owner, 4);
                         androidexplosion(hitsprite);
                         changespritestat(hitsprite, VANISH);
                         //jsdeletesprite(hitsprite);
                    }
                    else if( tekexplodebody(hitsprite) ) {
                         missionaccomplished(hitsprite);
                         killscore(hitsprite, sprptr[i]->owner, 4);
                         changespritestat(hitsprite, VANISH);
                         //jsdeletesprite(hitsprite);
                    }
                    else {
                         rv=damagesprite(hitsprite, 500);
                         if( rv == 1 ) {
                              killscore(hitsprite,sprptr[i]->owner,3);
                         }
                    }
               }
          }
          if( hitobject != 0 ) {
               j=jsinsertsprite(sprite[i].sectnum, 3);
               if( j != -1 ) {
                    fillsprite(j,sprptr[i]->x,sprptr[i]->y,sprptr[i]->z+(8<<8),0,-4,0,32,
                         64,64,0,0,
                         EXPLOSION,sprptr[i]->ang,0,0,0,i,sprptr[i]->sectnum,3,63,0,0);
               }
               jsdeletesprite((short)i);
          }

          i=nexti;
     }

     i=headspritestat[MOVEBODYPARTSSTAT];    //flying body parts (gore option)
     while (i >= 0) {
          nexti=nextspritestat[i];
          sprptr[i]->x+=((sprptr[i]->xvel*TICSPERFRAME)>>5);
          sprptr[i]->y+=((sprptr[i]->yvel*TICSPERFRAME)>>5);
          sprptr[i]->z+=((sprptr[i]->zvel*TICSPERFRAME)>>5);
          sprptr[i]->zvel+=(TICSPERFRAME<<7);
          if (sprptr[i]->z < sectptr[sprptr[i]->sectnum]->ceilingz+(4<<8)) {
               sprptr[i]->z=sectptr[sprptr[i]->sectnum]->ceilingz+(4<<8);
               sprptr[i]->zvel=-(sprptr[i]->zvel>>1);
          }
          if (sprptr[i]->z > sectptr[sprptr[i]->sectnum]->floorz-(4<<8)) {
               sprptr[i]->z=sectptr[sprptr[i]->sectnum]->floorz-(4<<8);
               if (sprptr[i]->picnum == GOREBLOOD) {
                    sprptr[i]->xvel=0;
                    sprptr[i]->yvel=0;
                    sprptr[i]->zvel=0;
                    sprptr[i]->cstat|=0x20;
               }
               else {
                    sprptr[i]->zvel=-(sprptr[i]->zvel>>1);
               }
          }
          sprptr[i]->lotag-=TICSPERFRAME;
          if (sprptr[i]->lotag < 0) {
               jsdeletesprite(i);
          }
          i=nexti;
     }
}

int       matgunpic;

void
tekdrawgun(int gun,short p)
{
     int  pic,x,apic;

     if (fireseq[p] == 0) {
          pic=guntype[gun].pic;
          return;
     }
     apic=AIMPIC;
     if( difficulty <= 1 )
          apic=BIGAIMPIC;
     if( (toggles[TOGGLE_RETICULE]) && (dimensionmode[myconnectindex] == 3) ) {
          overwritesprite(windowxy1.x+((windowxy2.x-windowxy1.x)>>1),
                          windowxy1.y+((windowxy2.y-windowxy1.y)>>1),apic,16,0x01,0);
     }
     gun=lastgun[p];
     if( firedonetics[p] > 0 ) {
          pic=guntype[gun].firepic;
     }
     else {
          pic=guntype[gun].pic+fireseq[p]-1;
     }
     x=160L;

     if( pic == 3981 ) {
          if( syncsvel[p] < 0 ) {
               overwritesprite(x,100L,3990,sectptr[cursectnum[p]]->floorshade,1|2,0);
               return;
          }
          else if( syncsvel[p] > 0 ) {
               overwritesprite(x,100L,3986,sectptr[cursectnum[p]]->floorshade,1|2,0);
               return;
          }
          else if( syncangvel[p] < 0 ) {
               overwritesprite(x,100L,3985,sectptr[cursectnum[p]]->floorshade,1|2,0);
               return;
          }
          else if( syncangvel[p] > 0 ) {
               overwritesprite(x,100L,3989,sectptr[cursectnum[p]]->floorshade,1|2,0);
               return;
          }
          else if( (syncbits[p]&1) != 0 ) {
               overwritesprite(x,100L,3994+((syncbits[p]&256)==0),sectptr[cursectnum[p]]->floorshade,1|2,0);
               return;
          }
          else if( (syncbits[p]&2) != 0 ) {
               overwritesprite(x,100L,3998+((syncbits[p]&256)==0),sectptr[cursectnum[p]]->floorshade,1|2,0);
               return;
          }
     }

     if( (syncvel[p]|syncsvel[p]) != 0 ) {
          switch( pic ) {
          case GUN01FIRESTART:
          case GUN02FIRESTART:
          case GUN03FIRESTART:
          case GUN04FIRESTART:
          case GUN05FIRESTART:
          case GUN06FIRESTART:
          case GUN07FIRESTART:
          case GUN08FIRESTART:
               bobtics+=( 1 + (((syncbits[p]&256)>0)<<2) );
               if( bobtics > TICSPERFRAME ) {
                    bobtics=0;
                    gunbob++;
                    if( gunbob > 9 )
                         gunbob=0;
               }
               break;
          default:
               gunbob=0;
               break;
          }
     }
     overwritesprite(x+gunbobx[gunbob],100L+gunboby[gunbob],pic,sectptr[cursectnum[p]]->floorshade,1|2,0);
}

int
tekhasweapon(int gun,short snum)
{
     int       hasit=0;

     if( mission == 7 ) {
          if( gun != 7 ) {
               if( snum == screenpeek ) {
                    notininventory=1;
               }
               return(0);
          }
          else {
               return(1);
          }
     }
     else {
          if( gun == 7 ) {
               if( snum == screenpeek ) {
                    showmessage("ONLY IN MATRIX");
               }
               return(0);
          }
     }

     hasit=(weapons[snum]&flags32[gun+1]);
     if( hasit )
          return(1);

     notininventory=1;
     return(0);
}

void
tekgunsave(int fil)
{
     write(fil,fireseq,MAXPLAYERS*sizeof(int));
     write(fil,ammo1,MAXPLAYERS*sizeof(short));
     write(fil,ammo2,MAXPLAYERS*sizeof(short));
     write(fil,ammo3,MAXPLAYERS*sizeof(short));
     write(fil,ammo4,MAXPLAYERS*sizeof(short));
     write(fil,ammo5,MAXPLAYERS*sizeof(short));
     write(fil,ammo6,MAXPLAYERS*sizeof(short));
     write(fil,ammo7,MAXPLAYERS*sizeof(short));
     write(fil,ammo8,MAXPLAYERS*sizeof(short));
     write(fil,weapons,MAXPLAYERS*sizeof(int));
     write(fil,firedonetics,MAXPLAYERS*sizeof(int));
     write(fil,lastgun,MAXPLAYERS*sizeof(int));
     write(fil,&goreflag,sizeof(int));
}

void
tekgunload(int fil)
{
     read(fil,fireseq,MAXPLAYERS*sizeof(int));
     read(fil,ammo1,MAXPLAYERS*sizeof(short));
     read(fil,ammo2,MAXPLAYERS*sizeof(short));
     read(fil,ammo3,MAXPLAYERS*sizeof(short));
     read(fil,ammo4,MAXPLAYERS*sizeof(short));
     read(fil,ammo5,MAXPLAYERS*sizeof(short));
     read(fil,ammo6,MAXPLAYERS*sizeof(short));
     read(fil,ammo7,MAXPLAYERS*sizeof(short));
     read(fil,ammo8,MAXPLAYERS*sizeof(short));
     read(fil,weapons,MAXPLAYERS*sizeof(int));
     read(fil,firedonetics,MAXPLAYERS*sizeof(int));
     read(fil,lastgun,MAXPLAYERS*sizeof(int));
     read(fil,&goreflag,sizeof(int));
}

repo_name: orochi/nblood

license: mit


code:
/***************************************************************************
 *   TEKLDSV.C - load and save game, perhaps will develop so can go back   *
 *               and forth beteen maps but I dont want to                  *
 *                                                                         *
 ***************************************************************************/

#include "build.h"
#include "names.h"
#include "mmulti.h"

#include "tekwar.h"

#ifdef COMPRESSION
void
writerle(int fil,void *data,int size)
{
     unsigned short n;
     int  i;
     char c,*p;

     if (size > 4) {
          p=(char *)data;
          i=0;
          while (i < size) {
               n=1;
               c=p[i++];
               while (c == p[i] && i < size) {
                    n++;
                    i++;
               }
               write(fil,&n,sizeof(short));
               write(fil,&c,sizeof(char));
          }
     }
     else {
          write(fil,data,size);
     }
}
#endif

#ifdef COMPRESSION
void
readrle(int fil,void *data,int size)
{
     unsigned short n;
     int  i;
     char c,*p;

     if (size > 4) {
          p=(char *)data;
          i=0;
          while (i < size) {
               read(fil,&n,sizeof(short));
               read(fil,&c,sizeof(char));
               while (n > 0) {
                    p[i++]=c;
                    n--;
               }
          }
     }
     else {
          read(fil,data,size);
     }
}
#endif

int
loadgame(int loadno)
{
     int      i, fil;
     short     dummyscreensize;
     int       rv;
     intptr_t tmpanimates[MAXANIMATES];
     char filename[BMAX_PATH];

     sprintf(filename, "savegam%d.tek", loadno);
     if ((fil = open(filename, O_BINARY | O_RDWR, S_IREAD)) == -1)
     {
         return -1;
     }

     lseek(fil, 0, SEEK_SET);

     read(fil,loadsavenames[loadno-1],MAXLOADSAVESIZE);

     read(fil,boardfilename,80);
     // setup new map
     newgame(boardfilename);

     read(fil,&numplayers,2);
     read(fil,&myconnectindex,2);
     read(fil,&connecthead,2);
     read(fil,connectpoint2,MAXPLAYERS<<1);

     // Make sure palookups get set, sprites will get overwritten later
     for(i=connecthead;i>=0;i=connectpoint2[i]) initplayersprite((short)i);

     read(fil,posx,MAXPLAYERS<<2);
     read(fil,posy,MAXPLAYERS<<2);
     read(fil,posz,MAXPLAYERS<<2);
     read(fil,horiz,MAXPLAYERS<<2);
     read(fil,zoom,MAXPLAYERS<<2);
     read(fil,hvel,MAXPLAYERS<<2);
     read(fil,ang,MAXPLAYERS<<1);
     read(fil,cursectnum,MAXPLAYERS<<1);
     read(fil,ocursectnum,MAXPLAYERS<<1);
     read(fil,playersprite,MAXPLAYERS<<1);
     read(fil,deaths,MAXPLAYERS<<1);
     read(fil,lastchaingun,MAXPLAYERS<<2);
     read(fil,health,MAXPLAYERS<<2);
     read(fil,score,MAXPLAYERS<<2);
     read(fil,saywatchit,MAXPLAYERS<<2);
     read(fil,numbombs,MAXPLAYERS<<1);
     read(fil,&dummyscreensize,2);
     read(fil,oflags,MAXPLAYERS<<1);
     read(fil,dimensionmode,MAXPLAYERS);
     read(fil,revolvedoorstat,MAXPLAYERS);
     read(fil,revolvedoorang,MAXPLAYERS<<1);
     read(fil,revolvedoorrotang,MAXPLAYERS<<1);
     read(fil,revolvedoorx,MAXPLAYERS<<2);
     read(fil,revolvedoory,MAXPLAYERS<<2);

     read(fil,&numsectors,2);
     read(fil,sector,sizeof(sectortype)*numsectors);

     read(fil,&numwalls,2);
     read(fil,wall,sizeof(walltype)*numwalls);

     // Store all sprites (even holes) to preserve indeces
     read(fil,sprite,sizeof(spritetype)*MAXSPRITES);
     read(fil,headspritesect,(MAXSECTORS+1)<<1);
     read(fil,prevspritesect,MAXSPRITES<<1);
     read(fil,nextspritesect,MAXSPRITES<<1);
     read(fil,headspritestat,(MAXSTATUS+1)<<1);
     read(fil,prevspritestat,MAXSPRITES<<1);
     read(fil,nextspritestat,MAXSPRITES<<1);

     read(fil,&vel,4);
     read(fil,&svel,4);
     read(fil,&angvel,4);

     read(fil,&locselectedgun,4);
     read(fil,&locvel,1);
     read(fil,&olocvel,1);
     read(fil,&locsvel,2);                                   // Les 09/28/95
     read(fil,&olocsvel,2);                                  // Les 09/28/95
     read(fil,&locangvel,2);                                 // Les 09/28/95
     read(fil,&olocangvel,2);                                // Les 09/28/95
     read(fil,&locbits,2);
     read(fil,&olocbits,2);

     read(fil,&locselectedgun2,4);
     read(fil,&locvel2,1);
     read(fil,&olocvel2,1);
     read(fil,&locsvel2,2);                                  // Les 09/28/95
     read(fil,&olocsvel2,2);                                 // Les 09/28/95
     read(fil,&locangvel2,2);                                // Les 09/28/95
     read(fil,&olocangvel2,2);                               // Les 09/28/95
     read(fil,&locbits2,2);
     read(fil,&olocbits2,2);

     read(fil,syncvel,MAXPLAYERS);
     read(fil,osyncvel,MAXPLAYERS);
     read(fil,syncsvel,MAXPLAYERS<<1);                       // Les 09/28/95
     read(fil,osyncsvel,MAXPLAYERS<<1);                      // Les 09/28/95
     read(fil,syncangvel,MAXPLAYERS<<1);                     // Les 09/28/95
     read(fil,osyncangvel,MAXPLAYERS<<1);                    // Les 09/28/95
     read(fil,syncbits,MAXPLAYERS<<1);
     read(fil,osyncbits,MAXPLAYERS<<1);

     read(fil,&screenpeek,2);
     read(fil,&oldmousebstatus,2);
     read(fil,&brightness,2);
     read(fil,&neartagsector,2);
     read(fil,&neartagwall,2);
     read(fil,&neartagsprite,2);
     read(fil,&lockclock,4);
     read(fil,&neartagdist,4);
     read(fil,&neartaghitdist,4);
     read(fil,&masterslavetexttime,4);

     read(fil,rotatespritelist,16<<1);
     read(fil,&rotatespritecnt,2);
     read(fil,warpsectorlist,16<<1);
     read(fil,&warpsectorcnt,2);
     read(fil,xpanningsectorlist,16<<1);
     read(fil,&xpanningsectorcnt,2);
     read(fil,ypanningwalllist,64<<1);
     read(fil,&ypanningwallcnt,2);
     read(fil,floorpanninglist,64<<1);
     read(fil,&floorpanningcnt,2);
     read(fil,dragsectorlist,16<<1);
     read(fil,dragxdir,16<<1);
     read(fil,dragydir,16<<1);
     read(fil,&dragsectorcnt,2);
     read(fil,dragx1,16<<2);
     read(fil,dragy1,16<<2);
     read(fil,dragx2,16<<2);
     read(fil,dragy2,16<<2);
     read(fil,dragfloorz,16<<2);
     read(fil,&swingcnt,2);
     read(fil,swingwall,(32*5)<<1);
     read(fil,swingsector,32<<1);
     read(fil,swingangopen,32<<1);
     read(fil,swingangclosed,32<<1);
     read(fil,swingangopendir,32<<1);
     read(fil,swingang,32<<1);
     read(fil,swinganginc,32<<1);
     read(fil,swingx,(32*8)<<2);
     read(fil,swingy,(32*8)<<2);
     read(fil,revolvesector,4<<1);
     read(fil,revolveang,4<<1);
     read(fil,&revolvecnt,2);
     read(fil,revolvex,(4*16)<<2);
     read(fil,revolvey,(4*16)<<2);
     read(fil,revolvepivotx,4<<2);
     read(fil,revolvepivoty,4<<2);
     read(fil,subwaytracksector,(4*128)<<1);
     read(fil,subwaynumsectors,4<<1);
     read(fil,&subwaytrackcnt,2);
     read(fil,subwaystop,(4*8)<<2);
     read(fil,subwaystopcnt,4<<2);
     read(fil,subwaytrackx1,4<<2);
     read(fil,subwaytracky1,4<<2);
     read(fil,subwaytrackx2,4<<2);
     read(fil,subwaytracky2,4<<2);
     read(fil,subwayx,4<<2);
     read(fil,subwaygoalstop,4<<2);
     read(fil,subwayvel,4<<2);
     read(fil,subwaypausetime,4<<2);
     read(fil,waterfountainwall,MAXPLAYERS<<1);
     read(fil,waterfountaincnt,MAXPLAYERS<<1);
     read(fil,slimesoundcnt,MAXPLAYERS<<1);

     // Warning: only works if all pointers are in sector structures!
     read(fil,tmpanimates,sizeof(intptr_t) * MAXANIMATES);
     for(i=MAXANIMATES-1;i>=0;i--)
          animateptr[i] = (int *)(tmpanimates[i] + (intptr_t)sector);
     read(fil,animategoal,MAXANIMATES<<2);
     read(fil,animatevel,MAXANIMATES<<2);
     read(fil,animateacc,MAXANIMATES<<2);
     read(fil,&animatecnt,4);

     read(fil,&totalclock,4);
     read(fil,&numframes,4);
     read(fil,&randomseed,4);

    #ifdef UNINITENGINECRASH
     read(fil,startumost,MAXXDIM<<1);
     read(fil,startdmost,MAXXDIM<<1);
    #endif

     #if 0 // TODO
     read(fil,&numpalookups,2);

     read(fil,&visibility,4);
     read(fil,&parallaxtype,1);
     read(fil,&parallaxyoffs,4);
     read(fil,pskyoff,MAXPSKYTILES<<1);
     read(fil,&pskybits,2);
     #endif

     read(fil,show2dsector,MAXSECTORS>>3);
     read(fil,show2dwall,MAXWALLS>>3);
     read(fil,show2dsprite,MAXSPRITES>>3);
     read(fil,&automapping,1);

     read(fil,invredcards,MAXPLAYERS<<2);   //  sizeof(invredcards));
     read(fil,invbluecards,MAXPLAYERS<<2);  //  sizeof(invbluecards));
     read(fil,invaccutrak,MAXPLAYERS<<2);   //  sizeof(invaccutrak));

     tekgunload(fil);
     tektagload(fil);
     tekstatload(fil);

     tekloadmissioninfo(fil);

     rv=close(fil);

     for(i=connecthead;i>=0;i=connectpoint2[i]) initplayersprite((short)i);

     totalclock = lockclock;
     ototalclock = lockclock;

     showmessage("GAME LOADED");

     return(0);
}

int
savegame(int saveno)
{
     int      i, fil;
     int       rv;
     intptr_t tmpanimates[MAXANIMATES];

     sprintf(tempbuf,"savegam%d.tek",saveno);

     if( (fil = open(tempbuf,O_BINARY|O_TRUNC|O_CREAT|O_WRONLY,S_IWRITE)) == -1 ) {
          return(-1);
     }

     lseek(fil, 0, SEEK_SET);

     rv=write(fil,loadsavenames[saveno-1],MAXLOADSAVESIZE);

     rv=write(fil,boardfilename,80);

     rv=write(fil,&numplayers,2);
     rv=write(fil,&myconnectindex,2);
     rv=write(fil,&connecthead,2);
     rv=write(fil,connectpoint2,MAXPLAYERS<<1);

     rv=write(fil,posx,MAXPLAYERS<<2);
     rv=write(fil,posy,MAXPLAYERS<<2);
     rv=write(fil,posz,MAXPLAYERS<<2);
     rv=write(fil,horiz,MAXPLAYERS<<2);
     rv=write(fil,zoom,MAXPLAYERS<<2);
     rv=write(fil,hvel,MAXPLAYERS<<2);
     rv=write(fil,ang,MAXPLAYERS<<1);
     rv=write(fil,cursectnum,MAXPLAYERS<<1);
     rv=write(fil,ocursectnum,MAXPLAYERS<<1);
     rv=write(fil,playersprite,MAXPLAYERS<<1);
     rv=write(fil,deaths,MAXPLAYERS<<1);
     rv=write(fil,lastchaingun,MAXPLAYERS<<2);
     rv=write(fil,health,MAXPLAYERS<<2);
     rv=write(fil,score,MAXPLAYERS<<2);
     rv=write(fil,saywatchit,MAXPLAYERS<<2);
     rv=write(fil,numbombs,MAXPLAYERS<<1);
     rv=write(fil,&screensize,2);
     rv=write(fil,oflags,MAXPLAYERS<<1);
     rv=write(fil,dimensionmode,MAXPLAYERS);
     rv=write(fil,revolvedoorstat,MAXPLAYERS);
     rv=write(fil,revolvedoorang,MAXPLAYERS<<1);
     rv=write(fil,revolvedoorrotang,MAXPLAYERS<<1);
     rv=write(fil,revolvedoorx,MAXPLAYERS<<2);
     rv=write(fil,revolvedoory,MAXPLAYERS<<2);

     rv=write(fil,&numsectors,2);
     rv=write(fil,sector,sizeof(sectortype)*numsectors);

     rv=write(fil,&numwalls,2);
     rv=write(fil,wall,sizeof(walltype)*numwalls);

     // Store all sprites (even holes) to preserve indeces
     rv=write(fil,sprite,sizeof(spritetype)*MAXSPRITES);
     rv=write(fil,headspritesect,(MAXSECTORS+1)<<1);
     rv=write(fil,prevspritesect,MAXSPRITES<<1);
     rv=write(fil,nextspritesect,MAXSPRITES<<1);
     rv=write(fil,headspritestat,(MAXSTATUS+1)<<1);
     rv=write(fil,prevspritestat,MAXSPRITES<<1);
     rv=write(fil,nextspritestat,MAXSPRITES<<1);

     rv=write(fil,&vel,4);
     rv=write(fil,&svel,4);
     rv=write(fil,&angvel,4);

     rv=write(fil,&locselectedgun,4);
     rv=write(fil,&locvel,1);
     rv=write(fil,&olocvel,1);
     rv=write(fil,&locsvel,2);                                  // Les 09/28/95
     rv=write(fil,&olocsvel,2);                                 // Les 09/28/95
     rv=write(fil,&locangvel,2);                                // Les 09/28/95
     rv=write(fil,&olocangvel,2);                               // Les 09/28/95
     rv=write(fil,&locbits,2);
     rv=write(fil,&olocbits,2);

     rv=write(fil,&locselectedgun2,4);
     rv=write(fil,&locvel2,1);
     rv=write(fil,&olocvel2,1);
     rv=write(fil,&locsvel2,2);                                 // Les 09/28/95
     rv=write(fil,&olocsvel2,2);                                // Les 09/28/95
     rv=write(fil,&locangvel2,2);                               // Les 09/28/95
     rv=write(fil,&olocangvel2,2);                              // Les 09/28/95
     rv=write(fil,&locbits2,2);
     rv=write(fil,&olocbits2,2);

     rv=write(fil,syncvel,MAXPLAYERS);
     rv=write(fil,osyncvel,MAXPLAYERS);
     rv=write(fil,syncsvel,MAXPLAYERS<<1);                      // Les 09/28/95
     rv=write(fil,osyncsvel,MAXPLAYERS<<1);                     // Les 09/28/95
     rv=write(fil,syncangvel,MAXPLAYERS<<1);                    // Les 09/28/95
     rv=write(fil,osyncangvel,MAXPLAYERS<<1);                   // Les 09/28/95
     rv=write(fil,syncbits,MAXPLAYERS<<1);
     rv=write(fil,osyncbits,MAXPLAYERS<<1);

     rv=write(fil,&screenpeek,2);
     rv=write(fil,&oldmousebstatus,2);
     rv=write(fil,&brightness,2);
     rv=write(fil,&neartagsector,2);
     rv=write(fil,&neartagwall,2);
     rv=write(fil,&neartagsprite,2);
     rv=write(fil,&lockclock,4);
     rv=write(fil,&neartagdist,4);
     rv=write(fil,&neartaghitdist,4);
     rv=write(fil,&masterslavetexttime,4);

     rv=write(fil,rotatespritelist,16<<1);
     rv=write(fil,&rotatespritecnt,2);
     rv=write(fil,warpsectorlist,16<<1);
     rv=write(fil,&warpsectorcnt,2);
     rv=write(fil,xpanningsectorlist,16<<1);
     rv=write(fil,&xpanningsectorcnt,2);
     rv=write(fil,ypanningwalllist,64<<1);
     rv=write(fil,&ypanningwallcnt,2);
     rv=write(fil,floorpanninglist,64<<1);
     rv=write(fil,&floorpanningcnt,2);
     rv=write(fil,dragsectorlist,16<<1);
     rv=write(fil,dragxdir,16<<1);
     rv=write(fil,dragydir,16<<1);
     rv=write(fil,&dragsectorcnt,2);
     rv=write(fil,dragx1,16<<2);
     rv=write(fil,dragy1,16<<2);
     rv=write(fil,dragx2,16<<2);
     rv=write(fil,dragy2,16<<2);
     rv=write(fil,dragfloorz,16<<2);
     rv=write(fil,&swingcnt,2);
     rv=write(fil,swingwall,(32*5)<<1);
     rv=write(fil,swingsector,32<<1);
     rv=write(fil,swingangopen,32<<1);
     rv=write(fil,swingangclosed,32<<1);
     rv=write(fil,swingangopendir,32<<1);
     rv=write(fil,swingang,32<<1);
     rv=write(fil,swinganginc,32<<1);
     rv=write(fil,swingx,(32*8)<<2);
     rv=write(fil,swingy,(32*8)<<2);
     rv=write(fil,revolvesector,4<<1);
     rv=write(fil,revolveang,4<<1);
     rv=write(fil,&revolvecnt,2);
     rv=write(fil,revolvex,(4*16)<<2);
     rv=write(fil,revolvey,(4*16)<<2);
     rv=write(fil,revolvepivotx,4<<2);
     rv=write(fil,revolvepivoty,4<<2);
     rv=write(fil,subwaytracksector,(4*128)<<1);
     rv=write(fil,subwaynumsectors,4<<1);
     rv=write(fil,&subwaytrackcnt,2);
     rv=write(fil,subwaystop,(4*8)<<2);
     rv=write(fil,subwaystopcnt,4<<2);
     rv=write(fil,subwaytrackx1,4<<2);
     rv=write(fil,subwaytracky1,4<<2);
     rv=write(fil,subwaytrackx2,4<<2);
     rv=write(fil,subwaytracky2,4<<2);
     rv=write(fil,subwayx,4<<2);
     rv=write(fil,subwaygoalstop,4<<2);
     rv=write(fil,subwayvel,4<<2);
     rv=write(fil,subwaypausetime,4<<2);
     rv=write(fil,waterfountainwall,MAXPLAYERS<<1);
     rv=write(fil,waterfountaincnt,MAXPLAYERS<<1);
     rv=write(fil,slimesoundcnt,MAXPLAYERS<<1);

     // Warning: only works if all pointers are in sector structures!
     for(i=MAXANIMATES-1;i>=0;i--)
          tmpanimates[i] = (intptr_t)animateptr[i] - (intptr_t)sector;
     rv=write(fil,tmpanimates, sizeof(intptr_t)*MAXANIMATES);
     rv=write(fil,animategoal,MAXANIMATES<<2);
     rv=write(fil,animatevel,MAXANIMATES<<2);
     rv=write(fil,animateacc,MAXANIMATES<<2);
     rv=write(fil,&animatecnt,4);

     rv=write(fil,&totalclock,4);
     rv=write(fil,&numframes,4);
     rv=write(fil,&randomseed,4);

    #ifdef UNINITENGINECRASH
     rv=write(fil,startumost,MAXXDIM<<1);
     rv=write(fil,startdmost,MAXXDIM<<1);
    #endif

     #if 0 // TODO
     rv=write(fil,&numpalookups,2);

     rv=write(fil,&visibility,4);
     rv=write(fil,&parallaxtype,1);
     rv=write(fil,&parallaxyoffs,4);
     rv=write(fil,pskyoff,MAXPSKYTILES<<1);
     rv=write(fil,&pskybits,2);
     #endif

     rv=write(fil,show2dsector,MAXSECTORS>>3);
     rv=write(fil,show2dwall,MAXWALLS>>3);
     rv=write(fil,show2dsprite,MAXSPRITES>>3);
     rv=write(fil,&automapping,1);

     rv=write(fil,invredcards,MAXPLAYERS<<2);  // sizeof(invredcards));
     rv=write(fil,invbluecards,MAXPLAYERS<<2); // sizeof(invbluecards));
     rv=write(fil,invaccutrak,MAXPLAYERS<<2);  // sizeof(invaccutrak));

     tekgunsave(fil);
     tektagsave(fil);
     tekstatsave(fil);

     teksavemissioninfo(fil);

     rv=close(fil);

     showmessage("GAME SAVED");

     return(0);
}


code:
/***************************************************************************
 *   TEKMAP.C  - 2 dimensional map modes                                   *
 *                                                                         *
 *                                                                         *
 ***************************************************************************/

#include "build.h"
#include "pragmas.h"
#include "names.h"

#include "tekwar.h"

void
drawoverheadmap(int cposx, int cposy, int czoom, short cang)
{
    #if 0// TODO
     int i, j, k, l, x1, y1, x2, y2, x3, y3, x4, y4, ox, oy, xoff, yoff;
     int dax, day, cosang, sinang, xspan, yspan, sprx, spry;
     int xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang;
     int xvect, yvect, xvect2, yvect2;
     unsigned char col;
     walltype *wal, *wal2;
     spritetype *spr;

     xvect = sintable[(2048-cang)&2047] * czoom;
     yvect = sintable[(1536-cang)&2047] * czoom;
     xvect2 = mulscale(xvect,yxaspect,16);
     yvect2 = mulscale(yvect,yxaspect,16);

          //Draw red lines
     for(i=0;i<numsectors;i++)
     {
          startwall = sector[i].wallptr;
          endwall = sector[i].wallptr + sector[i].wallnum - 1;

          z1 = sector[i].ceilingz; z2 = sector[i].floorz;

          for(j=startwall,wal=&wall[startwall];j<=endwall;j++,wal++)
          {
               k = wal->nextwall; if (k < 0) continue;

               if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue;
               if ((k > j) && ((show2dwall[k>>3]&(1<<(k&7))) > 0)) continue;

               if (sector[wal->nextsector].ceilingz == z1)
                    if (sector[wal->nextsector].floorz == z2)
                         if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0) continue;

               col = 232;

               if (dimensionmode[screenpeek] == 2)
               {
                    if (sector[i].floorz != sector[i].ceilingz)
                         if (sector[wal->nextsector].floorz != sector[wal->nextsector].ceilingz)
                              if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0)
                                   if (sector[i].floorz == sector[wal->nextsector].floorz) continue;
                    if (sector[i].floorpicnum != sector[wal->nextsector].floorpicnum) continue;
                    if (sector[i].floorshade != sector[wal->nextsector].floorshade) continue;
                    col = 232;
               }

               ox = wal->x-cposx; oy = wal->y-cposy;
               x1 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
               y1 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);

               wal2 = &wall[wal->point2];
               ox = wal2->x-cposx; oy = wal2->y-cposy;
               x2 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
               y2 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);

               drawline256(x1+(xdim<<11),y1+(ydim<<11),x2+(xdim<<11),y2+(ydim<<11),col);
          }
     }

          //Draw sprites
     k = playersprite[screenpeek];
     show2dsprite[k>>3] |= (1<<(k&7));
     for(i=0;i<numsectors;i++)
          for(j=headspritesect[i];j>=0;j=nextspritesect[j])
               if ((show2dsprite[j>>3]&(1<<(j&7))) > 0)
               {
                    spr = &sprite[j];
                    col = 56;
                    if ((spr->cstat&1) > 0) col = 248;
                    if (j == k) col = 31;

                    sprx = spr->x;
                    spry = spr->y;

                    k = spr->statnum;
                    if ((k >= 1) && (k <= 8) && (k != 2))  //Interpolate moving sprite
                    {
                         sprx = osprite[j].x+mulscale(sprx-osprite[j].x,smoothratio,16);
                         spry = osprite[j].y+mulscale(spry-osprite[j].y,smoothratio,16);
                    }

                    switch (spr->cstat&48)
                    {
                         case 0:
                              ox = sprx-cposx; oy = spry-cposy;
                              x1 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
                              y1 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);

                              if (dimensionmode[screenpeek] == 1)
                              {
                                   ox = (sintable[(spr->ang+512)&2047]>>7);
                                   oy = (sintable[(spr->ang)&2047]>>7);
                                   x2 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
                                   y2 = mulscale(oy,xvect,16) + mulscale(ox,yvect,16);

                                   if (j == playersprite[screenpeek])
                                   {
                                        x2 = 0L;
                                        y2 = -(czoom<<5);
                                   }

                                   x3 = mulscale(x2,yxaspect,16);
                                   y3 = mulscale(y2,yxaspect,16);

                                   drawline256(x1-x2+(xdim<<11),y1-y3+(ydim<<11),
                                                       x1+x2+(xdim<<11),y1+y3+(ydim<<11),col);
                                   drawline256(x1-y2+(xdim<<11),y1+x3+(ydim<<11),
                                                       x1+x2+(xdim<<11),y1+y3+(ydim<<11),col);
                                   drawline256(x1+y2+(xdim<<11),y1-x3+(ydim<<11),
                                                       x1+x2+(xdim<<11),y1+y3+(ydim<<11),col);
                              }
                              else
                              {
                                   if (((gotsector[i>>3]&(1<<(i&7))) > 0) && (czoom > 192))
                                   {
                                        daang = (spr->ang-cang)&2047;
                                        if (j == playersprite[screenpeek])
                                             { x1 = 0; y1 = (yxaspect<<2); daang = 0; }
                                        rotatesprite((x1<<4)+(xdim<<15),(y1<<4)+(ydim<<15),mulscale(czoom*spr->yrepeat,yxaspect,16),daang,spr->picnum,spr->shade,spr->pal,(spr->cstat&2)>>1, windowxy1.x, windowxy1.y, windowxy2.x, windowxy2.y);
                                   }
                              }
                              break;
                         case 16:
                              x1 = sprx; y1 = spry;
                              tilenum = spr->picnum;
                              xoff = (int)((signed char)((picanm[tilenum].xofs)&255))+((int)spr->xoffset);
                              if ((spr->cstat&4) > 0) xoff = -xoff;
                              k = spr->ang; l = spr->xrepeat;
                              dax = sintable[k&2047]*l; day = sintable[(k+1536)&2047]*l;
                              l = tilesiz[tilenum].x; k = (l>>1)+xoff;
                              x1 -= mulscale(dax,k,16); x2 = x1+mulscale(dax,l,16);
                              y1 -= mulscale(day,k,16); y2 = y1+mulscale(day,l,16);

                              ox = x1-cposx; oy = y1-cposy;
                              x1 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
                              y1 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);

                              ox = x2-cposx; oy = y2-cposy;
                              x2 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
                              y2 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);

                              drawline256(x1+(xdim<<11),y1+(ydim<<11),
                                                  x2+(xdim<<11),y2+(ydim<<11),col);

                              break;
                         case 32:
                              if (dimensionmode[screenpeek] == 1)
                              {
                                   tilenum = spr->picnum;
                                   xoff = (int)((signed char)((picanm[tilenum].xofs)&255))+((int)spr->xoffset);
                                   yoff = (int)((signed char)((picanm[tilenum].yofs)&255))+((int)spr->yoffset);
                                   if ((spr->cstat&4) > 0) xoff = -xoff;
                                   if ((spr->cstat&8) > 0) yoff = -yoff;

                                   k = spr->ang;
                                   cosang = sintable[(k+512)&2047]; sinang = sintable[k];
                                   xspan = tilesiz[tilenum].x; xrepeat = spr->xrepeat;
                                   yspan = tilesiz[tilenum].y; yrepeat = spr->yrepeat;

                                   dax = ((xspan>>1)+xoff)*xrepeat; day = ((yspan>>1)+yoff)*yrepeat;
                                   x1 = sprx + mulscale(sinang,dax,16) + mulscale(cosang,day,16);
                                   y1 = spry + mulscale(sinang,day,16) - mulscale(cosang,dax,16);
                                   l = xspan*xrepeat;
                                   x2 = x1 - mulscale(sinang,l,16);
                                   y2 = y1 + mulscale(cosang,l,16);
                                   l = yspan*yrepeat;
                                   k = -mulscale(cosang,l,16); x3 = x2+k; x4 = x1+k;
                                   k = -mulscale(sinang,l,16); y3 = y2+k; y4 = y1+k;

                                   ox = x1-cposx; oy = y1-cposy;
                                   x1 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
                                   y1 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);

                                   ox = x2-cposx; oy = y2-cposy;
                                   x2 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
                                   y2 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);

                                   ox = x3-cposx; oy = y3-cposy;
                                   x3 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
                                   y3 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);

                                   ox = x4-cposx; oy = y4-cposy;
                                   x4 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
                                   y4 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);

                                   drawline256(x1+(xdim<<11),y1+(ydim<<11),
                                                       x2+(xdim<<11),y2+(ydim<<11),col);

                                   drawline256(x2+(xdim<<11),y2+(ydim<<11),
                                                       x3+(xdim<<11),y3+(ydim<<11),col);

                                   drawline256(x3+(xdim<<11),y3+(ydim<<11),
                                                       x4+(xdim<<11),y4+(ydim<<11),col);

                                   drawline256(x4+(xdim<<11),y4+(ydim<<11),
                                                       x1+(xdim<<11),y1+(ydim<<11),col);

                              }
                              break;
                    }
               }

          //Draw white lines
     for(i=0;i<numsectors;i++)
     {
          startwall = sector[i].wallptr;
          endwall = sector[i].wallptr + sector[i].wallnum - 1;

          for(j=startwall,wal=&wall[startwall];j<=endwall;j++,wal++)
          {
               if (wal->nextwall >= 0) continue;

               if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue;

               if (tilesiz[wal->picnum].x == 0) continue;
               if (tilesiz[wal->picnum].y == 0) continue;

               ox = wal->x-cposx; oy = wal->y-cposy;
               x1 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
               y1 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);

               wal2 = &wall[wal->point2];
               ox = wal2->x-cposx; oy = wal2->y-cposy;
               x2 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
               y2 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);

               drawline256(x1+(xdim<<11),y1+(ydim<<11),x2+(xdim<<11),y2+(ydim<<11),239);
          }
     }
     #endif
}