1 //**************************************************************************
2 //**
3 //**	##   ##    ##    ##   ##   ####     ####   ###     ###
4 //**	##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
5 //**	 ## ##  ##    ##  ## ##  ##    ## ##    ## ## ## ## ##
6 //**	 ## ##  ########  ## ##  ##    ## ##    ## ##  ###  ##
7 //**	  ###   ##    ##   ###    ##  ##   ##  ##  ##       ##
8 //**	   #    ##    ##    #      ####     ####   ##       ##
9 //**
10 //**	$Id: r_particle.cpp 4298 2010-06-04 21:27:57Z 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 //**	Rendering of particles.
27 //**
28 //**************************************************************************
29 
30 // HEADER FILES ------------------------------------------------------------
31 
32 #include "gamedefs.h"
33 #include "r_local.h"
34 
35 // MACROS ------------------------------------------------------------------
36 
37 // TYPES -------------------------------------------------------------------
38 
39 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
40 
41 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
42 
43 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
44 
45 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
46 
47 // PUBLIC DATA DEFINITIONS -------------------------------------------------
48 
49 VCvarI				r_draw_particles("r_draw_particles", "1", CVAR_Archive);
50 
51 // PRIVATE DATA DEFINITIONS ------------------------------------------------
52 
53 // CODE --------------------------------------------------------------------
54 
55 //==========================================================================
56 //
57 //	VRenderLevelShared::InitParticles
58 //
59 //==========================================================================
60 
InitParticles()61 void VRenderLevelShared::InitParticles()
62 {
63 	guard(VRenderLevelShared::InitParticles);
64 	const char* p = GArgs.CheckValue("-particles");
65 
66 	if (p)
67 	{
68 		NumParticles = atoi(p);
69 		if (NumParticles < ABSOLUTE_MIN_PARTICLES)
70 			NumParticles = ABSOLUTE_MIN_PARTICLES;
71 	}
72 	else
73 	{
74 		NumParticles = MAX_PARTICLES;
75 	}
76 
77 	Particles = new particle_t[NumParticles];
78 	unguard;
79 }
80 
81 //==========================================================================
82 //
83 //	VRenderLevelShared::ClearParticles
84 //
85 //==========================================================================
86 
ClearParticles()87 void VRenderLevelShared::ClearParticles()
88 {
89 	guard(VRenderLevelShared::ClearParticles);
90 	FreeParticles = &Particles[0];
91 	ActiveParticles = NULL;
92 
93 	for (int i = 0; i < NumParticles; i++)
94 		Particles[i].next = &Particles[i + 1];
95 	Particles[NumParticles - 1].next = NULL;
96 	unguard;
97 }
98 
99 //==========================================================================
100 //
101 //	VRenderLevelShared::NewParticle
102 //
103 //==========================================================================
104 
NewParticle()105 particle_t* VRenderLevelShared::NewParticle()
106 {
107 	guard(VRenderLevelShared::NewParticle);
108 	if (!FreeParticles)
109 	{
110 		//	No free particles
111 		return NULL;
112 	}
113 	//	Remove from list of free particles
114 	particle_t* p = FreeParticles;
115 	FreeParticles = p->next;
116 	//	Clean
117 	memset(p, 0, sizeof(*p));
118 	//	Add to active particles
119 	p->next = ActiveParticles;
120 	ActiveParticles = p;
121 	return p;
122 	unguard;
123 }
124 
125 //==========================================================================
126 //
127 //	VRenderLevelShared::UpdateParticles
128 //
129 //==========================================================================
130 
UpdateParticles(float frametime)131 void VRenderLevelShared::UpdateParticles(float frametime)
132 {
133 	guard(VRenderLevelShared::UpdateParticles);
134 	particle_t		*p, *kill;
135 
136 	if (GGameInfo->IsPaused())
137 	{
138 		return;
139 	}
140 
141 	kill = ActiveParticles;
142 	while (kill && kill->die < Level->Time)
143 	{
144 		ActiveParticles = kill->next;
145 		kill->next = FreeParticles;
146 		FreeParticles = kill;
147 		kill = ActiveParticles;
148 	}
149 
150 	for (p = ActiveParticles; p; p = p->next)
151 	{
152 		kill = p->next;
153 		while (kill && kill->die < Level->Time)
154 		{
155 			p->next = kill->next;
156 			kill->next = FreeParticles;
157 			FreeParticles = kill;
158 			kill = p->next;
159 		}
160 
161 		p->org += (p->vel * frametime);
162 		Level->LevelInfo->eventUpdateParticle(p, frametime);
163 	}
164 	unguard;
165 }
166 
167 //==========================================================================
168 //
169 //	VRenderLevelShared::DrawParticles
170 //
171 //==========================================================================
172 
DrawParticles()173 void VRenderLevelShared::DrawParticles()
174 {
175 	guard(VRenderLevelShared::DrawParticles);
176 	if (!r_draw_particles)
177 	{
178 		return;
179 	}
180 	Drawer->StartParticles();
181 	for (particle_t* p = ActiveParticles; p; p = p->next)
182 	{
183 		if (ColourMap)
184 		{
185 			vuint32 Col = p->colour;
186 			rgba_t TmpCol = ColourMaps[ColourMap].GetPalette()[R_LookupRGB(
187 				(Col >> 16) & 0xff, (Col >> 8) & 0xff, Col & 0xff)];
188 			p->colour = (Col & 0xff000000) | (TmpCol.r << 16) |
189 				(TmpCol.g << 8) | TmpCol.b;
190 			Drawer->DrawParticle(p);
191 			p->colour = Col;
192 		}
193 		else
194 		{
195 			Drawer->DrawParticle(p);
196 		}
197 	}
198 	Drawer->EndParticles();
199 	unguard;
200 }
201