Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. // Emacs style mode select   -*- C++ -*-
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. //      All the clipping: columns, horizontal spans, sky columns.
  21. //
  22. //-----------------------------------------------------------------------------
  23.  
  24.  
  25. static const char
  26. rcsid[] = "$Id: r_segs.c,v 1.3 1997/01/29 20:10:19 b1 Exp $";
  27.  
  28.  
  29.  
  30.  
  31.  
  32. #include <stdlib.h>
  33.  
  34. #include "i_system.h"
  35.  
  36. #include "doomdef.h"
  37. #include "doomstat.h"
  38.  
  39. #include "r_local.h"
  40. #include "r_sky.h"
  41.  
  42.  
  43. // OPTIMIZE: closed two sided lines as single sided
  44.  
  45. // True if any of the segs textures might be visible.
  46. boolean         segtextured;   
  47.  
  48. // False if the back side is the same plane.
  49. boolean         markfloor;     
  50. boolean         markceiling;
  51.  
  52. boolean         maskedtexture;
  53. int             toptexture;
  54. int             bottomtexture;
  55. int             midtexture;
  56.  
  57.  
  58. angle_t         rw_normalangle;
  59. // angle to line origin
  60. int             rw_angle1;     
  61.  
  62. //
  63. // regular wall
  64. //
  65. int             rw_x;
  66. int             rw_stopx;
  67. angle_t         rw_centerangle;
  68. fixed_t         rw_offset;
  69. fixed_t         rw_distance;
  70. fixed_t         rw_scale;
  71. fixed_t         rw_scalestep;
  72. fixed_t         rw_midtexturemid;
  73. fixed_t         rw_toptexturemid;
  74. fixed_t         rw_bottomtexturemid;
  75.  
  76. int             worldtop;
  77. int             worldbottom;
  78. int             worldhigh;
  79. int             worldlow;
  80.  
  81. fixed_t         pixhigh;
  82. fixed_t         pixlow;
  83. fixed_t         pixhighstep;
  84. fixed_t         pixlowstep;
  85.  
  86. fixed_t         topfrac;
  87. fixed_t         topstep;
  88.  
  89. fixed_t         bottomfrac;
  90. fixed_t         bottomstep;
  91.  
  92.  
  93. lighttable_t**  walllights;
  94.  
  95. short*          maskedtexturecol;
  96.  
  97.  
  98.  
  99. //
  100. // R_RenderMaskedSegRange
  101. //
  102. void
  103. R_RenderMaskedSegRange
  104. ( drawseg_t*    ds,
  105.   int           x1,
  106.   int           x2 )
  107. {
  108.     unsigned    index;
  109.     column_t*   col;
  110.     int         lightnum;
  111.     int         texnum;
  112.    
  113.     // Calculate light table.
  114.     // Use different light tables
  115.     //   for horizontal / vertical / diagonal. Diagonal?
  116.     // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
  117.     curline = ds->curline;
  118.     frontsector = curline->frontsector;
  119.     backsector = curline->backsector;
  120.     texnum = texturetranslation[curline->sidedef->midtexture];
  121.        
  122.     lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;
  123.  
  124.     if (curline->v1->y == curline->v2->y)
  125.         lightnum--;
  126.     else if (curline->v1->x == curline->v2->x)
  127.         lightnum++;
  128.  
  129.     if (lightnum < 0)          
  130.         walllights = scalelight[0];
  131.     else if (lightnum >= LIGHTLEVELS)
  132.         walllights = scalelight[LIGHTLEVELS-1];
  133.     else
  134.         walllights = scalelight[lightnum];
  135.  
  136.     maskedtexturecol = ds->maskedtexturecol;
  137.  
  138.     rw_scalestep = ds->scalestep;              
  139.     spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
  140.     mfloorclip = ds->sprbottomclip;
  141.     mceilingclip = ds->sprtopclip;
  142.    
  143.     // find positioning
  144.     if (curline->linedef->flags & ML_DONTPEGBOTTOM)
  145.     {
  146.         dc_texturemid = frontsector->floorheight > backsector->floorheight
  147.             ? frontsector->floorheight : backsector->floorheight;
  148.         dc_texturemid = dc_texturemid + textureheight[texnum] - viewz;
  149.     }
  150.     else
  151.     {
  152.         dc_texturemid =frontsector->ceilingheight<backsector->ceilingheight
  153.             ? frontsector->ceilingheight : backsector->ceilingheight;
  154.         dc_texturemid = dc_texturemid - viewz;
  155.     }
  156.     dc_texturemid += curline->sidedef->rowoffset;
  157.                        
  158.     if (fixedcolormap)
  159.         dc_colormap = fixedcolormap;
  160.    
  161.     // draw the columns
  162.     for (dc_x = x1 ; dc_x <= x2 ; dc_x++)
  163.     {
  164.         // calculate lighting
  165.         if (maskedtexturecol[dc_x] != MAXSHORT)
  166.         {
  167.             if (!fixedcolormap)
  168.             {
  169.                 index = spryscale>>LIGHTSCALESHIFT;
  170.  
  171.                 if (index >=  MAXLIGHTSCALE )
  172.                     index = MAXLIGHTSCALE-1;
  173.  
  174.                 dc_colormap = walllights[index];
  175.             }
  176.                        
  177.             sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
  178.             dc_iscale = 0xffffffffu / (unsigned)spryscale;
  179.            
  180.             // draw the texture
  181.             col = (column_t *)(
  182.                 (byte *)R_GetColumn(texnum,maskedtexturecol[dc_x]) -3);
  183.                        
  184.             R_DrawMaskedColumn (col);
  185.             maskedtexturecol[dc_x] = MAXSHORT;
  186.         }
  187.         spryscale += rw_scalestep;
  188.     }
  189.        
  190. }
  191.  
  192.  
  193.  
  194.  
  195. //
  196. // R_RenderSegLoop
  197. // Draws zero, one, or two textures (and possibly a masked
  198. //  texture) for walls.
  199. // Can draw or mark the starting pixel of floor and ceiling
  200. //  textures.
  201. // CALLED: CORE LOOPING ROUTINE.
  202. //
  203. #define HEIGHTBITS              12
  204. #define HEIGHTUNIT              (1<<HEIGHTBITS)
  205.  
  206. void R_RenderSegLoop (void)
  207. {
  208.     angle_t             angle;
  209.     unsigned            index;
  210.     int                 yl;
  211.     int                 yh;
  212.     int                 mid;
  213.     fixed_t             texturecolumn;
  214.     int                 top;
  215.     int                 bottom;
  216.  
  217.     //texturecolumn = 0;                                // shut up compiler warning
  218.        
  219.     for ( ; rw_x < rw_stopx ; rw_x++)
  220.     {
  221.         // mark floor / ceiling areas
  222.         yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS;
  223.  
  224.         // no space above wall?
  225.         if (yl < ceilingclip[rw_x]+1)
  226.             yl = ceilingclip[rw_x]+1;
  227.        
  228.         if (markceiling)
  229.         {
  230.             top = ceilingclip[rw_x]+1;
  231.             bottom = yl-1;
  232.  
  233.             if (bottom >= floorclip[rw_x])
  234.                 bottom = floorclip[rw_x]-1;
  235.  
  236.             if (top <= bottom)
  237.             {
  238.                 ceilingplane->top[rw_x] = top;
  239.                 ceilingplane->bottom[rw_x] = bottom;
  240.             }
  241.         }
  242.                
  243.         yh = bottomfrac>>HEIGHTBITS;
  244.  
  245.         if (yh >= floorclip[rw_x])
  246.             yh = floorclip[rw_x]-1;
  247.  
  248.         if (markfloor)
  249.         {
  250.             top = yh+1;
  251.             bottom = floorclip[rw_x]-1;
  252.             if (top <= ceilingclip[rw_x])
  253.                 top = ceilingclip[rw_x]+1;
  254.             if (top <= bottom)
  255.             {
  256.                 floorplane->top[rw_x] = top;
  257.                 floorplane->bottom[rw_x] = bottom;
  258.             }
  259.         }
  260.        
  261.         // texturecolumn and lighting are independent of wall tiers
  262.         if (segtextured)
  263.         {
  264.             // calculate texture offset
  265.             angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT;
  266.             texturecolumn = rw_offset-FixedMul(finetangent[angle],rw_distance);
  267.             texturecolumn >>= FRACBITS;
  268.             // calculate lighting
  269.             index = rw_scale>>LIGHTSCALESHIFT;
  270.  
  271.             if (index >=  MAXLIGHTSCALE )
  272.                 index = MAXLIGHTSCALE-1;
  273.  
  274.             dc_colormap = walllights[index];
  275.             dc_x = rw_x;
  276.             dc_iscale = 0xffffffffu / (unsigned)rw_scale;
  277.         }
  278.        
  279.         // draw the wall tiers
  280.         if (midtexture)
  281.         {
  282.             // single sided line
  283.             dc_yl = yl;
  284.             dc_yh = yh;
  285.             dc_texturemid = rw_midtexturemid;
  286.             dc_source = R_GetColumn(midtexture,texturecolumn);
  287.             colfunc ();
  288.             ceilingclip[rw_x] = viewheight;
  289.             floorclip[rw_x] = -1;
  290.         }
  291.         else
  292.         {
  293.             // two sided line
  294.             if (toptexture)
  295.             {
  296.                 // top wall
  297.                 mid = pixhigh>>HEIGHTBITS;
  298.                 pixhigh += pixhighstep;
  299.  
  300.                 if (mid >= floorclip[rw_x])
  301.                     mid = floorclip[rw_x]-1;
  302.  
  303.                 if (mid >= yl)
  304.                 {
  305.                     dc_yl = yl;
  306.                     dc_yh = mid;
  307.                     dc_texturemid = rw_toptexturemid;
  308.                     dc_source = R_GetColumn(toptexture,texturecolumn);
  309.                     colfunc ();
  310.                     ceilingclip[rw_x] = mid;
  311.                 }
  312.                 else
  313.                     ceilingclip[rw_x] = yl-1;
  314.             }
  315.             else
  316.             {
  317.                 // no top wall
  318.                 if (markceiling)
  319.                     ceilingclip[rw_x] = yl-1;
  320.             }
  321.                        
  322.             if (bottomtexture)
  323.             {
  324.                 // bottom wall
  325.                 mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS;
  326.                 pixlow += pixlowstep;
  327.  
  328.                 // no space above wall?
  329.                 if (mid <= ceilingclip[rw_x])
  330.                     mid = ceilingclip[rw_x]+1;
  331.                
  332.                 if (mid <= yh)
  333.                 {
  334.                     dc_yl = mid;
  335.                     dc_yh = yh;
  336.                     dc_texturemid = rw_bottomtexturemid;
  337.                     dc_source = R_GetColumn(bottomtexture,
  338.                                             texturecolumn);
  339.                     colfunc ();
  340.                     floorclip[rw_x] = mid;
  341.                 }
  342.                 else
  343.                     floorclip[rw_x] = yh+1;
  344.             }
  345.             else
  346.             {
  347.                 // no bottom wall
  348.                 if (markfloor)
  349.                     floorclip[rw_x] = yh+1;
  350.             }
  351.                        
  352.             if (maskedtexture)
  353.             {
  354.                 // save texturecol
  355.                 //  for backdrawing of masked mid texture
  356.                 maskedtexturecol[rw_x] = texturecolumn;
  357.             }
  358.         }
  359.                
  360.         rw_scale += rw_scalestep;
  361.         topfrac += topstep;
  362.         bottomfrac += bottomstep;
  363.     }
  364. }
  365.  
  366.  
  367.  
  368.  
  369. //
  370. // R_StoreWallRange
  371. // A wall segment will be drawn
  372. //  between start and stop pixels (inclusive).
  373. //
  374. void
  375. R_StoreWallRange
  376. ( int   start,
  377.   int   stop )
  378. {
  379.     fixed_t             hyp;
  380.     fixed_t             sineval;
  381.     angle_t             distangle, offsetangle;
  382.     fixed_t             vtop;
  383.     int                 lightnum;
  384.  
  385.     // don't overflow and crash
  386.     if (ds_p == &drawsegs[MAXDRAWSEGS])
  387.         return;        
  388.                
  389. #ifdef RANGECHECK
  390.     if (start >=viewwidth || start > stop)
  391.         I_Error ("Bad R_RenderWallRange: %i to %i", start , stop);
  392. #endif
  393.    
  394.     sidedef = curline->sidedef;
  395.     linedef = curline->linedef;
  396.  
  397.     // mark the segment as visible for auto map
  398.     linedef->flags |= ML_MAPPED;
  399.    
  400.     // calculate rw_distance for scale calculation
  401.     rw_normalangle = curline->angle + ANG90;
  402.     offsetangle = abs(rw_normalangle-rw_angle1);
  403.    
  404.     if (offsetangle > ANG90)
  405.         offsetangle = ANG90;
  406.  
  407.     distangle = ANG90 - offsetangle;
  408.     hyp = R_PointToDist (curline->v1->x, curline->v1->y);
  409.     sineval = finesine[distangle>>ANGLETOFINESHIFT];
  410.     rw_distance = FixedMul (hyp, sineval);
  411.                
  412.        
  413.     ds_p->x1 = rw_x = start;
  414.     ds_p->x2 = stop;
  415.     ds_p->curline = curline;
  416.     rw_stopx = stop+1;
  417.    
  418.     // calculate scale at both ends and step
  419.     ds_p->scale1 = rw_scale =
  420.         R_ScaleFromGlobalAngle (viewangle + xtoviewangle[start]);
  421.    
  422.     if (stop > start )
  423.     {
  424.         ds_p->scale2 = R_ScaleFromGlobalAngle (viewangle + xtoviewangle[stop]);
  425.         ds_p->scalestep = rw_scalestep =
  426.             (ds_p->scale2 - rw_scale) / (stop-start);
  427.     }
  428.     else
  429.     {
  430.         // UNUSED: try to fix the stretched line bug
  431. #if 0
  432.         if (rw_distance < FRACUNIT/2)
  433.         {
  434.             fixed_t             trx,try;
  435.             fixed_t             gxt,gyt;
  436.  
  437.             trx = curline->v1->x - viewx;
  438.             try = curline->v1->y - viewy;
  439.                        
  440.             gxt = FixedMul(trx,viewcos);
  441.             gyt = -FixedMul(try,viewsin);
  442.             ds_p->scale1 = FixedDiv(projection, gxt-gyt)<<detailshift;
  443.         }
  444. #endif
  445.         ds_p->scale2 = ds_p->scale1;
  446.     }
  447.    
  448.     // calculate texture boundaries
  449.     //  and decide if floor / ceiling marks are needed
  450.     worldtop = frontsector->ceilingheight - viewz;
  451.     worldbottom = frontsector->floorheight - viewz;
  452.        
  453.     midtexture = toptexture = bottomtexture = maskedtexture = 0;
  454.     ds_p->maskedtexturecol = NULL;
  455.        
  456.     if (!backsector)
  457.     {
  458.         // single sided line
  459.         midtexture = texturetranslation[sidedef->midtexture];
  460.         // a single sided line is terminal, so it must mark ends
  461.         markfloor = markceiling = true;
  462.         if (linedef->flags & ML_DONTPEGBOTTOM)
  463.         {
  464.             vtop = frontsector->floorheight +
  465.                 textureheight[sidedef->midtexture];
  466.             // bottom of texture at bottom
  467.             rw_midtexturemid = vtop - viewz;   
  468.         }
  469.         else
  470.         {
  471.             // top of texture at top
  472.             rw_midtexturemid = worldtop;
  473.         }
  474.         rw_midtexturemid += sidedef->rowoffset;
  475.  
  476.         ds_p->silhouette = SIL_BOTH;
  477.         ds_p->sprtopclip = screenheightarray;
  478.         ds_p->sprbottomclip = negonearray;
  479.         ds_p->bsilheight = MAXINT;
  480.         ds_p->tsilheight = MININT;
  481.     }
  482.     else
  483.     {
  484.         // two sided line
  485.         ds_p->sprtopclip = ds_p->sprbottomclip = NULL;
  486.         ds_p->silhouette = 0;
  487.        
  488.         if (frontsector->floorheight > backsector->floorheight)
  489.         {
  490.             ds_p->silhouette = SIL_BOTTOM;
  491.             ds_p->bsilheight = frontsector->floorheight;
  492.         }
  493.         else if (backsector->floorheight > viewz)
  494.         {
  495.             ds_p->silhouette = SIL_BOTTOM;
  496.             ds_p->bsilheight = MAXINT;
  497.             // ds_p->sprbottomclip = negonearray;
  498.         }
  499.        
  500.         if (frontsector->ceilingheight < backsector->ceilingheight)
  501.         {
  502.             ds_p->silhouette |= SIL_TOP;
  503.             ds_p->tsilheight = frontsector->ceilingheight;
  504.         }
  505.         else if (backsector->ceilingheight < viewz)
  506.         {
  507.             ds_p->silhouette |= SIL_TOP;
  508.             ds_p->tsilheight = MININT;
  509.             // ds_p->sprtopclip = screenheightarray;
  510.         }
  511.                
  512.         if (backsector->ceilingheight <= frontsector->floorheight)
  513.         {
  514.             ds_p->sprbottomclip = negonearray;
  515.             ds_p->bsilheight = MAXINT;
  516.             ds_p->silhouette |= SIL_BOTTOM;
  517.         }
  518.        
  519.         if (backsector->floorheight >= frontsector->ceilingheight)
  520.         {
  521.             ds_p->sprtopclip = screenheightarray;
  522.             ds_p->tsilheight = MININT;
  523.             ds_p->silhouette |= SIL_TOP;
  524.         }
  525.        
  526.         worldhigh = backsector->ceilingheight - viewz;
  527.         worldlow = backsector->floorheight - viewz;
  528.                
  529.         // hack to allow height changes in outdoor areas
  530.         if (frontsector->ceilingpic == skyflatnum
  531.             && backsector->ceilingpic == skyflatnum)
  532.         {
  533.             worldtop = worldhigh;
  534.         }
  535.        
  536.                        
  537.         if (worldlow != worldbottom
  538.             || backsector->floorpic != frontsector->floorpic
  539.             || backsector->lightlevel != frontsector->lightlevel)
  540.         {
  541.             markfloor = true;
  542.         }
  543.         else
  544.         {
  545.             // same plane on both sides
  546.             markfloor = false;
  547.         }
  548.        
  549.                        
  550.         if (worldhigh != worldtop
  551.             || backsector->ceilingpic != frontsector->ceilingpic
  552.             || backsector->lightlevel != frontsector->lightlevel)
  553.         {
  554.             markceiling = true;
  555.         }
  556.         else
  557.         {
  558.             // same plane on both sides
  559.             markceiling = false;
  560.         }
  561.        
  562.         if (backsector->ceilingheight <= frontsector->floorheight
  563.             || backsector->floorheight >= frontsector->ceilingheight)
  564.         {
  565.             // closed door
  566.             markceiling = markfloor = true;
  567.         }
  568.        
  569.  
  570.         if (worldhigh < worldtop)
  571.         {
  572.             // top texture
  573.             toptexture = texturetranslation[sidedef->toptexture];
  574.             if (linedef->flags & ML_DONTPEGTOP)
  575.             {
  576.                 // top of texture at top
  577.                 rw_toptexturemid = worldtop;
  578.             }
  579.             else
  580.             {
  581.                 vtop =
  582.                     backsector->ceilingheight
  583.                     + textureheight[sidedef->toptexture];
  584.                
  585.                 // bottom of texture
  586.                 rw_toptexturemid = vtop - viewz;       
  587.             }
  588.         }
  589.         if (worldlow > worldbottom)
  590.         {
  591.             // bottom texture
  592.             bottomtexture = texturetranslation[sidedef->bottomtexture];
  593.  
  594.             if (linedef->flags & ML_DONTPEGBOTTOM )
  595.             {
  596.                 // bottom of texture at bottom
  597.                 // top of texture at top
  598.                 rw_bottomtexturemid = worldtop;
  599.             }
  600.             else        // top of texture at top
  601.                 rw_bottomtexturemid = worldlow;
  602.         }
  603.         rw_toptexturemid += sidedef->rowoffset;
  604.         rw_bottomtexturemid += sidedef->rowoffset;
  605.        
  606.         // allocate space for masked texture tables
  607.         if (sidedef->midtexture)
  608.         {
  609.             // masked midtexture
  610.             maskedtexture = true;
  611.             ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x;
  612.             lastopening += rw_stopx - rw_x;
  613.         }
  614.     }
  615.    
  616.     // calculate rw_offset (only needed for textured lines)
  617.     segtextured = midtexture | toptexture | bottomtexture | maskedtexture;
  618.  
  619.     if (segtextured)
  620.     {
  621.         offsetangle = rw_normalangle-rw_angle1;
  622.        
  623.         if (offsetangle > ANG180)
  624.             offsetangle = -offsetangle;
  625.  
  626.         if (offsetangle > ANG90)
  627.             offsetangle = ANG90;
  628.  
  629.         sineval = finesine[offsetangle >>ANGLETOFINESHIFT];
  630.         rw_offset = FixedMul (hyp, sineval);
  631.  
  632.         if (rw_normalangle-rw_angle1 < ANG180)
  633.             rw_offset = -rw_offset;
  634.  
  635.         rw_offset += sidedef->textureoffset + curline->offset;
  636.         rw_centerangle = ANG90 + viewangle - rw_normalangle;
  637.        
  638.         // calculate light table
  639.         //  use different light tables
  640.         //  for horizontal / vertical / diagonal
  641.         // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
  642.         if (!fixedcolormap)
  643.         {
  644.             lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;
  645.  
  646.             if (curline->v1->y == curline->v2->y)
  647.                 lightnum--;
  648.             else if (curline->v1->x == curline->v2->x)
  649.                 lightnum++;
  650.  
  651.             if (lightnum < 0)          
  652.                 walllights = scalelight[0];
  653.             else if (lightnum >= LIGHTLEVELS)
  654.                 walllights = scalelight[LIGHTLEVELS-1];
  655.             else
  656.                 walllights = scalelight[lightnum];
  657.         }
  658.     }
  659.    
  660.     // if a floor / ceiling plane is on the wrong side
  661.     //  of the view plane, it is definitely invisible
  662.     //  and doesn't need to be marked.
  663.    
  664.  
  665.     if (frontsector->floorheight >= viewz)
  666.     {
  667.         // above view plane
  668.         markfloor = false;
  669.     }
  670.    
  671.     if (frontsector->ceilingheight <= viewz
  672.         && frontsector->ceilingpic != skyflatnum)
  673.     {
  674.         // below view plane
  675.         markceiling = false;
  676.     }
  677.  
  678.    
  679.     // calculate incremental stepping values for texture edges
  680.     worldtop >>= 4;
  681.     worldbottom >>= 4;
  682.        
  683.     topstep = -FixedMul (rw_scalestep, worldtop);
  684.     topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale);
  685.  
  686.     bottomstep = -FixedMul (rw_scalestep,worldbottom);
  687.     bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
  688.        
  689.     if (backsector)
  690.     {  
  691.         worldhigh >>= 4;
  692.         worldlow >>= 4;
  693.  
  694.         if (worldhigh < worldtop)
  695.         {
  696.             pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale);
  697.             pixhighstep = -FixedMul (rw_scalestep,worldhigh);
  698.         }
  699.        
  700.         if (worldlow > worldbottom)
  701.         {
  702.             pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
  703.             pixlowstep = -FixedMul (rw_scalestep,worldlow);
  704.         }
  705.     }
  706.    
  707.     // render it
  708.     if (markceiling)
  709.         ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1);
  710.    
  711.     if (markfloor)
  712.         floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1);
  713.  
  714.     R_RenderSegLoop ();
  715.  
  716.    
  717.     // save sprite clipping info
  718.     if ( ((ds_p->silhouette & SIL_TOP) || maskedtexture)
  719.          && !ds_p->sprtopclip)
  720.     {
  721.         memcpy (lastopening, ceilingclip+start, 2*(rw_stopx-start));
  722.         ds_p->sprtopclip = lastopening - start;
  723.         lastopening += rw_stopx - start;
  724.     }
  725.    
  726.     if ( ((ds_p->silhouette & SIL_BOTTOM) || maskedtexture)
  727.          && !ds_p->sprbottomclip)
  728.     {
  729.         memcpy (lastopening, floorclip+start, 2*(rw_stopx-start));
  730.         ds_p->sprbottomclip = lastopening - start;
  731.         lastopening += rw_stopx - start;       
  732.     }
  733.  
  734.     if (maskedtexture && !(ds_p->silhouette&SIL_TOP))
  735.     {
  736.         ds_p->silhouette |= SIL_TOP;
  737.         ds_p->tsilheight = MININT;
  738.     }
  739.     if (maskedtexture && !(ds_p->silhouette&SIL_BOTTOM))
  740.     {
  741.         ds_p->silhouette |= SIL_BOTTOM;
  742.         ds_p->bsilheight = MAXINT;
  743.     }
  744.     ds_p++;
  745. }
  746.  
  747.