1 //**************************************************************************
2 //**
3 //**	##   ##    ##    ##   ##   ####     ####   ###     ###
4 //**	##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
5 //**	 ## ##  ##    ##  ## ##  ##    ## ##    ## ## ## ## ##
6 //**	 ## ##  ########  ## ##  ##    ## ##    ## ##  ###  ##
7 //**	  ###   ##    ##   ###    ##  ##   ##  ##  ##       ##
8 //**	   #    ##    ##    #      ####     ####   ##       ##
9 //**
10 //**	$Id: r_things.cpp 4003 2009-03-04 20:08:00Z dj_jl $
11 //**
12 //**	Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //**	This program is free software; you can redistribute it and/or
15 //**  modify it under the terms of the GNU General Public License
16 //**  as published by the Free Software Foundation; either version 2
17 //**  of the License, or (at your option) any later version.
18 //**
19 //**	This program is distributed in the hope that it will be useful,
20 //**  but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //**  GNU General Public License for more details.
23 //**
24 //**************************************************************************
25 //**
26 //**	Refresh of things, i.e. objects represented by sprites.
27 //**
28 //** 	Sprite rotation 0 is facing the viewer, rotation 1 is one angle turn
29 //**  CLOCKWISE around the axis. This is not the same as the angle, which
30 //**  increases counter clockwise (protractor). There was a lot of stuff
31 //**  grabbed wrong, so I changed it...
32 //**
33 //**************************************************************************
34 
35 // HEADER FILES ------------------------------------------------------------
36 
37 #include "gamedefs.h"
38 #include "r_local.h"
39 #include "sv_local.h"
40 
41 // MACROS ------------------------------------------------------------------
42 
43 // TYPES -------------------------------------------------------------------
44 
45 enum
46 {
47 	SPR_VP_PARALLEL_UPRIGHT,
48 	SPR_FACING_UPRIGHT,
49 	SPR_VP_PARALLEL,
50 	SPR_ORIENTED,
51 	SPR_VP_PARALLEL_ORIENTED,
52 	SPR_VP_PARALLEL_UPRIGHT_ORIENTED,
53 };
54 
55 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
56 
57 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
58 
59 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
60 
61 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
62 
63 extern VCvarI		r_chasecam;
64 
65 // PUBLIC DATA DEFINITIONS -------------------------------------------------
66 
67 // PRIVATE DATA DEFINITIONS ------------------------------------------------
68 
69 extern VCvarI			r_draw_mobjs;
70 extern VCvarI			r_draw_psprites;
71 extern VCvarI			r_models;
72 extern VCvarI			r_hide_models;
73 extern VCvarI			r_view_models;
74 extern VCvarI			r_model_shadows;
75 extern VCvarI			r_model_light;
76 extern VCvarI			r_sort_sprites;
77 extern VCvarI			r_fix_sprite_offsets;
78 extern VCvarI			r_sprite_fix_delta;
79 extern VCvarI			r_drawfuzz;
80 extern VCvarF			transsouls;
81 extern VCvarI			croshair;
82 extern VCvarF			croshair_alpha;
83 
84 // CODE --------------------------------------------------------------------
85 
86 //==========================================================================
87 //
88 //	VAdvancedRenderLevel::RenderThingAmbient
89 //
90 //==========================================================================
91 
RenderThingAmbient(VEntity * mobj)92 void VAdvancedRenderLevel::RenderThingAmbient(VEntity* mobj)
93 {
94 	guard(VAdvancedRenderLevel::RenderThingAmbient);
95 	//	Skip things in subsectors that are not visible.
96 	int SubIdx = mobj->SubSector - Level->Subsectors;
97 	if (!(BspVis[SubIdx >> 3] & (1 << (SubIdx & 7))))
98 	{
99 		return;
100 	}
101 	if (mobj == ViewEnt && (!r_chasecam || ViewEnt != cl->MO))
102 	{
103 		//	Don't draw camera actor.
104 		return;
105 	}
106 
107 	if ((mobj->EntityFlags & VEntity::EF_NoSector) ||
108 		(mobj->EntityFlags & VEntity::EF_Invisible))
109 	{
110 		return;
111 	}
112 	if (!mobj->State)
113 	{
114 		return;
115 	}
116 
117 	int RendStyle = mobj->RenderStyle;
118 	float Alpha = mobj->Alpha;
119 
120 	if (RendStyle == STYLE_SoulTrans)
121 	{
122 		RendStyle = STYLE_Translucent;
123 		Alpha = transsouls;
124 	}
125 	else if (RendStyle == STYLE_OptFuzzy)
126 	{
127 		RendStyle = r_drawfuzz ? STYLE_Fuzzy : STYLE_Translucent;
128 	}
129 
130 	switch (RendStyle)
131 	{
132 	case STYLE_None:
133 		return;
134 
135 	case STYLE_Normal:
136 		Alpha = 1.0;
137 		break;
138 
139 	case STYLE_Fuzzy:
140 		return;
141 
142 	case STYLE_Add:
143 		return;
144 	}
145 	Alpha = MID(0.0, Alpha, 1.0);
146 
147 	if (Alpha < 1.0)
148 	{
149 		return;
150 	}
151 
152 	//	Setup lighting
153 	vuint32 light;
154 	if ((mobj->State->Frame & VState::FF_FULLBRIGHT) ||
155 		(mobj->EntityFlags & (VEntity::EF_FullBright | VEntity::EF_Bright)))
156 	{
157 		light = 0xffffffff;
158 	}
159 	else
160 	{
161 		light = LightPointAmbient(mobj->Origin);
162 	}
163 
164 	float TimeFrac = 0;
165 	if (mobj->State->Time > 0)
166 	{
167 		TimeFrac = 1.0 - (mobj->StateTime / mobj->State->Time);
168 		TimeFrac = MID(0.0, TimeFrac, 1.0);
169 	}
170 
171 	DrawEntityModel(mobj, light, 0, 1, false, TimeFrac, RPASS_Ambient);
172 	unguard;
173 }
174 
175 //==========================================================================
176 //
177 //	VAdvancedRenderLevel::RenderMobjsAmbient
178 //
179 //==========================================================================
180 
RenderMobjsAmbient()181 void VAdvancedRenderLevel::RenderMobjsAmbient()
182 {
183 	guard(VAdvancedRenderLevel::RenderMobjsAmbient);
184 	if (!r_draw_mobjs || !r_models)
185 	{
186 		return;
187 	}
188 
189 	for (TThinkerIterator<VEntity> Ent(Level); Ent; ++Ent)
190 	{
191 		RenderThingAmbient(*Ent);
192 	}
193 	unguard;
194 }
195 
196 //==========================================================================
197 //
198 //	VAdvancedRenderLevel::RenderThingTextures
199 //
200 //==========================================================================
201 
RenderThingTextures(VEntity * mobj)202 void VAdvancedRenderLevel::RenderThingTextures(VEntity* mobj)
203 {
204 	guard(VAdvancedRenderLevel::RenderThingAmbient);
205 	//	Skip things in subsectors that are not visible.
206 	int SubIdx = mobj->SubSector - Level->Subsectors;
207 	if (!(BspVis[SubIdx >> 3] & (1 << (SubIdx & 7))))
208 	{
209 		return;
210 	}
211 	if (mobj == ViewEnt && (!r_chasecam || ViewEnt != cl->MO))
212 	{
213 		//	Don't draw camera actor.
214 		return;
215 	}
216 
217 	if ((mobj->EntityFlags & VEntity::EF_NoSector) ||
218 		(mobj->EntityFlags & VEntity::EF_Invisible))
219 	{
220 		return;
221 	}
222 	if (!mobj->State)
223 	{
224 		return;
225 	}
226 
227 	int RendStyle = mobj->RenderStyle;
228 	float Alpha = mobj->Alpha;
229 
230 	if (RendStyle == STYLE_SoulTrans)
231 	{
232 		RendStyle = STYLE_Translucent;
233 		Alpha = transsouls;
234 	}
235 	else if (RendStyle == STYLE_OptFuzzy)
236 	{
237 		RendStyle = r_drawfuzz ? STYLE_Fuzzy : STYLE_Translucent;
238 	}
239 
240 	switch (RendStyle)
241 	{
242 	case STYLE_None:
243 		return;
244 
245 	case STYLE_Normal:
246 		Alpha = 1.0;
247 		break;
248 
249 	case STYLE_Fuzzy:
250 		return;
251 
252 	case STYLE_Add:
253 		return;
254 	}
255 	Alpha = MID(0.0, Alpha, 1.0);
256 
257 	if (Alpha < 1.0)
258 	{
259 		return;
260 	}
261 
262 	float TimeFrac = 0;
263 	if (mobj->State->Time > 0)
264 	{
265 		TimeFrac = 1.0 - (mobj->StateTime / mobj->State->Time);
266 		TimeFrac = MID(0.0, TimeFrac, 1.0);
267 	}
268 
269 	DrawEntityModel(mobj, 0xffffffff, 0, 1, false, TimeFrac, RPASS_Textures);
270 	unguard;
271 }
272 
273 //==========================================================================
274 //
275 //	VAdvancedRenderLevel::RenderMobjsTextures
276 //
277 //==========================================================================
278 
RenderMobjsTextures()279 void VAdvancedRenderLevel::RenderMobjsTextures()
280 {
281 	guard(VAdvancedRenderLevel::RenderMobjsTextures);
282 	if (!r_draw_mobjs || !r_models)
283 	{
284 		return;
285 	}
286 
287 	for (TThinkerIterator<VEntity> Ent(Level); Ent; ++Ent)
288 	{
289 		RenderThingTextures(*Ent);
290 	}
291 	unguard;
292 }
293 
294 //==========================================================================
295 //
296 //	VAdvancedRenderLevel::IsTouchedByLight
297 //
298 //==========================================================================
299 
IsTouchedByLight(VEntity * Ent)300 bool VAdvancedRenderLevel::IsTouchedByLight(VEntity* Ent)
301 {
302 	guard(VAdvancedRenderLevel::IsTouchedByLight);
303 	TVec Delta = Ent->Origin - CurrLightPos;
304 	float Dist = Ent->Radius + CurrLightRadius;
305 	if (fabs(Delta.x) > Dist || Delta.y > Dist)
306 	{
307 		return false;
308 	}
309 	if (Delta.z < -CurrLightRadius)
310 	{
311 		return false;
312 	}
313 	if (Delta.z > CurrLightRadius + Ent->Height)
314 	{
315 		return false;
316 	}
317 	Delta.z = 0;
318 	if (Delta.Length() > Dist)
319 	{
320 		return false;
321 	}
322 	return true;
323 	unguard;
324 }
325 
326 //==========================================================================
327 //
328 //	VAdvancedRenderLevel::RenderThingLight
329 //
330 //==========================================================================
331 
RenderThingLight(VEntity * mobj)332 void VAdvancedRenderLevel::RenderThingLight(VEntity* mobj)
333 {
334 	guard(VAdvancedRenderLevel::RenderThingLight);
335 	//	Skip things in subsectors that are not visible.
336 	int SubIdx = mobj->SubSector - Level->Subsectors;
337 	if (!(LightBspVis[SubIdx >> 3] & (1 << (SubIdx & 7))))
338 	{
339 		return;
340 	}
341 	if (mobj == ViewEnt && (!r_chasecam || ViewEnt != cl->MO))
342 	{
343 		//	Don't draw camera actor.
344 		return;
345 	}
346 
347 	if ((mobj->EntityFlags & VEntity::EF_NoSector) ||
348 		(mobj->EntityFlags & VEntity::EF_Invisible))
349 	{
350 		return;
351 	}
352 	if (!mobj->State)
353 	{
354 		return;
355 	}
356 
357 	if (!IsTouchedByLight(mobj))
358 	{
359 		return;
360 	}
361 
362 	int RendStyle = mobj->RenderStyle;
363 	float Alpha = mobj->Alpha;
364 
365 	if (RendStyle == STYLE_SoulTrans)
366 	{
367 		RendStyle = STYLE_Translucent;
368 		Alpha = transsouls;
369 	}
370 	else if (RendStyle == STYLE_OptFuzzy)
371 	{
372 		RendStyle = r_drawfuzz ? STYLE_Fuzzy : STYLE_Translucent;
373 	}
374 
375 	switch (RendStyle)
376 	{
377 	case STYLE_None:
378 		return;
379 
380 	case STYLE_Normal:
381 		Alpha = 1.0;
382 		break;
383 
384 	case STYLE_Fuzzy:
385 		return;
386 
387 	case STYLE_Add:
388 		return;
389 	}
390 	Alpha = MID(0.0, Alpha, 1.0);
391 
392 	if (Alpha < 1.0)
393 	{
394 		return;
395 	}
396 
397 	float TimeFrac = 0;
398 	if (mobj->State->Time > 0)
399 	{
400 		TimeFrac = 1.0 - (mobj->StateTime / mobj->State->Time);
401 		TimeFrac = MID(0.0, TimeFrac, 1.0);
402 	}
403 
404 	DrawEntityModel(mobj, 0xffffffff, 0, 1, false, TimeFrac, RPASS_Light);
405 	unguard;
406 }
407 
408 //==========================================================================
409 //
410 //	VAdvancedRenderLevel::RenderMobjsLight
411 //
412 //==========================================================================
413 
RenderMobjsLight()414 void VAdvancedRenderLevel::RenderMobjsLight()
415 {
416 	guard(VAdvancedRenderLevel::RenderMobjsLight);
417 	if (!r_draw_mobjs || !r_models || !r_model_light)
418 	{
419 		return;
420 	}
421 
422 	for (TThinkerIterator<VEntity> Ent(Level); Ent; ++Ent)
423 	{
424 		RenderThingLight(*Ent);
425 	}
426 	unguard;
427 }
428 
429 //==========================================================================
430 //
431 //	VAdvancedRenderLevel::RenderThingShadow
432 //
433 //==========================================================================
434 
RenderThingShadow(VEntity * mobj)435 void VAdvancedRenderLevel::RenderThingShadow(VEntity* mobj)
436 {
437 	guard(VAdvancedRenderLevel::RenderThingShadow);
438 	//	Skip things in subsectors that are not visible.
439 	int SubIdx = mobj->SubSector - Level->Subsectors;
440 	if (!(LightVis[SubIdx >> 3] & (1 << (SubIdx & 7))))
441 	{
442 		return;
443 	}
444 	if (mobj == ViewEnt && (!r_chasecam || ViewEnt != cl->MO))
445 	{
446 		//	Don't draw camera actor.
447 		return;
448 	}
449 	if ((mobj->EntityFlags & VEntity::EF_NoSector) ||
450 		(mobj->EntityFlags & VEntity::EF_Invisible))
451 	{
452 		return;
453 	}
454 	if (!mobj->State)
455 	{
456 		return;
457 	}
458 	if (!IsTouchedByLight(mobj))
459 	{
460 		return;
461 	}
462 
463 	int RendStyle = mobj->RenderStyle;
464 	float Alpha = mobj->Alpha;
465 
466 	if (RendStyle == STYLE_SoulTrans)
467 	{
468 		RendStyle = STYLE_Translucent;
469 		Alpha = transsouls;
470 	}
471 	else if (RendStyle == STYLE_OptFuzzy)
472 	{
473 		RendStyle = r_drawfuzz ? STYLE_Fuzzy : STYLE_Translucent;
474 	}
475 
476 	switch (RendStyle)
477 	{
478 	case STYLE_None:
479 		return;
480 
481 	case STYLE_Normal:
482 		Alpha = 1.0;
483 		break;
484 
485 	case STYLE_Fuzzy:
486 		return;
487 
488 	case STYLE_Add:
489 		return;
490 	}
491 	Alpha = MID(0.0, Alpha, 1.0);
492 
493 	if (Alpha < 1.0)
494 	{
495 		return;
496 	}
497 
498 	float TimeFrac = 0;
499 	if (mobj->State->Time > 0)
500 	{
501 		TimeFrac = 1.0 - (mobj->StateTime / mobj->State->Time);
502 		TimeFrac = MID(0.0, TimeFrac, 1.0);
503 	}
504 
505 	DrawEntityModel(mobj, 0xffffffff, 0, 1, false, TimeFrac, RPASS_ShadowVolumes);
506 	unguard;
507 }
508 
509 //==========================================================================
510 //
511 //	VAdvancedRenderLevel::RenderMobjsShadow
512 //
513 //==========================================================================
514 
RenderMobjsShadow()515 void VAdvancedRenderLevel::RenderMobjsShadow()
516 {
517 	guard(VAdvancedRenderLevel::RenderMobjsShadow);
518 	if (!r_draw_mobjs || !r_models || !r_model_shadows)
519 	{
520 		return;
521 	}
522 
523 	for (TThinkerIterator<VEntity> Ent(Level); Ent; ++Ent)
524 	{
525 		RenderThingShadow(*Ent);
526 	}
527 	unguard;
528 }
529 
530 //==========================================================================
531 //
532 //	VAdvancedRenderLevel::RenderThingFog
533 //
534 //==========================================================================
535 
RenderThingFog(VEntity * mobj)536 void VAdvancedRenderLevel::RenderThingFog(VEntity* mobj)
537 {
538 	guard(VAdvancedRenderLevel::RenderThingFog);
539 	//	Skip things in subsectors that are not visible.
540 	int SubIdx = mobj->SubSector - Level->Subsectors;
541 	if (!(BspVis[SubIdx >> 3] & (1 << (SubIdx & 7))))
542 	{
543 		return;
544 	}
545 
546 	if (mobj == ViewEnt && (!r_chasecam || ViewEnt != cl->MO))
547 	{
548 		//	Don't draw camera actor.
549 		return;
550 	}
551 
552 	if ((mobj->EntityFlags & VEntity::EF_NoSector) ||
553 		(mobj->EntityFlags & VEntity::EF_Invisible))
554 	{
555 		return;
556 	}
557 	if (!mobj->State)
558 	{
559 		return;
560 	}
561 
562 	int RendStyle = mobj->RenderStyle;
563 	float Alpha = mobj->Alpha;
564 
565 	if (RendStyle == STYLE_SoulTrans)
566 	{
567 		RendStyle = STYLE_Translucent;
568 		Alpha = transsouls;
569 	}
570 	else if (RendStyle == STYLE_OptFuzzy)
571 	{
572 		RendStyle = r_drawfuzz ? STYLE_Fuzzy : STYLE_Translucent;
573 	}
574 
575 	switch (RendStyle)
576 	{
577 	case STYLE_None:
578 		return;
579 
580 	case STYLE_Normal:
581 		Alpha = 1.0;
582 		break;
583 
584 	case STYLE_Fuzzy:
585 		return;
586 
587 	case STYLE_Add:
588 		return;
589 	}
590 	Alpha = MID(0.0, Alpha, 1.0);
591 
592 	if (Alpha < 1.0)
593 	{
594 		return;
595 	}
596 	vuint32 Fade = GetFade(SV_PointInRegion(mobj->Sector, mobj->Origin));
597 	if (!Fade)
598 	{
599 		return;
600 	}
601 
602 	float TimeFrac = 0;
603 	if (mobj->State->Time > 0)
604 	{
605 		TimeFrac = 1.0 - (mobj->StateTime / mobj->State->Time);
606 		TimeFrac = MID(0.0, TimeFrac, 1.0);
607 	}
608 
609 	DrawEntityModel(mobj, 0xffffffff, Fade, 1, false, TimeFrac, RPASS_Fog);
610 	unguard;
611 }
612 
613 //==========================================================================
614 //
615 //	VAdvancedRenderLevel::RenderMobjsFog
616 //
617 //==========================================================================
618 
RenderMobjsFog()619 void VAdvancedRenderLevel::RenderMobjsFog()
620 {
621 	guard(VAdvancedRenderLevel::RenderMobjsFog);
622 	if (!r_draw_mobjs || !r_models)
623 	{
624 		return;
625 	}
626 
627 	for (TThinkerIterator<VEntity> Ent(Level); Ent; ++Ent)
628 	{
629 		RenderThingFog(*Ent);
630 	}
631 	unguard;
632 }
633