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