home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser-CD 2000 January / LCD_01_2000.iso / games / doom / pmdoom / src / r_segs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-17  |  17.4 KB  |  732 lines

  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=0;
  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.     ds_p->scale2 = ds_p->scale1;
  431.     }
  432.     
  433.     /*  calculate texture boundaries */
  434.     /*   and decide if floor / ceiling marks are needed */
  435.     worldtop = frontsector->ceilingheight - viewz;
  436.     worldbottom = frontsector->floorheight - viewz;
  437.     
  438.     midtexture = toptexture = bottomtexture = maskedtexture = 0;
  439.     ds_p->maskedtexturecol = NULL;
  440.     
  441.     if (!backsector)
  442.     {
  443.     /*  single sided line */
  444.     midtexture = texturetranslation[sidedef->midtexture];
  445.     /*  a single sided line is terminal, so it must mark ends */
  446.     markfloor = markceiling = true;
  447.     if (linedef->flags & ML_DONTPEGBOTTOM)
  448.     {
  449.         vtop = frontsector->floorheight +
  450.         textureheight[sidedef->midtexture];
  451.         /*  bottom of texture at bottom */
  452.         rw_midtexturemid = vtop - viewz;    
  453.     }
  454.     else
  455.     {
  456.         /*  top of texture at top */
  457.         rw_midtexturemid = worldtop;
  458.     }
  459.     rw_midtexturemid += sidedef->rowoffset;
  460.  
  461.     ds_p->silhouette = SIL_BOTH;
  462.     ds_p->sprtopclip = screenheightarray;
  463.     ds_p->sprbottomclip = negonearray;
  464.     ds_p->bsilheight = MAXINT;
  465.     ds_p->tsilheight = MININT;
  466.     }
  467.     else
  468.     {
  469.     /*  two sided line */
  470.     ds_p->sprtopclip = ds_p->sprbottomclip = NULL;
  471.     ds_p->silhouette = 0;
  472.     
  473.     if (frontsector->floorheight > backsector->floorheight)
  474.     {
  475.         ds_p->silhouette = SIL_BOTTOM;
  476.         ds_p->bsilheight = frontsector->floorheight;
  477.     }
  478.     else if (backsector->floorheight > viewz)
  479.     {
  480.         ds_p->silhouette = SIL_BOTTOM;
  481.         ds_p->bsilheight = MAXINT;
  482.         /*  ds_p->sprbottomclip = negonearray; */
  483.     }
  484.     
  485.     if (frontsector->ceilingheight < backsector->ceilingheight)
  486.     {
  487.         ds_p->silhouette |= SIL_TOP;
  488.         ds_p->tsilheight = frontsector->ceilingheight;
  489.     }
  490.     else if (backsector->ceilingheight < viewz)
  491.     {
  492.         ds_p->silhouette |= SIL_TOP;
  493.         ds_p->tsilheight = MININT;
  494.         /*  ds_p->sprtopclip = screenheightarray; */
  495.     }
  496.         
  497.     if (backsector->ceilingheight <= frontsector->floorheight)
  498.     {
  499.         ds_p->sprbottomclip = negonearray;
  500.         ds_p->bsilheight = MAXINT;
  501.         ds_p->silhouette |= SIL_BOTTOM;
  502.     }
  503.     
  504.     if (backsector->floorheight >= frontsector->ceilingheight)
  505.     {
  506.         ds_p->sprtopclip = screenheightarray;
  507.         ds_p->tsilheight = MININT;
  508.         ds_p->silhouette |= SIL_TOP;
  509.     }
  510.     
  511.     worldhigh = backsector->ceilingheight - viewz;
  512.     worldlow = backsector->floorheight - viewz;
  513.         
  514.     /*  hack to allow height changes in outdoor areas */
  515.     if (frontsector->ceilingpic == skyflatnum 
  516.         && backsector->ceilingpic == skyflatnum)
  517.     {
  518.         worldtop = worldhigh;
  519.     }
  520.     
  521.             
  522.     if (worldlow != worldbottom 
  523.         || backsector->floorpic != frontsector->floorpic
  524.         || backsector->lightlevel != frontsector->lightlevel)
  525.     {
  526.         markfloor = true;
  527.     }
  528.     else
  529.     {
  530.         /*  same plane on both sides */
  531.         markfloor = false;
  532.     }
  533.     
  534.             
  535.     if (worldhigh != worldtop 
  536.         || backsector->ceilingpic != frontsector->ceilingpic
  537.         || backsector->lightlevel != frontsector->lightlevel)
  538.     {
  539.         markceiling = true;
  540.     }
  541.     else
  542.     {
  543.         /*  same plane on both sides */
  544.         markceiling = false;
  545.     }
  546.     
  547.     if (backsector->ceilingheight <= frontsector->floorheight
  548.         || backsector->floorheight >= frontsector->ceilingheight)
  549.     {
  550.         /*  closed door */
  551.         markceiling = markfloor = true;
  552.     }
  553.     
  554.  
  555.     if (worldhigh < worldtop)
  556.     {
  557.         /*  top texture */
  558.         toptexture = texturetranslation[sidedef->toptexture];
  559.         if (linedef->flags & ML_DONTPEGTOP)
  560.         {
  561.         /*  top of texture at top */
  562.         rw_toptexturemid = worldtop;
  563.         }
  564.         else
  565.         {
  566.         vtop =
  567.             backsector->ceilingheight
  568.             + textureheight[sidedef->toptexture];
  569.         
  570.         /*  bottom of texture */
  571.         rw_toptexturemid = vtop - viewz;    
  572.         }
  573.     }
  574.     if (worldlow > worldbottom)
  575.     {
  576.         /*  bottom texture */
  577.         bottomtexture = texturetranslation[sidedef->bottomtexture];
  578.  
  579.         if (linedef->flags & ML_DONTPEGBOTTOM )
  580.         {
  581.         /*  bottom of texture at bottom */
  582.         /*  top of texture at top */
  583.         rw_bottomtexturemid = worldtop;
  584.         }
  585.         else    /*  top of texture at top */
  586.         rw_bottomtexturemid = worldlow;
  587.     }
  588.     rw_toptexturemid += sidedef->rowoffset;
  589.     rw_bottomtexturemid += sidedef->rowoffset;
  590.     
  591.     /*  allocate space for masked texture tables */
  592.     if (sidedef->midtexture)
  593.     {
  594.         /*  masked midtexture */
  595.         maskedtexture = true;
  596.         ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x;
  597.         lastopening += rw_stopx - rw_x;
  598.     }
  599.     }
  600.     
  601.     /*  calculate rw_offset (only needed for textured lines) */
  602.     segtextured = midtexture | toptexture | bottomtexture | maskedtexture;
  603.  
  604.     if (segtextured)
  605.     {
  606.     offsetangle = rw_normalangle-rw_angle1;
  607.     
  608.     if (offsetangle > ANG180)
  609.         offsetangle = -offsetangle;
  610.  
  611.     if (offsetangle > ANG90)
  612.         offsetangle = ANG90;
  613.  
  614.     sineval = finesine[offsetangle >>ANGLETOFINESHIFT];
  615.     rw_offset = FixedMul (hyp, sineval);
  616.  
  617.     if (rw_normalangle-rw_angle1 < ANG180)
  618.         rw_offset = -rw_offset;
  619.  
  620.     rw_offset += sidedef->textureoffset + curline->offset;
  621.     rw_centerangle = ANG90 + viewangle - rw_normalangle;
  622.     
  623.     /*  calculate light table */
  624.     /*   use different light tables */
  625.     /*   for horizontal / vertical / diagonal */
  626.     /*  OPTIMIZE: get rid of LIGHTSEGSHIFT globally */
  627.     if (!fixedcolormap)
  628.     {
  629.         lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;
  630.  
  631.         if (curline->v1->y == curline->v2->y)
  632.         lightnum--;
  633.         else if (curline->v1->x == curline->v2->x)
  634.         lightnum++;
  635.  
  636.         if (lightnum < 0)        
  637.         walllights = scalelight[0];
  638.         else if (lightnum >= LIGHTLEVELS)
  639.         walllights = scalelight[LIGHTLEVELS-1];
  640.         else
  641.         walllights = scalelight[lightnum];
  642.     }
  643.     }
  644.     
  645.     /*  if a floor / ceiling plane is on the wrong side */
  646.     /*   of the view plane, it is definitely invisible */
  647.     /*   and doesn't need to be marked. */
  648.     
  649.   
  650.     if (frontsector->floorheight >= viewz)
  651.     {
  652.     /*  above view plane */
  653.     markfloor = false;
  654.     }
  655.     
  656.     if (frontsector->ceilingheight <= viewz 
  657.     && frontsector->ceilingpic != skyflatnum)
  658.     {
  659.     /*  below view plane */
  660.     markceiling = false;
  661.     }
  662.  
  663.     
  664.     /*  calculate incremental stepping values for texture edges */
  665.     worldtop >>= 4;
  666.     worldbottom >>= 4;
  667.     
  668.     topstep = -FixedMul (rw_scalestep, worldtop);
  669.     topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale);
  670.  
  671.     bottomstep = -FixedMul (rw_scalestep,worldbottom);
  672.     bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
  673.     
  674.     if (backsector)
  675.     {    
  676.     worldhigh >>= 4;
  677.     worldlow >>= 4;
  678.  
  679.     if (worldhigh < worldtop)
  680.     {
  681.         pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale);
  682.         pixhighstep = -FixedMul (rw_scalestep,worldhigh);
  683.     }
  684.     
  685.     if (worldlow > worldbottom)
  686.     {
  687.         pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
  688.         pixlowstep = -FixedMul (rw_scalestep,worldlow);
  689.     }
  690.     }
  691.     
  692.     /*  render it */
  693.     if (markceiling)
  694.     ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1);
  695.     
  696.     if (markfloor)
  697.     floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1);
  698.  
  699.     R_RenderSegLoop ();
  700.  
  701.     
  702.     /*  save sprite clipping info */
  703.     if ( ((ds_p->silhouette & SIL_TOP) || maskedtexture)
  704.      && !ds_p->sprtopclip)
  705.     {
  706.     memcpy (lastopening, ceilingclip+start, 2*(rw_stopx-start));
  707.     ds_p->sprtopclip = lastopening - start;
  708.     lastopening += rw_stopx - start;
  709.     }
  710.     
  711.     if ( ((ds_p->silhouette & SIL_BOTTOM) || maskedtexture)
  712.      && !ds_p->sprbottomclip)
  713.     {
  714.     memcpy (lastopening, floorclip+start, 2*(rw_stopx-start));
  715.     ds_p->sprbottomclip = lastopening - start;
  716.     lastopening += rw_stopx - start;    
  717.     }
  718.  
  719.     if (maskedtexture && !(ds_p->silhouette&SIL_TOP))
  720.     {
  721.     ds_p->silhouette |= SIL_TOP;
  722.     ds_p->tsilheight = MININT;
  723.     }
  724.     if (maskedtexture && !(ds_p->silhouette&SIL_BOTTOM))
  725.     {
  726.     ds_p->silhouette |= SIL_BOTTOM;
  727.     ds_p->bsilheight = MAXINT;
  728.     }
  729.     ds_p++;
  730. }
  731.  
  732.