R_THINGS.C 22 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034
  1. //**************************************************************************
  2. //**
  3. //** r_things.c : Heretic 2 : Raven Software, Corp.
  4. //**
  5. //** $RCSfile: r_things.c,v $
  6. //** $Revision: 1.26 $
  7. //** $Date: 96/01/06 18:37:42 $
  8. //** $Author: bgokey $
  9. //**
  10. //**************************************************************************
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include "h2def.h"
  14. #include "r_local.h"
  15. void R_DrawColumn (void);
  16. void R_DrawFuzzColumn (void);
  17. void R_DrawAltFuzzColumn(void);
  18. //void R_DrawTranslatedAltFuzzColumn(void);
  19. typedef struct
  20. {
  21. int x1, x2;
  22. int column;
  23. int topclip;
  24. int bottomclip;
  25. } maskdraw_t;
  26. /*
  27. Sprite rotation 0 is facing the viewer, rotation 1 is one angle turn CLOCKWISE around the axis.
  28. This is not the same as the angle, which increases counter clockwise
  29. (protractor). There was a lot of stuff grabbed wrong, so I changed it...
  30. */
  31. fixed_t pspritescale, pspriteiscale;
  32. lighttable_t **spritelights;
  33. // constant arrays used for psprite clipping and initializing clipping
  34. short negonearray[SCREENWIDTH];
  35. short screenheightarray[SCREENWIDTH];
  36. boolean LevelUseFullBright;
  37. /*
  38. ===============================================================================
  39. INITIALIZATION FUNCTIONS
  40. ===============================================================================
  41. */
  42. // variables used to look up and range check thing_t sprites patches
  43. spritedef_t *sprites;
  44. int numsprites;
  45. spriteframe_t sprtemp[30];
  46. int maxframe;
  47. char *spritename;
  48. /*
  49. =================
  50. =
  51. = R_InstallSpriteLump
  52. =
  53. = Local function for R_InitSprites
  54. =================
  55. */
  56. void R_InstallSpriteLump (int lump, unsigned frame, unsigned rotation, boolean flipped)
  57. {
  58. int r;
  59. if (frame >= 30 || rotation > 8)
  60. I_Error ("R_InstallSpriteLump: Bad frame characters in lump %i", lump);
  61. if ((int)frame > maxframe)
  62. maxframe = frame;
  63. if (rotation == 0)
  64. {
  65. // the lump should be used for all rotations
  66. if (sprtemp[frame].rotate == false)
  67. I_Error ("R_InitSprites: Sprite %s frame %c has multip rot=0 lump"
  68. , spritename, 'A'+frame);
  69. if (sprtemp[frame].rotate == true)
  70. I_Error ("R_InitSprites: Sprite %s frame %c has rotations and a rot=0 lump"
  71. , spritename, 'A'+frame);
  72. sprtemp[frame].rotate = false;
  73. for (r=0 ; r<8 ; r++)
  74. {
  75. sprtemp[frame].lump[r] = lump - firstspritelump;
  76. sprtemp[frame].flip[r] = (byte)flipped;
  77. }
  78. return;
  79. }
  80. // the lump is only used for one rotation
  81. if (sprtemp[frame].rotate == false)
  82. I_Error ("R_InitSprites: Sprite %s frame %c has rotations and a rot=0 lump"
  83. , spritename, 'A'+frame);
  84. sprtemp[frame].rotate = true;
  85. rotation--; // make 0 based
  86. if (sprtemp[frame].lump[rotation] != -1)
  87. I_Error ("R_InitSprites: Sprite %s : %c : %c has two lumps mapped to it"
  88. ,spritename, 'A'+frame, '1'+rotation);
  89. sprtemp[frame].lump[rotation] = lump - firstspritelump;
  90. sprtemp[frame].flip[rotation] = (byte)flipped;
  91. }
  92. /*
  93. =================
  94. =
  95. = R_InitSpriteDefs
  96. =
  97. = Pass a null terminated list of sprite names (4 chars exactly) to be used
  98. = Builds the sprite rotation matrixes to account for horizontally flipped
  99. = sprites. Will report an error if the lumps are inconsistant
  100. = Only called at startup
  101. =
  102. = Sprite lump names are 4 characters for the actor, a letter for the frame,
  103. = and a number for the rotation, A sprite that is flippable will have an
  104. = additional letter/number appended. The rotation character can be 0 to
  105. = signify no rotations
  106. =================
  107. */
  108. void R_InitSpriteDefs (char **namelist)
  109. {
  110. char **check;
  111. int i, l, intname, frame, rotation;
  112. int start, end;
  113. // count the number of sprite names
  114. check = namelist;
  115. while (*check != NULL)
  116. check++;
  117. numsprites = check-namelist;
  118. if (!numsprites)
  119. return;
  120. sprites = Z_Malloc(numsprites *sizeof(*sprites), PU_STATIC, NULL);
  121. start = firstspritelump-1;
  122. end = lastspritelump+1;
  123. // scan all the lump names for each of the names, noting the highest
  124. // frame letter
  125. // Just compare 4 characters as ints
  126. for (i=0 ; i<numsprites ; i++)
  127. {
  128. spritename = namelist[i];
  129. memset (sprtemp,-1, sizeof(sprtemp));
  130. maxframe = -1;
  131. intname = *(int *)namelist[i];
  132. //
  133. // scan the lumps, filling in the frames for whatever is found
  134. //
  135. for (l=start+1 ; l<end ; l++)
  136. if (*(int *)lumpinfo[l].name == intname)
  137. {
  138. frame = lumpinfo[l].name[4] - 'A';
  139. rotation = lumpinfo[l].name[5] - '0';
  140. R_InstallSpriteLump (l, frame, rotation, false);
  141. if (lumpinfo[l].name[6])
  142. {
  143. frame = lumpinfo[l].name[6] - 'A';
  144. rotation = lumpinfo[l].name[7] - '0';
  145. R_InstallSpriteLump (l, frame, rotation, true);
  146. }
  147. }
  148. //
  149. // check the frames that were found for completeness
  150. //
  151. if (maxframe == -1)
  152. {
  153. //continue;
  154. sprites[i].numframes = 0;
  155. if (shareware)
  156. continue;
  157. I_Error ("R_InitSprites: No lumps found for sprite %s"
  158. ,namelist[i]);
  159. }
  160. maxframe++;
  161. for (frame = 0 ; frame < maxframe ; frame++)
  162. {
  163. switch ((int)sprtemp[frame].rotate)
  164. {
  165. case -1: // no rotations were found for that frame at all
  166. I_Error ("R_InitSprites: No patches found for %s frame %c"
  167. , namelist[i], frame+'A');
  168. case 0: // only the first rotation is needed
  169. break;
  170. case 1: // must have all 8 frames
  171. for (rotation=0 ; rotation<8 ; rotation++)
  172. if (sprtemp[frame].lump[rotation] == -1)
  173. I_Error ("R_InitSprites: Sprite %s frame %c is missing rotations"
  174. , namelist[i], frame+'A');
  175. }
  176. }
  177. //
  178. // allocate space for the frames present and copy sprtemp to it
  179. //
  180. sprites[i].numframes = maxframe;
  181. sprites[i].spriteframes =
  182. Z_Malloc (maxframe * sizeof(spriteframe_t), PU_STATIC, NULL);
  183. memcpy (sprites[i].spriteframes, sprtemp, maxframe*sizeof(spriteframe_t));
  184. }
  185. }
  186. /*
  187. ===============================================================================
  188. GAME FUNCTIONS
  189. ===============================================================================
  190. */
  191. vissprite_t vissprites[MAXVISSPRITES], *vissprite_p;
  192. int newvissprite;
  193. /*
  194. ===================
  195. =
  196. = R_InitSprites
  197. =
  198. = Called at program start
  199. ===================
  200. */
  201. void R_InitSprites (char **namelist)
  202. {
  203. int i;
  204. for (i=0 ; i<SCREENWIDTH ; i++)
  205. {
  206. negonearray[i] = -1;
  207. }
  208. R_InitSpriteDefs (namelist);
  209. }
  210. /*
  211. ===================
  212. =
  213. = R_ClearSprites
  214. =
  215. = Called at frame start
  216. ===================
  217. */
  218. void R_ClearSprites (void)
  219. {
  220. vissprite_p = vissprites;
  221. }
  222. /*
  223. ===================
  224. =
  225. = R_NewVisSprite
  226. =
  227. ===================
  228. */
  229. vissprite_t overflowsprite;
  230. vissprite_t *R_NewVisSprite (void)
  231. {
  232. if (vissprite_p == &vissprites[MAXVISSPRITES])
  233. return &overflowsprite;
  234. vissprite_p++;
  235. return vissprite_p-1;
  236. }
  237. /*
  238. ================
  239. =
  240. = R_DrawMaskedColumn
  241. =
  242. = Used for sprites and masked mid textures
  243. ================
  244. */
  245. short *mfloorclip;
  246. short *mceilingclip;
  247. fixed_t spryscale;
  248. fixed_t sprtopscreen;
  249. fixed_t sprbotscreen;
  250. void R_DrawMaskedColumn (column_t *column, signed int baseclip)
  251. {
  252. int topscreen, bottomscreen;
  253. fixed_t basetexturemid;
  254. basetexturemid = dc_texturemid;
  255. for ( ; column->topdelta != 0xff ; )
  256. {
  257. // calculate unclipped screen coordinates for post
  258. topscreen = sprtopscreen + spryscale*column->topdelta;
  259. bottomscreen = topscreen + spryscale*column->length;
  260. dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
  261. dc_yh = (bottomscreen-1)>>FRACBITS;
  262. if (dc_yh >= mfloorclip[dc_x])
  263. dc_yh = mfloorclip[dc_x]-1;
  264. if (dc_yl <= mceilingclip[dc_x])
  265. dc_yl = mceilingclip[dc_x]+1;
  266. if(dc_yh >= baseclip && baseclip != -1)
  267. dc_yh = baseclip;
  268. if (dc_yl <= dc_yh)
  269. {
  270. dc_source = (byte *)column + 3;
  271. dc_texturemid = basetexturemid - (column->topdelta<<FRACBITS);
  272. // dc_source = (byte *)column + 3 - column->topdelta;
  273. colfunc (); // either R_DrawColumn or R_DrawFuzzColumn
  274. }
  275. column = (column_t *)( (byte *)column + column->length + 4);
  276. }
  277. dc_texturemid = basetexturemid;
  278. }
  279. /*
  280. ================
  281. =
  282. = R_DrawVisSprite
  283. =
  284. = mfloorclip and mceilingclip should also be set
  285. ================
  286. */
  287. void R_DrawVisSprite (vissprite_t *vis, int x1, int x2)
  288. {
  289. column_t *column;
  290. int texturecolumn;
  291. fixed_t frac;
  292. patch_t *patch;
  293. fixed_t baseclip;
  294. patch = W_CacheLumpNum(vis->patch+firstspritelump, PU_CACHE);
  295. dc_colormap = vis->colormap;
  296. // if(!dc_colormap)
  297. // colfunc = fuzzcolfunc; // NULL colormap = shadow draw
  298. if(vis->mobjflags&(MF_SHADOW|MF_ALTSHADOW))
  299. {
  300. if(vis->mobjflags&MF_TRANSLATION)
  301. {
  302. colfunc = R_DrawTranslatedFuzzColumn;
  303. dc_translation = translationtables-256
  304. +vis->class*((MAXPLAYERS-1)*256)+
  305. ((vis->mobjflags&MF_TRANSLATION)>>(MF_TRANSSHIFT-8));
  306. }
  307. else if(vis->mobjflags&MF_SHADOW)
  308. { // Draw using shadow column function
  309. colfunc = fuzzcolfunc;
  310. }
  311. else
  312. {
  313. colfunc = R_DrawAltFuzzColumn;
  314. }
  315. }
  316. else if(vis->mobjflags&MF_TRANSLATION)
  317. {
  318. // Draw using translated column function
  319. colfunc = R_DrawTranslatedColumn;
  320. dc_translation = translationtables-256
  321. +vis->class*((MAXPLAYERS-1)*256)+
  322. ((vis->mobjflags&MF_TRANSLATION)>>(MF_TRANSSHIFT-8));
  323. }
  324. dc_iscale = abs(vis->xiscale)>>detailshift;
  325. dc_texturemid = vis->texturemid;
  326. frac = vis->startfrac;
  327. spryscale = vis->scale;
  328. sprtopscreen = centeryfrac - FixedMul(dc_texturemid,spryscale);
  329. // check to see if vissprite is a weapon
  330. if(vis->psprite)
  331. {
  332. dc_texturemid += FixedMul(((centery-viewheight/2)<<FRACBITS),
  333. vis->xiscale);
  334. sprtopscreen += (viewheight/2-centery)<<FRACBITS;
  335. }
  336. if(vis->floorclip && !vis->psprite)
  337. {
  338. sprbotscreen = sprtopscreen+FixedMul(patch->height<<FRACBITS,
  339. spryscale);
  340. baseclip = (sprbotscreen-FixedMul(vis->floorclip,
  341. spryscale))>>FRACBITS;
  342. }
  343. else
  344. {
  345. baseclip = -1;
  346. }
  347. for (dc_x=vis->x1 ; dc_x<=vis->x2 ; dc_x++, frac += vis->xiscale)
  348. {
  349. texturecolumn = frac>>FRACBITS;
  350. #ifdef RANGECHECK
  351. if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
  352. I_Error ("R_DrawSpriteRange: bad texturecolumn");
  353. #endif
  354. column = (column_t *) ((byte *)patch +
  355. LONG(patch->columnofs[texturecolumn]));
  356. R_DrawMaskedColumn (column, baseclip);
  357. }
  358. colfunc = basecolfunc;
  359. }
  360. /*
  361. ===================
  362. =
  363. = R_ProjectSprite
  364. =
  365. = Generates a vissprite for a thing if it might be visible
  366. =
  367. ===================
  368. */
  369. void R_ProjectSprite (mobj_t *thing)
  370. {
  371. fixed_t trx,try;
  372. fixed_t gxt,gyt;
  373. fixed_t tx,tz;
  374. fixed_t xscale;
  375. int x1, x2;
  376. spritedef_t *sprdef;
  377. spriteframe_t *sprframe;
  378. int lump;
  379. unsigned rot;
  380. boolean flip;
  381. int index;
  382. vissprite_t *vis;
  383. angle_t ang;
  384. fixed_t iscale;
  385. if(thing->flags2&MF2_DONTDRAW)
  386. { // Never make a vissprite when MF2_DONTDRAW is flagged.
  387. return;
  388. }
  389. //
  390. // transform the origin point
  391. //
  392. trx = thing->x - viewx;
  393. try = thing->y - viewy;
  394. gxt = FixedMul(trx,viewcos);
  395. gyt = -FixedMul(try,viewsin);
  396. tz = gxt-gyt;
  397. if (tz < MINZ)
  398. return; // thing is behind view plane
  399. xscale = FixedDiv(projection, tz);
  400. gxt = -FixedMul(trx,viewsin);
  401. gyt = FixedMul(try,viewcos);
  402. tx = -(gyt+gxt);
  403. if (abs(tx)>(tz<<2))
  404. return; // too far off the side
  405. //
  406. // decide which patch to use for sprite reletive to player
  407. //
  408. #ifdef RANGECHECK
  409. if ((unsigned)thing->sprite >= numsprites)
  410. I_Error ("R_ProjectSprite: invalid sprite number %i ",thing->sprite);
  411. #endif
  412. sprdef = &sprites[thing->sprite];
  413. #ifdef RANGECHECK
  414. if ( (thing->frame&FF_FRAMEMASK) >= sprdef->numframes )
  415. I_Error ("R_ProjectSprite: invalid sprite frame %i : %i "
  416. ,thing->sprite, thing->frame);
  417. #endif
  418. sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK];
  419. if (sprframe->rotate)
  420. { // choose a different rotation based on player view
  421. ang = R_PointToAngle (thing->x, thing->y);
  422. rot = (ang-thing->angle+(unsigned)(ANG45/2)*9)>>29;
  423. lump = sprframe->lump[rot];
  424. flip = (boolean)sprframe->flip[rot];
  425. }
  426. else
  427. { // use single rotation for all views
  428. lump = sprframe->lump[0];
  429. flip = (boolean)sprframe->flip[0];
  430. }
  431. //
  432. // calculate edges of the shape
  433. //
  434. tx -= spriteoffset[lump];
  435. x1 = (centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS;
  436. if (x1 > viewwidth)
  437. return; // off the right side
  438. tx += spritewidth[lump];
  439. x2 = ((centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS) - 1;
  440. if (x2 < 0)
  441. return; // off the left side
  442. //
  443. // store information in a vissprite
  444. //
  445. vis = R_NewVisSprite ();
  446. vis->mobjflags = thing->flags;
  447. vis->psprite = false;
  448. vis->scale = xscale<<detailshift;
  449. vis->gx = thing->x;
  450. vis->gy = thing->y;
  451. vis->gz = thing->z;
  452. vis->gzt = thing->z + spritetopoffset[lump];
  453. if(thing->flags&MF_TRANSLATION)
  454. {
  455. if(thing->player)
  456. {
  457. vis->class = thing->player->class;
  458. }
  459. else
  460. {
  461. vis->class = thing->special1;
  462. }
  463. if(vis->class > 2)
  464. {
  465. vis->class = 0;
  466. }
  467. }
  468. // foot clipping
  469. vis->floorclip = thing->floorclip;
  470. vis->texturemid = vis->gzt-viewz-vis->floorclip;
  471. vis->x1 = x1 < 0 ? 0 : x1;
  472. vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
  473. iscale = FixedDiv (FRACUNIT, xscale);
  474. if (flip)
  475. {
  476. vis->startfrac = spritewidth[lump]-1;
  477. vis->xiscale = -iscale;
  478. }
  479. else
  480. {
  481. vis->startfrac = 0;
  482. vis->xiscale = iscale;
  483. }
  484. if (vis->x1 > x1)
  485. vis->startfrac += vis->xiscale*(vis->x1-x1);
  486. vis->patch = lump;
  487. //
  488. // get light level
  489. //
  490. // if (thing->flags & MF_SHADOW)
  491. // vis->colormap = NULL; // shadow draw
  492. // else ...
  493. if (fixedcolormap)
  494. vis->colormap = fixedcolormap; // fixed map
  495. else if(LevelUseFullBright && thing->frame&FF_FULLBRIGHT)
  496. vis->colormap = colormaps; // full bright
  497. else
  498. { // diminished light
  499. index = xscale>>(LIGHTSCALESHIFT-detailshift);
  500. if (index >= MAXLIGHTSCALE)
  501. index = MAXLIGHTSCALE-1;
  502. vis->colormap = spritelights[index];
  503. }
  504. }
  505. /*
  506. ========================
  507. =
  508. = R_AddSprites
  509. =
  510. ========================
  511. */
  512. void R_AddSprites (sector_t *sec)
  513. {
  514. mobj_t *thing;
  515. int lightnum;
  516. if (sec->validcount == validcount)
  517. return; // already added
  518. sec->validcount = validcount;
  519. lightnum = (sec->lightlevel >> LIGHTSEGSHIFT)+extralight;
  520. if (lightnum < 0)
  521. spritelights = scalelight[0];
  522. else if (lightnum >= LIGHTLEVELS)
  523. spritelights = scalelight[LIGHTLEVELS-1];
  524. else
  525. spritelights = scalelight[lightnum];
  526. for (thing = sec->thinglist ; thing ; thing = thing->snext)
  527. R_ProjectSprite (thing);
  528. }
  529. /*
  530. ========================
  531. =
  532. = R_DrawPSprite
  533. =
  534. ========================
  535. */
  536. // Y-adjustment values for full screen (4 weapons)
  537. int PSpriteSY[NUMCLASSES][NUMWEAPONS] =
  538. {
  539. { 0, -12*FRACUNIT, -10*FRACUNIT, 10*FRACUNIT }, // Fighter
  540. { -8*FRACUNIT, 10*FRACUNIT, 10*FRACUNIT, 0 }, // Cleric
  541. { 9*FRACUNIT, 20*FRACUNIT, 20*FRACUNIT, 20*FRACUNIT }, // Mage
  542. { 10*FRACUNIT, 10*FRACUNIT, 10*FRACUNIT, 10*FRACUNIT } // Pig
  543. };
  544. void R_DrawPSprite (pspdef_t *psp)
  545. {
  546. fixed_t tx;
  547. int x1, x2;
  548. spritedef_t *sprdef;
  549. spriteframe_t *sprframe;
  550. int lump;
  551. boolean flip;
  552. vissprite_t *vis, avis;
  553. int tempangle;
  554. //
  555. // decide which patch to use
  556. //
  557. #ifdef RANGECHECK
  558. if ( (unsigned)psp->state->sprite >= numsprites)
  559. I_Error ("R_ProjectSprite: invalid sprite number %i "
  560. , psp->state->sprite);
  561. #endif
  562. sprdef = &sprites[psp->state->sprite];
  563. #ifdef RANGECHECK
  564. if ( (psp->state->frame & FF_FRAMEMASK) >= sprdef->numframes)
  565. I_Error ("R_ProjectSprite: invalid sprite frame %i : %i "
  566. , psp->state->sprite, psp->state->frame);
  567. #endif
  568. sprframe = &sprdef->spriteframes[ psp->state->frame & FF_FRAMEMASK ];
  569. lump = sprframe->lump[0];
  570. flip = (boolean)sprframe->flip[0];
  571. //
  572. // calculate edges of the shape
  573. //
  574. tx = psp->sx-160*FRACUNIT;
  575. tx -= spriteoffset[lump];
  576. if(viewangleoffset)
  577. {
  578. tempangle = ((centerxfrac/1024)*(viewangleoffset>>ANGLETOFINESHIFT));
  579. }
  580. else
  581. {
  582. tempangle = 0;
  583. }
  584. x1 = (centerxfrac + FixedMul (tx,pspritescale)+tempangle ) >>FRACBITS;
  585. if (x1 > viewwidth)
  586. return; // off the right side
  587. tx += spritewidth[lump];
  588. x2 = ((centerxfrac + FixedMul (tx, pspritescale)+tempangle ) >>FRACBITS) - 1;
  589. if (x2 < 0)
  590. return; // off the left side
  591. //
  592. // store information in a vissprite
  593. //
  594. vis = &avis;
  595. vis->mobjflags = 0;
  596. vis->class = 0;
  597. vis->psprite = true;
  598. vis->texturemid = (BASEYCENTER<<FRACBITS)+FRACUNIT/2
  599. -(psp->sy-spritetopoffset[lump]);
  600. if(viewheight == SCREENHEIGHT)
  601. {
  602. vis->texturemid -= PSpriteSY[viewplayer->class]
  603. [players[consoleplayer].readyweapon];
  604. }
  605. vis->x1 = x1 < 0 ? 0 : x1;
  606. vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
  607. vis->scale = pspritescale<<detailshift;
  608. if (flip)
  609. {
  610. vis->xiscale = -pspriteiscale;
  611. vis->startfrac = spritewidth[lump]-1;
  612. }
  613. else
  614. {
  615. vis->xiscale = pspriteiscale;
  616. vis->startfrac = 0;
  617. }
  618. if (vis->x1 > x1)
  619. vis->startfrac += vis->xiscale*(vis->x1-x1);
  620. vis->patch = lump;
  621. if(viewplayer->powers[pw_invulnerability] && viewplayer->class
  622. == PCLASS_CLERIC)
  623. {
  624. vis->colormap = spritelights[MAXLIGHTSCALE-1];
  625. if(viewplayer->powers[pw_invulnerability] > 4*32)
  626. {
  627. if(viewplayer->mo->flags2&MF2_DONTDRAW)
  628. { // don't draw the psprite
  629. vis->mobjflags |= MF_SHADOW;
  630. }
  631. else if(viewplayer->mo->flags&MF_SHADOW)
  632. {
  633. vis->mobjflags |= MF_ALTSHADOW;
  634. }
  635. }
  636. else if(viewplayer->powers[pw_invulnerability]&8)
  637. {
  638. vis->mobjflags |= MF_SHADOW;
  639. }
  640. }
  641. else if(fixedcolormap)
  642. {
  643. // Fixed color
  644. vis->colormap = fixedcolormap;
  645. }
  646. else if(psp->state->frame & FF_FULLBRIGHT)
  647. {
  648. // Full bright
  649. vis->colormap = colormaps;
  650. }
  651. else
  652. {
  653. // local light
  654. vis->colormap = spritelights[MAXLIGHTSCALE-1];
  655. }
  656. R_DrawVisSprite(vis, vis->x1, vis->x2);
  657. }
  658. /*
  659. ========================
  660. =
  661. = R_DrawPlayerSprites
  662. =
  663. ========================
  664. */
  665. void R_DrawPlayerSprites (void)
  666. {
  667. int i, lightnum;
  668. pspdef_t *psp;
  669. //
  670. // get light level
  671. //
  672. lightnum = (viewplayer->mo->subsector->sector->lightlevel >> LIGHTSEGSHIFT)
  673. +extralight;
  674. if (lightnum < 0)
  675. spritelights = scalelight[0];
  676. else if (lightnum >= LIGHTLEVELS)
  677. spritelights = scalelight[LIGHTLEVELS-1];
  678. else
  679. spritelights = scalelight[lightnum];
  680. //
  681. // clip to screen bounds
  682. //
  683. mfloorclip = screenheightarray;
  684. mceilingclip = negonearray;
  685. //
  686. // add all active psprites
  687. //
  688. for (i=0, psp=viewplayer->psprites ; i<NUMPSPRITES ; i++,psp++)
  689. if (psp->state)
  690. R_DrawPSprite (psp);
  691. }
  692. /*
  693. ========================
  694. =
  695. = R_SortVisSprites
  696. =
  697. ========================
  698. */
  699. vissprite_t vsprsortedhead;
  700. void R_SortVisSprites (void)
  701. {
  702. int i, count;
  703. vissprite_t *ds, *best;
  704. vissprite_t unsorted;
  705. fixed_t bestscale;
  706. count = vissprite_p - vissprites;
  707. unsorted.next = unsorted.prev = &unsorted;
  708. if (!count)
  709. return;
  710. for (ds=vissprites ; ds<vissprite_p ; ds++)
  711. {
  712. ds->next = ds+1;
  713. ds->prev = ds-1;
  714. }
  715. vissprites[0].prev = &unsorted;
  716. unsorted.next = &vissprites[0];
  717. (vissprite_p-1)->next = &unsorted;
  718. unsorted.prev = vissprite_p-1;
  719. //
  720. // pull the vissprites out by scale
  721. //
  722. best = 0; // shut up the compiler warning
  723. vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead;
  724. for (i=0 ; i<count ; i++)
  725. {
  726. bestscale = MAXINT;
  727. for (ds=unsorted.next ; ds!= &unsorted ; ds=ds->next)
  728. {
  729. if (ds->scale < bestscale)
  730. {
  731. bestscale = ds->scale;
  732. best = ds;
  733. }
  734. }
  735. best->next->prev = best->prev;
  736. best->prev->next = best->next;
  737. best->next = &vsprsortedhead;
  738. best->prev = vsprsortedhead.prev;
  739. vsprsortedhead.prev->next = best;
  740. vsprsortedhead.prev = best;
  741. }
  742. }
  743. /*
  744. ========================
  745. =
  746. = R_DrawSprite
  747. =
  748. ========================
  749. */
  750. void R_DrawSprite (vissprite_t *spr)
  751. {
  752. drawseg_t *ds;
  753. short clipbot[SCREENWIDTH], cliptop[SCREENWIDTH];
  754. int x, r1, r2;
  755. fixed_t scale, lowscale;
  756. int silhouette;
  757. for (x = spr->x1 ; x<=spr->x2 ; x++)
  758. clipbot[x] = cliptop[x] = -2;
  759. //
  760. // scan drawsegs from end to start for obscuring segs
  761. // the first drawseg that has a greater scale is the clip seg
  762. //
  763. for (ds=ds_p-1 ; ds >= drawsegs ; ds--)
  764. {
  765. //
  766. // determine if the drawseg obscures the sprite
  767. //
  768. if (ds->x1 > spr->x2 || ds->x2 < spr->x1 ||
  769. (!ds->silhouette && !ds->maskedtexturecol) )
  770. continue; // doesn't cover sprite
  771. r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1;
  772. r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2;
  773. if (ds->scale1 > ds->scale2)
  774. {
  775. lowscale = ds->scale2;
  776. scale = ds->scale1;
  777. }
  778. else
  779. {
  780. lowscale = ds->scale1;
  781. scale = ds->scale2;
  782. }
  783. if (scale < spr->scale || ( lowscale < spr->scale
  784. && !R_PointOnSegSide (spr->gx, spr->gy, ds->curline) ) )
  785. {
  786. if (ds->maskedtexturecol) // masked mid texture
  787. R_RenderMaskedSegRange (ds, r1, r2);
  788. continue; // seg is behind sprite
  789. }
  790. //
  791. // clip this piece of the sprite
  792. //
  793. silhouette = ds->silhouette;
  794. if (spr->gz >= ds->bsilheight)
  795. silhouette &= ~SIL_BOTTOM;
  796. if (spr->gzt <= ds->tsilheight)
  797. silhouette &= ~SIL_TOP;
  798. if (silhouette == 1)
  799. { // bottom sil
  800. for (x=r1 ; x<=r2 ; x++)
  801. if (clipbot[x] == -2)
  802. clipbot[x] = ds->sprbottomclip[x];
  803. }
  804. else if (silhouette == 2)
  805. { // top sil
  806. for (x=r1 ; x<=r2 ; x++)
  807. if (cliptop[x] == -2)
  808. cliptop[x] = ds->sprtopclip[x];
  809. }
  810. else if (silhouette == 3)
  811. { // both
  812. for (x=r1 ; x<=r2 ; x++)
  813. {
  814. if (clipbot[x] == -2)
  815. clipbot[x] = ds->sprbottomclip[x];
  816. if (cliptop[x] == -2)
  817. cliptop[x] = ds->sprtopclip[x];
  818. }
  819. }
  820. }
  821. //
  822. // all clipping has been performed, so draw the sprite
  823. //
  824. // check for unclipped columns
  825. for (x = spr->x1 ; x<=spr->x2 ; x++)
  826. {
  827. if (clipbot[x] == -2)
  828. clipbot[x] = viewheight;
  829. if (cliptop[x] == -2)
  830. cliptop[x] = -1;
  831. }
  832. mfloorclip = clipbot;
  833. mceilingclip = cliptop;
  834. R_DrawVisSprite (spr, spr->x1, spr->x2);
  835. }
  836. /*
  837. ========================
  838. =
  839. = R_DrawMasked
  840. =
  841. ========================
  842. */
  843. void R_DrawMasked (void)
  844. {
  845. vissprite_t *spr;
  846. drawseg_t *ds;
  847. R_SortVisSprites ();
  848. if (vissprite_p > vissprites)
  849. {
  850. // draw all vissprites back to front
  851. for (spr = vsprsortedhead.next ; spr != &vsprsortedhead
  852. ; spr=spr->next)
  853. R_DrawSprite (spr);
  854. }
  855. //
  856. // render any remaining masked mid textures
  857. //
  858. for (ds=ds_p-1 ; ds >= drawsegs ; ds--)
  859. if (ds->maskedtexturecol)
  860. R_RenderMaskedSegRange (ds, ds->x1, ds->x2);
  861. //
  862. // draw the psprites on top of everything
  863. //
  864. // Added for the sideviewing with an external device
  865. if (viewangleoffset <= 1024<<ANGLETOFINESHIFT || viewangleoffset >=
  866. -1024<<ANGLETOFINESHIFT)
  867. { // don't draw on side views
  868. R_DrawPlayerSprites ();
  869. }
  870. // if (!viewangleoffset) // don't draw on side views
  871. // R_DrawPlayerSprites ();
  872. }