r_segs.c 17 KB

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