Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "version.h"
  2.  
  3. #ifdef USE_DIR3DSPR
  4. #include "wl_def.h"
  5. #include "wl_shade.h"
  6.  
  7. // Define directional 3d sprites in wl_act1.cpp (there are two examples)
  8. // Make sure you have according entries in ScanInfoPlane in wl_game.cpp.
  9.  
  10.  
  11. void Scale3DShaper(int x1, int x2, int shapenum, uint32_t flags, fixed ny1, fixed ny2,
  12.                    fixed nx1, fixed nx2, byte *vbuf, unsigned vbufPitch)
  13. {
  14.     t_compshape *shape;
  15.     unsigned scale1,starty,endy;
  16.     word *cmdptr;
  17.     byte *line;
  18.     byte *vmem;
  19.     int dx,len,i,newstart,ycnt,pixheight,screndy,upperedge,scrstarty;
  20.     unsigned j;
  21.     fixed height,dheight,height1,height2;
  22.     int xpos[TEXTURESIZE+1];
  23.     int slinex;
  24.     fixed dxx=(ny2-ny1)<<8,dzz=(nx2-nx1)<<8;
  25.     fixed dxa=0,dza=0;
  26.     byte col;
  27.  
  28.     shape = (t_compshape *) PM_GetSprite(shapenum);
  29.  
  30.     len=shape->rightpix-shape->leftpix+1;
  31.     if(!len) return;
  32.  
  33.     ny1+=dxx>>9;
  34.     nx1+=dzz>>9;
  35.  
  36.     dxa=-(dxx>>1),dza=-(dzz>>1);
  37.     dxx>>=TEXTURESHIFT,dzz>>=TEXTURESHIFT;
  38.     dxa+=shape->leftpix*dxx,dza+=shape->leftpix*dzz;
  39.  
  40.     xpos[0]=(int)((ny1+(dxa>>8))*scale/(nx1+(dza>>8))+centerx);
  41.     height1 = heightnumerator/((nx1+(dza>>8))>>8);
  42.     height=(((fixed)height1)<<12)+2048;
  43.  
  44.     for(i=1;i<=len;i++)
  45.     {
  46.         dxa+=dxx,dza+=dzz;
  47.         xpos[i]=(int)((ny1+(dxa>>8))*scale/(nx1+(dza>>8))+centerx);
  48.         if(xpos[i-1]>viewwidth) break;
  49.     }
  50.     len=i-1;
  51.     dx = xpos[len] - xpos[0];
  52.     if(!dx) return;
  53.  
  54.     height2 = heightnumerator/((nx1+(dza>>8))>>8);
  55.     dheight=(((fixed)height2-(fixed)height1)<<12)/(fixed)dx;
  56.  
  57.     cmdptr = (word *) shape->dataofs;
  58.  
  59.     i=0;
  60.     if(x2>viewwidth) x2=viewwidth;
  61.  
  62.     for(i=0;i<len;i++)
  63.     {
  64.         for(slinex=xpos[i];slinex<xpos[i+1] && slinex<x2;slinex++)
  65.         {
  66.             height+=dheight;
  67.             if(slinex<0) continue;
  68.  
  69.             scale1=(unsigned)(height>>15);
  70.  
  71.             if(wallheight[slinex]<(height>>12) && scale1 /*&& scale1<=maxscale*/)
  72.             {
  73. #ifdef USE_SHADING
  74.                 byte *curshades;
  75.                 if(flags & FL_FULLBRIGHT)
  76.                     curshades = shadetable[0];
  77.                 else
  78.                     curshades = shadetable[GetShade(scale1<<3)];
  79. #endif
  80.  
  81.                 pixheight=scale1*SPRITESCALEFACTOR;
  82.                 upperedge=viewheight/2-scale1;
  83.  
  84.                 line=(byte *)shape + cmdptr[i];
  85.  
  86.                 while((endy = READWORD(line)) != 0)
  87.                 {
  88.                     endy >>= 1;
  89.                     newstart = READWORD(line);
  90.                     starty = READWORD(line) >> 1;
  91.                     j=starty;
  92.                     ycnt=j*pixheight;
  93.                     screndy=(ycnt>>6)+upperedge;
  94.                     if(screndy<0) vmem=vbuf+slinex;
  95.                     else vmem=vbuf+screndy*vbufPitch+slinex;
  96.                     for(;j<endy;j++)
  97.                     {
  98.                         scrstarty=screndy;
  99.                         ycnt+=pixheight;
  100.                         screndy=(ycnt>>6)+upperedge;
  101.                         if(scrstarty!=screndy && screndy>0)
  102.                         {
  103. #ifdef USE_SHADING
  104.                             col=curshades[((byte *)shape)[newstart+j]];
  105. #else
  106.                             col=((byte *)shape)[newstart+j];
  107. #endif
  108.                             if(scrstarty<0) scrstarty=0;
  109.                             if(screndy>viewheight) screndy=viewheight,j=endy;
  110.  
  111.                             while(scrstarty<screndy)
  112.                             {
  113.                                 *vmem=col;
  114.                                 vmem+=vbufPitch;
  115.                                 scrstarty++;
  116.                             }
  117.                         }
  118.                     }
  119.                 }
  120.             }
  121.         }
  122.     }
  123. }
  124.  
  125. void Scale3DShape(byte *vbuf, unsigned vbufPitch, statobj_t *ob)
  126. {
  127.     fixed nx1,nx2,ny1,ny2;
  128.     int viewx1,viewx2;
  129.     fixed diradd;
  130.     fixed playx = viewx;
  131.     fixed playy = viewy;
  132.  
  133.     //
  134.     // the following values for "diradd" aren't optimized yet
  135.     // if you have problems with sprites being visible through wall edges
  136.     // where they shouldn't, you can try to adjust these values and SIZEADD
  137.     //
  138.  
  139. #define SIZEADD 1024
  140.  
  141.     switch(ob->flags & FL_DIR_POS_MASK)
  142.     {
  143.         case FL_DIR_POS_FW: diradd=0x7ff0+0x8000; break;
  144.         case FL_DIR_POS_BW: diradd=-0x7ff0+0x8000; break;
  145.         case FL_DIR_POS_MID: diradd=0x8000; break;
  146.         default:
  147.             Quit("Unknown directional 3d sprite position (shapenum = %i)", ob->shapenum);
  148.     }
  149.  
  150.     if(ob->flags & FL_DIR_VERT_FLAG)     // vertical dir 3d sprite
  151.     {
  152.         fixed gy1,gy2,gx,gyt1,gyt2,gxt;
  153.         //
  154.         // translate point to view centered coordinates
  155.         //
  156.         gy1 = (((long)ob->tiley) << TILESHIFT)+0x8000-playy-0x8000L-SIZEADD;
  157.         gy2 = gy1+0x10000L+2*SIZEADD;
  158.         gx = (((long)ob->tilex) << TILESHIFT)+diradd-playx;
  159.  
  160.         //
  161.         // calculate newx
  162.         //
  163.         gxt = FixedMul(gx,viewcos);
  164.         gyt1 = FixedMul(gy1,viewsin);
  165.         gyt2 = FixedMul(gy2,viewsin);
  166.         nx1 = gxt-gyt1;
  167.         nx2 = gxt-gyt2;
  168.  
  169.         //
  170.         // calculate newy
  171.         //
  172.         gxt = FixedMul(gx,viewsin);
  173.         gyt1 = FixedMul(gy1,viewcos);
  174.         gyt2 = FixedMul(gy2,viewcos);
  175.         ny1 = gyt1+gxt;
  176.         ny2 = gyt2+gxt;
  177.     }
  178.     else                                    // horizontal dir 3d sprite
  179.     {
  180.         fixed gx1,gx2,gy,gxt1,gxt2,gyt;
  181.         //
  182.         // translate point to view centered coordinates
  183.         //
  184.         gx1 = (((long)ob->tilex) << TILESHIFT)+0x8000-playx-0x8000L-SIZEADD;
  185.         gx2 = gx1+0x10000L+2*SIZEADD;
  186.         gy = (((long)ob->tiley) << TILESHIFT)+diradd-playy;
  187.  
  188.         //
  189.         // calculate newx
  190.         //
  191.         gxt1 = FixedMul(gx1,viewcos);
  192.         gxt2 = FixedMul(gx2,viewcos);
  193.         gyt = FixedMul(gy,viewsin);
  194.         nx1 = gxt1-gyt;
  195.         nx2 = gxt2-gyt;
  196.  
  197.         //
  198.         // calculate newy
  199.         //
  200.         gxt1 = FixedMul(gx1,viewsin);
  201.         gxt2 = FixedMul(gx2,viewsin);
  202.         gyt = FixedMul(gy,viewcos);
  203.         ny1 = gyt+gxt1;
  204.         ny2 = gyt+gxt2;
  205.     }
  206.  
  207.     if(nx1 < 0 || nx2 < 0) return;      // TODO: Clip on viewplane
  208.  
  209.     //
  210.     // calculate perspective ratio
  211.     //
  212.     if(nx1>=0 && nx1<=1792) nx1=1792;
  213.     if(nx1<0 && nx1>=-1792) nx1=-1792;
  214.     if(nx2>=0 && nx2<=1792) nx2=1792;
  215.     if(nx2<0 && nx2>=-1792) nx2=-1792;
  216.  
  217.     viewx1=(int)(centerx+ny1*scale/nx1);
  218.     viewx2=(int)(centerx+ny2*scale/nx2);
  219.  
  220.     if(viewx2 < viewx1)
  221.     {
  222.         Scale3DShaper(viewx2,viewx1,ob->shapenum,ob->flags,ny2,ny1,nx2,nx1,vbuf,vbufPitch);
  223.     }
  224.     else
  225.     {
  226.         Scale3DShaper(viewx1,viewx2,ob->shapenum,ob->flags,ny1,ny2,nx1,nx2,vbuf,vbufPitch);
  227.     }
  228. }
  229.  
  230. #endif
  231.