r_things.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "Precompiled.h"
  21. #include "globaldata.h"
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include "doomdef.h"
  25. #include "m_swap.h"
  26. #include "i_system.h"
  27. #include "z_zone.h"
  28. #include "w_wad.h"
  29. #include "r_local.h"
  30. #include "doomstat.h"
  31. //void R_DrawColumn (void);
  32. //void R_DrawFuzzColumn (void);
  33. //
  34. // Sprite rotation 0 is facing the viewer,
  35. // rotation 1 is one angle turn CLOCKWISE around the axis.
  36. // This is not the same as the angle,
  37. // which increases counter clockwise (protractor).
  38. // There was a lot of stuff grabbed wrong, so I changed it...
  39. //
  40. // constant arrays
  41. // used for psprite clipping and initializing clipping
  42. //
  43. // INITIALIZATION FUNCTIONS
  44. //
  45. // variables used to look up
  46. // and range check thing_t ::g->sprites patches
  47. //
  48. // R_InstallSpriteLump
  49. // Local function for R_InitSprites.
  50. //
  51. void
  52. R_InstallSpriteLump
  53. ( int lump,
  54. unsigned frame,
  55. unsigned rotation,
  56. qboolean flipped )
  57. {
  58. int r;
  59. if (frame >= 29 || rotation > 8)
  60. I_Error("R_InstallSpriteLump: "
  61. "Bad frame characters in lump %i", lump);
  62. if ((int)frame > ::g->maxframe)
  63. ::g->maxframe = frame;
  64. if (rotation == 0)
  65. {
  66. // the lump should be used for all rotations
  67. if (::g->sprtemp[frame].rotate == false)
  68. I_Error ("R_InitSprites: Sprite %s frame %c has "
  69. "multip rot=0 lump", ::g->spritename, 'A'+frame);
  70. if (::g->sprtemp[frame].rotate == true)
  71. I_Error ("R_InitSprites: Sprite %s frame %c has rotations "
  72. "and a rot=0 lump", ::g->spritename, 'A'+frame);
  73. ::g->sprtemp[frame].rotate = false;
  74. for (r=0 ; r<8 ; r++)
  75. {
  76. ::g->sprtemp[frame].lump[r] = lump - ::g->firstspritelump;
  77. ::g->sprtemp[frame].flip[r] = (byte)flipped;
  78. }
  79. return;
  80. }
  81. // the lump is only used for one rotation
  82. if (::g->sprtemp[frame].rotate == false)
  83. I_Error ("R_InitSprites: Sprite %s frame %c has rotations "
  84. "and a rot=0 lump", ::g->spritename, 'A'+frame);
  85. ::g->sprtemp[frame].rotate = true;
  86. // make 0 based
  87. rotation--;
  88. if (::g->sprtemp[frame].lump[rotation] != -1)
  89. I_Error ("R_InitSprites: Sprite %s : %c : %c "
  90. "has two lumps mapped to it",
  91. ::g->spritename, 'A'+frame, '1'+rotation);
  92. ::g->sprtemp[frame].lump[rotation] = lump - ::g->firstspritelump;
  93. ::g->sprtemp[frame].flip[rotation] = (byte)flipped;
  94. }
  95. //
  96. // R_InitSpriteDefs
  97. // Pass a null terminated list of sprite names
  98. // (4 chars exactly) to be used.
  99. // Builds the sprite rotation matrixes to account
  100. // for horizontally flipped ::g->sprites.
  101. // Will report an error if the lumps are inconsistant.
  102. // Only called at startup.
  103. //
  104. // Sprite lump names are 4 characters for the actor,
  105. // a letter for the frame, and a number for the rotation.
  106. // A sprite that is flippable will have an additional
  107. // letter/number appended.
  108. // The rotation character can be 0 to signify no rotations.
  109. //
  110. void R_InitSpriteDefs (const char* const* namelist)
  111. {
  112. const char* const* check;
  113. int i;
  114. int l;
  115. int intname;
  116. int frame;
  117. int rotation;
  118. int start;
  119. int end;
  120. int patched;
  121. // count the number of sprite names
  122. check = namelist;
  123. while (*check != NULL)
  124. check++;
  125. ::g->numsprites = check-namelist;
  126. if (!::g->numsprites)
  127. return;
  128. ::g->sprites = (spritedef_t*)DoomLib::Z_Malloc(::g->numsprites *sizeof(*::g->sprites), PU_STATIC, NULL);
  129. start = ::g->firstspritelump-1;
  130. end = ::g->lastspritelump+1;
  131. // scan all the lump names for each of the names,
  132. // noting the highest frame letter.
  133. // Just compare 4 characters as ints
  134. for (i=0 ; i < ::g->numsprites ; i++)
  135. {
  136. ::g->spritename = namelist[i];
  137. memset (::g->sprtemp,-1, sizeof(::g->sprtemp));
  138. ::g->maxframe = -1;
  139. intname = *(int *)namelist[i];
  140. // scan the lumps,
  141. // filling in the frames for whatever is found
  142. for (l=start+1 ; l<end ; l++)
  143. {
  144. if (*(int *)lumpinfo[l].name == intname)
  145. {
  146. frame = lumpinfo[l].name[4] - 'A';
  147. rotation = lumpinfo[l].name[5] - '0';
  148. if (::g->modifiedgame)
  149. patched = W_GetNumForName (lumpinfo[l].name);
  150. else
  151. patched = l;
  152. R_InstallSpriteLump (patched, frame, rotation, false);
  153. if (lumpinfo[l].name[6])
  154. {
  155. frame = lumpinfo[l].name[6] - 'A';
  156. rotation = lumpinfo[l].name[7] - '0';
  157. R_InstallSpriteLump (l, frame, rotation, true);
  158. }
  159. }
  160. }
  161. // check the frames that were found for completeness
  162. if (::g->maxframe == -1)
  163. {
  164. ::g->sprites[i].numframes = 0;
  165. continue;
  166. }
  167. ::g->maxframe++;
  168. for (frame = 0 ; frame < ::g->maxframe ; frame++)
  169. {
  170. switch ((int)::g->sprtemp[frame].rotate)
  171. {
  172. case -1:
  173. // no rotations were found for that frame at all
  174. I_Error ("R_InitSprites: No patches found "
  175. "for %s frame %c", namelist[i], frame+'A');
  176. break;
  177. case 0:
  178. // only the first rotation is needed
  179. break;
  180. case 1:
  181. // must have all 8 frames
  182. for (rotation=0 ; rotation<8 ; rotation++)
  183. if (::g->sprtemp[frame].lump[rotation] == -1)
  184. I_Error ("R_InitSprites: Sprite %s frame %c "
  185. "is missing rotations",
  186. namelist[i], frame+'A');
  187. break;
  188. }
  189. }
  190. // allocate space for the frames present and copy ::g->sprtemp to it
  191. ::g->sprites[i].numframes = ::g->maxframe;
  192. ::g->sprites[i].spriteframes =
  193. (spriteframe_t*)DoomLib::Z_Malloc (::g->maxframe * sizeof(spriteframe_t), PU_STATIC, NULL);
  194. memcpy (::g->sprites[i].spriteframes, ::g->sprtemp, ::g->maxframe*sizeof(spriteframe_t));
  195. }
  196. }
  197. //
  198. // GAME FUNCTIONS
  199. //
  200. //
  201. // R_InitSprites
  202. // Called at program start.
  203. //
  204. void R_InitSprites (const char* const* namelist)
  205. {
  206. int i;
  207. for (i=0 ; i<SCREENWIDTH ; i++)
  208. {
  209. ::g->negonearray[i] = -1;
  210. }
  211. R_InitSpriteDefs (namelist);
  212. }
  213. //
  214. // R_ClearSprites
  215. // Called at frame start.
  216. //
  217. void R_ClearSprites (void)
  218. {
  219. ::g->vissprite_p = ::g->vissprites;
  220. }
  221. //
  222. // R_NewVisSprite
  223. //
  224. vissprite_t* R_NewVisSprite (void)
  225. {
  226. if (::g->vissprite_p == &::g->vissprites[MAXVISSPRITES])
  227. return &::g->overflowsprite;
  228. ::g->vissprite_p++;
  229. return ::g->vissprite_p-1;
  230. }
  231. //
  232. // R_DrawMaskedColumn
  233. // Used for ::g->sprites and masked mid textures.
  234. // Masked means: partly transparent, i.e. stored
  235. // in posts/runs of opaque pixels.
  236. //
  237. void R_DrawMaskedColumn (postColumn_t* column)
  238. {
  239. int topscreen;
  240. int bottomscreen;
  241. fixed_t basetexturemid;
  242. basetexturemid = ::g->dc_texturemid;
  243. for ( ; column->topdelta != 0xff ; )
  244. {
  245. // calculate unclipped screen coordinates
  246. // for post
  247. topscreen = ::g->sprtopscreen + ::g->spryscale*column->topdelta;
  248. bottomscreen = topscreen + ::g->spryscale*column->length;
  249. ::g->dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
  250. ::g->dc_yh = (bottomscreen-1)>>FRACBITS;
  251. if (::g->dc_yh >= ::g->mfloorclip[::g->dc_x])
  252. ::g->dc_yh = ::g->mfloorclip[::g->dc_x]-1;
  253. if (::g->dc_yl <= ::g->mceilingclip[::g->dc_x])
  254. ::g->dc_yl = ::g->mceilingclip[::g->dc_x]+1;
  255. if (::g->dc_yl <= ::g->dc_yh)
  256. {
  257. ::g->dc_source = (byte *)column + 3;
  258. ::g->dc_texturemid = basetexturemid - (column->topdelta<<FRACBITS);
  259. // ::g->dc_source = (byte *)column + 3 - column->topdelta;
  260. // Drawn by either R_DrawColumn
  261. // or (SHADOW) R_DrawFuzzColumn.
  262. colfunc ( ::g->dc_colormap, ::g->dc_source );
  263. }
  264. column = (postColumn_t *)( (byte *)column + column->length + 4);
  265. }
  266. ::g->dc_texturemid = basetexturemid;
  267. }
  268. //
  269. // R_DrawVisSprite
  270. // ::g->mfloorclip and ::g->mceilingclip should also be set.
  271. //
  272. void
  273. R_DrawVisSprite
  274. ( vissprite_t* vis,
  275. int x1,
  276. int x2 )
  277. {
  278. postColumn_t* column;
  279. int texturecolumn;
  280. fixed_t frac;
  281. patch_t* patch;
  282. patch = (patch_t*)W_CacheLumpNum (vis->patch+::g->firstspritelump, PU_CACHE_SHARED);
  283. ::g->dc_colormap = vis->colormap;
  284. if (!::g->dc_colormap)
  285. {
  286. // NULL colormap = shadow draw
  287. colfunc = fuzzcolfunc;
  288. }
  289. else if (vis->mobjflags & MF_TRANSLATION)
  290. {
  291. colfunc = R_DrawTranslatedColumn;
  292. ::g->dc_translation = ::g->translationtables - 256 +
  293. ( (vis->mobjflags & MF_TRANSLATION) >> (MF_TRANSSHIFT-8) );
  294. }
  295. ::g->dc_iscale = abs(vis->xiscale)>>::g->detailshift;
  296. ::g->dc_texturemid = vis->texturemid;
  297. frac = vis->startfrac;
  298. ::g->spryscale = vis->scale;
  299. ::g->sprtopscreen = ::g->centeryfrac - FixedMul(::g->dc_texturemid,::g->spryscale);
  300. for (::g->dc_x=vis->x1 ; ::g->dc_x<=vis->x2 ; ::g->dc_x++, frac += vis->xiscale)
  301. {
  302. texturecolumn = frac>>FRACBITS;
  303. #ifdef RANGECHECK
  304. if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
  305. I_Error ("R_DrawSpriteRange: bad texturecolumn");
  306. #endif
  307. column = (postColumn_t *) ((byte *)patch +
  308. LONG(patch->columnofs[texturecolumn]));
  309. R_DrawMaskedColumn (column);
  310. }
  311. colfunc = basecolfunc;
  312. }
  313. //
  314. // R_ProjectSprite
  315. // Generates a vissprite for a thing
  316. // if it might be visible.
  317. //
  318. void R_ProjectSprite (mobj_t* thing)
  319. {
  320. fixed_t tr_x;
  321. fixed_t tr_y;
  322. fixed_t gxt;
  323. fixed_t gyt;
  324. fixed_t tx;
  325. fixed_t tz;
  326. fixed_t xscale;
  327. int x1;
  328. int x2;
  329. spritedef_t* sprdef;
  330. spriteframe_t* sprframe;
  331. int lump;
  332. unsigned rot;
  333. qboolean flip;
  334. int index;
  335. vissprite_t* vis;
  336. angle_t ang;
  337. fixed_t iscale;
  338. // transform the origin point
  339. extern fixed_t GetViewX(); extern fixed_t GetViewY();
  340. tr_x = thing->x - GetViewX();
  341. tr_y = thing->y - GetViewY();
  342. gxt = FixedMul(tr_x,::g->viewcos);
  343. gyt = -FixedMul(tr_y,::g->viewsin);
  344. tz = gxt-gyt;
  345. // thing is behind view plane?
  346. if (tz < MINZ)
  347. return;
  348. xscale = FixedDiv(::g->projection, tz);
  349. gxt = -FixedMul(tr_x,::g->viewsin);
  350. gyt = FixedMul(tr_y,::g->viewcos);
  351. tx = -(gyt+gxt);
  352. // too far off the side?
  353. if (abs(tx)>(tz<<2))
  354. return;
  355. // decide which patch to use for sprite relative to player
  356. #ifdef RANGECHECK
  357. if (thing->sprite >= ::g->numsprites)
  358. I_Error ("R_ProjectSprite: invalid sprite number %i ",
  359. thing->sprite);
  360. #endif
  361. sprdef = &::g->sprites[thing->sprite];
  362. #ifdef RANGECHECK
  363. if ( (thing->frame&FF_FRAMEMASK) >= sprdef->numframes )
  364. I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ",
  365. thing->sprite, thing->frame);
  366. #endif
  367. sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK];
  368. if (sprframe->rotate)
  369. {
  370. // choose a different rotation based on player view
  371. ang = R_PointToAngle (thing->x, thing->y);
  372. rot = (ang-thing->angle+(unsigned)(ANG45/2)*9)>>29;
  373. lump = sprframe->lump[rot];
  374. flip = (qboolean)sprframe->flip[rot];
  375. }
  376. else
  377. {
  378. // use single rotation for all views
  379. lump = sprframe->lump[0];
  380. flip = (qboolean)sprframe->flip[0];
  381. }
  382. // calculate edges of the shape
  383. tx -= ::g->spriteoffset[lump];
  384. x1 = (::g->centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS;
  385. // off the right side?
  386. if (x1 > ::g->viewwidth)
  387. return;
  388. tx += ::g->spritewidth[lump];
  389. x2 = ((::g->centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS) - 1;
  390. // off the left side
  391. if (x2 < 0)
  392. return;
  393. // store information in a vissprite
  394. vis = R_NewVisSprite ();
  395. vis->mobjflags = thing->flags;
  396. vis->scale = xscale << ::g->detailshift;
  397. vis->gx = thing->x;
  398. vis->gy = thing->y;
  399. vis->gz = thing->z;
  400. vis->gzt = thing->z + ::g->spritetopoffset[lump];
  401. vis->texturemid = vis->gzt - ::g->viewz;
  402. vis->x1 = x1 < 0 ? 0 : x1;
  403. vis->x2 = x2 >= ::g->viewwidth ? ::g->viewwidth-1 : x2;
  404. iscale = FixedDiv (FRACUNIT, xscale);
  405. if (flip)
  406. {
  407. vis->startfrac = ::g->spritewidth[lump]-1;
  408. vis->xiscale = -iscale;
  409. }
  410. else
  411. {
  412. vis->startfrac = 0;
  413. vis->xiscale = iscale;
  414. }
  415. if (vis->x1 > x1)
  416. vis->startfrac += vis->xiscale*(vis->x1-x1);
  417. vis->patch = lump;
  418. // get light level
  419. if (thing->flags & MF_SHADOW)
  420. {
  421. // shadow draw
  422. vis->colormap = NULL;
  423. }
  424. else if (::g->fixedcolormap)
  425. {
  426. // fixed map
  427. vis->colormap = ::g->fixedcolormap;
  428. }
  429. else if (thing->frame & FF_FULLBRIGHT)
  430. {
  431. // full bright
  432. vis->colormap = ::g->colormaps;
  433. }
  434. else
  435. {
  436. // diminished light
  437. index = xscale>>(LIGHTSCALESHIFT-::g->detailshift);
  438. if (index >= MAXLIGHTSCALE)
  439. index = MAXLIGHTSCALE-1;
  440. vis->colormap = ::g->spritelights[index];
  441. }
  442. }
  443. //
  444. // R_AddSprites
  445. // During BSP traversal, this adds ::g->sprites by sector.
  446. //
  447. void R_AddSprites (sector_t* sec)
  448. {
  449. mobj_t* thing;
  450. int lightnum;
  451. // BSP is traversed by subsector.
  452. // A sector might have been split into several
  453. // ::g->subsectors during BSP building.
  454. // Thus we check whether its already added.
  455. if (sec->validcount == ::g->validcount)
  456. return;
  457. // Well, now it will be done.
  458. sec->validcount = ::g->validcount;
  459. lightnum = (sec->lightlevel >> LIGHTSEGSHIFT)+::g->extralight;
  460. if (lightnum < 0)
  461. ::g->spritelights = ::g->scalelight[0];
  462. else if (lightnum >= LIGHTLEVELS)
  463. ::g->spritelights = ::g->scalelight[LIGHTLEVELS-1];
  464. else
  465. ::g->spritelights = ::g->scalelight[lightnum];
  466. // Handle all things in sector.
  467. for (thing = sec->thinglist ; thing ; thing = thing->snext)
  468. R_ProjectSprite (thing);
  469. }
  470. //
  471. // R_DrawPSprite
  472. //
  473. void R_DrawPSprite (pspdef_t* psp)
  474. {
  475. fixed_t tx;
  476. int x1;
  477. int x2;
  478. spritedef_t* sprdef;
  479. spriteframe_t* sprframe;
  480. int lump;
  481. qboolean flip;
  482. vissprite_t* vis;
  483. vissprite_t avis;
  484. // decide which patch to use
  485. #ifdef RANGECHECK
  486. if ( psp->state->sprite >= ::g->numsprites)
  487. I_Error ("R_ProjectSprite: invalid sprite number %i ",
  488. psp->state->sprite);
  489. #endif
  490. sprdef = &::g->sprites[psp->state->sprite];
  491. #ifdef RANGECHECK
  492. if ( (psp->state->frame & FF_FRAMEMASK) >= sprdef->numframes)
  493. I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ",
  494. psp->state->sprite, psp->state->frame);
  495. #endif
  496. sprframe = &sprdef->spriteframes[ psp->state->frame & FF_FRAMEMASK ];
  497. lump = sprframe->lump[0];
  498. flip = (qboolean)sprframe->flip[0];
  499. // calculate edges of the shape
  500. tx = psp->sx-160*FRACUNIT;
  501. tx -= ::g->spriteoffset[lump];
  502. x1 = (::g->centerxfrac + FixedMul (tx,::g->pspritescale) ) >>FRACBITS;
  503. // off the right side
  504. if (x1 > ::g->viewwidth)
  505. return;
  506. tx += ::g->spritewidth[lump];
  507. x2 = ((::g->centerxfrac + FixedMul (tx, ::g->pspritescale) ) >>FRACBITS) - 1;
  508. // off the left side
  509. if (x2 < 0)
  510. return;
  511. // store information in a vissprite
  512. vis = &avis;
  513. vis->mobjflags = 0;
  514. vis->texturemid = (BASEYCENTER<<FRACBITS)+FRACUNIT/2-(psp->sy-::g->spritetopoffset[lump]);
  515. vis->x1 = x1 < 0 ? 0 : x1;
  516. vis->x2 = x2 >= ::g->viewwidth ? ::g->viewwidth-1 : x2;
  517. vis->scale = ::g->pspritescale << ::g->detailshift;
  518. if (flip)
  519. {
  520. vis->xiscale = -::g->pspriteiscale;
  521. vis->startfrac = ::g->spritewidth[lump]-1;
  522. }
  523. else
  524. {
  525. vis->xiscale = ::g->pspriteiscale;
  526. vis->startfrac = 0;
  527. }
  528. if (vis->x1 > x1)
  529. vis->startfrac += vis->xiscale*(vis->x1-x1);
  530. vis->patch = lump;
  531. if (::g->viewplayer->powers[pw_invisibility] > 4*32
  532. || ::g->viewplayer->powers[pw_invisibility] & 8)
  533. {
  534. // shadow draw
  535. vis->colormap = NULL;
  536. }
  537. else if (::g->fixedcolormap)
  538. {
  539. // fixed color
  540. vis->colormap = ::g->fixedcolormap;
  541. }
  542. else if (psp->state->frame & FF_FULLBRIGHT)
  543. {
  544. // full bright
  545. vis->colormap = ::g->colormaps;
  546. }
  547. else
  548. {
  549. // local light
  550. vis->colormap = ::g->spritelights[MAXLIGHTSCALE-1];
  551. }
  552. R_DrawVisSprite (vis, vis->x1, vis->x2);
  553. }
  554. //
  555. // R_DrawPlayerSprites
  556. //
  557. void R_DrawPlayerSprites (void)
  558. {
  559. int i;
  560. int lightnum;
  561. pspdef_t* psp;
  562. // get light level
  563. lightnum =
  564. (::g->viewplayer->mo->subsector->sector->lightlevel >> LIGHTSEGSHIFT)
  565. +::g->extralight;
  566. if (lightnum < 0)
  567. ::g->spritelights = ::g->scalelight[0];
  568. else if (lightnum >= LIGHTLEVELS)
  569. ::g->spritelights = ::g->scalelight[LIGHTLEVELS-1];
  570. else
  571. ::g->spritelights = ::g->scalelight[lightnum];
  572. // clip to screen bounds
  573. ::g->mfloorclip = ::g->screenheightarray;
  574. ::g->mceilingclip = ::g->negonearray;
  575. // add all active psprites
  576. for (i=0, psp=::g->viewplayer->psprites;
  577. i<NUMPSPRITES;
  578. i++,psp++)
  579. {
  580. if (psp->state)
  581. R_DrawPSprite (psp);
  582. }
  583. }
  584. //
  585. // R_SortVisSprites
  586. //
  587. void R_SortVisSprites (void)
  588. {
  589. int i;
  590. int count;
  591. vissprite_t* ds = NULL;
  592. vissprite_t* best = NULL;
  593. vissprite_t unsorted;
  594. fixed_t bestscale;
  595. count = ::g->vissprite_p - ::g->vissprites;
  596. unsorted.next = unsorted.prev = &unsorted;
  597. if (!count)
  598. return;
  599. for (ds=::g->vissprites ; ds < ::g->vissprite_p ; ds++)
  600. {
  601. ds->next = ds+1;
  602. ds->prev = ds-1;
  603. }
  604. ::g->vissprites[0].prev = &unsorted;
  605. unsorted.next = &::g->vissprites[0];
  606. (::g->vissprite_p-1)->next = &unsorted;
  607. unsorted.prev = ::g->vissprite_p-1;
  608. // pull the ::g->vissprites out by scale
  609. //best = 0; // shut up the compiler warning
  610. ::g->vsprsortedhead.next = ::g->vsprsortedhead.prev = &::g->vsprsortedhead;
  611. for (i=0 ; i<count ; i++)
  612. {
  613. bestscale = MAXINT;
  614. for (ds=unsorted.next ; ds!= &unsorted ; ds=ds->next)
  615. {
  616. if (ds->scale < bestscale)
  617. {
  618. bestscale = ds->scale;
  619. best = ds;
  620. }
  621. }
  622. best->next->prev = best->prev;
  623. best->prev->next = best->next;
  624. best->next = &::g->vsprsortedhead;
  625. best->prev = ::g->vsprsortedhead.prev;
  626. ::g->vsprsortedhead.prev->next = best;
  627. ::g->vsprsortedhead.prev = best;
  628. }
  629. }
  630. //
  631. // R_DrawSprite
  632. //
  633. void R_DrawSprite (vissprite_t* spr)
  634. {
  635. drawseg_t* ds;
  636. short clipbot[SCREENWIDTH];
  637. short cliptop[SCREENWIDTH];
  638. int x;
  639. int r1;
  640. int r2;
  641. fixed_t scale;
  642. fixed_t lowscale;
  643. int silhouette;
  644. for (x = spr->x1 ; x<=spr->x2 ; x++)
  645. clipbot[x] = cliptop[x] = -2;
  646. // Scan ::g->drawsegs from end to start for obscuring ::g->segs.
  647. // The first drawseg that has a greater scale
  648. // is the clip seg.
  649. for (ds=::g->ds_p-1 ; ds >= ::g->drawsegs ; ds--)
  650. {
  651. // determine if the drawseg obscures the sprite
  652. if (ds->x1 > spr->x2
  653. || ds->x2 < spr->x1
  654. || (!ds->silhouette
  655. && !ds->maskedtexturecol) )
  656. {
  657. // does not cover sprite
  658. continue;
  659. }
  660. r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1;
  661. r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2;
  662. if (ds->scale1 > ds->scale2)
  663. {
  664. lowscale = ds->scale2;
  665. scale = ds->scale1;
  666. }
  667. else
  668. {
  669. lowscale = ds->scale1;
  670. scale = ds->scale2;
  671. }
  672. if (scale < spr->scale
  673. || ( lowscale < spr->scale
  674. && !R_PointOnSegSide (spr->gx, spr->gy, ds->curline) ) )
  675. {
  676. // masked mid texture?
  677. if (ds->maskedtexturecol)
  678. R_RenderMaskedSegRange (ds, r1, r2);
  679. // seg is behind sprite
  680. continue;
  681. }
  682. // clip this piece of the sprite
  683. silhouette = ds->silhouette;
  684. if (spr->gz >= ds->bsilheight)
  685. silhouette &= ~SIL_BOTTOM;
  686. if (spr->gzt <= ds->tsilheight)
  687. silhouette &= ~SIL_TOP;
  688. if (silhouette == 1)
  689. {
  690. // bottom sil
  691. for (x=r1 ; x<=r2 ; x++)
  692. if (clipbot[x] == -2)
  693. clipbot[x] = ds->sprbottomclip[x];
  694. }
  695. else if (silhouette == 2)
  696. {
  697. // top sil
  698. for (x=r1 ; x<=r2 ; x++)
  699. if (cliptop[x] == -2)
  700. cliptop[x] = ds->sprtopclip[x];
  701. }
  702. else if (silhouette == 3)
  703. {
  704. // both
  705. for (x=r1 ; x<=r2 ; x++)
  706. {
  707. if (clipbot[x] == -2)
  708. clipbot[x] = ds->sprbottomclip[x];
  709. if (cliptop[x] == -2)
  710. cliptop[x] = ds->sprtopclip[x];
  711. }
  712. }
  713. }
  714. // all clipping has been performed, so draw the sprite
  715. // check for unclipped columns
  716. for (x = spr->x1 ; x<=spr->x2 ; x++)
  717. {
  718. if (clipbot[x] == -2)
  719. clipbot[x] = ::g->viewheight;
  720. if (cliptop[x] == -2)
  721. cliptop[x] = -1;
  722. }
  723. ::g->mfloorclip = clipbot;
  724. ::g->mceilingclip = cliptop;
  725. R_DrawVisSprite (spr, spr->x1, spr->x2);
  726. }
  727. //
  728. // R_DrawMasked
  729. //
  730. void R_DrawMasked (void)
  731. {
  732. vissprite_t* spr;
  733. drawseg_t* ds;
  734. R_SortVisSprites ();
  735. if (::g->vissprite_p > ::g->vissprites)
  736. {
  737. // draw all ::g->vissprites back to front
  738. for (spr = ::g->vsprsortedhead.next ;
  739. spr != &::g->vsprsortedhead ;
  740. spr=spr->next)
  741. {
  742. R_DrawSprite (spr);
  743. }
  744. }
  745. // render any remaining masked mid textures
  746. for (ds=::g->ds_p-1 ; ds >= ::g->drawsegs ; ds--)
  747. if (ds->maskedtexturecol)
  748. R_RenderMaskedSegRange (ds, ds->x1, ds->x2);
  749. // draw the psprites on top of everything
  750. // but does not draw on side views
  751. if (!::g->viewangleoffset)
  752. R_DrawPlayerSprites ();
  753. }