Updated to work with freeglut 2.4.0
[crack-attack.git] / src / SparkleManager.cxx
blob6a071288afc9b0aef72b963d5e8983483b399e5c
1 /*
2 * SparkleManager.cxx
3 * Daniel Nelson - 9/4/0
5 * Copyright (C) 2000 Daniel Nelson
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * Daniel Nelson - aluminumangel.org
22 * 174 W. 18th Ave.
23 * Columbus, OH 43210
25 * Handles all the pretty sparkles!
28 using namespace std;
30 #include "Game.h"
31 #include "Displayer.h"
32 #include "MetaState.h"
33 #include "Random.h"
34 #include "SparkleManager.h"
36 int SparkleManager::spark_count;
37 Spark SparkleManager::sparks[DC_MAX_SPARK_NUMBER];
39 int SparkleManager::mote_count;
40 Mote SparkleManager::motes[DC_MAX_MOTE_NUMBER];
42 const int SparkleManager::mote_colors[DC_NUMBER_MOTE_LEVELS]
43 = { 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11,
44 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3 };
46 const int SparkleManager::mote_light_colors[DC_NUMBER_MOTE_LEVELS]
47 = { 0, 0, 0, 0, 1, 0, 2, 3, 4, 5, 6,
48 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
50 const int SparkleManager::mote_types[DC_NUMBER_MOTE_LEVELS]
51 = { MT_FOUR_POINTED_STAR, MT_FIVE_POINTED_STAR,
52 MT_SIX_POINTED_STAR, MT_SPECIAL_STAR, MT_SPECIAL_STAR, MT_SPECIAL_STAR,
53 MT_SPECIAL_STAR, MT_SPECIAL_STAR, MT_SPECIAL_STAR, MT_SPECIAL_STAR,
54 MT_SPECIAL_STAR, MT_MULTIPLIER_ONE_STAR, MT_MULTIPLIER_TWO_STAR,
55 MT_MULTIPLIER_THREE_STAR, MT_MULTIPLIER_THREE_STAR,
56 MT_MULTIPLIER_THREE_STAR, MT_MULTIPLIER_THREE_STAR,
57 MT_MULTIPLIER_THREE_STAR, MT_MULTIPLIER_THREE_STAR,
58 MT_MULTIPLIER_THREE_STAR, MT_MULTIPLIER_THREE_STAR,
59 MT_MULTIPLIER_THREE_STAR };
61 const GLfloat SparkleManager::mote_sizes[DC_NUMBER_MOTE_LEVELS]
62 = { 2.0f, 2.8f, 2.8f, 3.4f, 3.4f, 3.4f, 3.4f, 3.4f, 3.4f, 3.4f, 3.4f,
63 4.0f, 2.6f, 3.5f, 3.7f, 3.9f, 4.1f, 4.3f, 4.5f, 4.7f, 4.9f, 5.1f };
65 const float SparkleManager::mote_inverse_masses[DC_NUMBER_MOTE_LEVELS]
66 = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
67 1.0f, 1.0f, 1.0f, 1.0f, 1.0f / 1.4f, 1.0f / 1.8f, 1.0f / 2.2f,
68 1.0f / 2.6f, 1.0f / 3.0f, 1.0f / 3.4f, 1.0f / 3.8f, 1.0f / 4.2f };
70 void SparkleManager::initialize ( )
72 spark_count = 0;
73 for (int n = DC_MAX_SPARK_NUMBER; n--; )
74 sparks[n].active = false;
76 mote_count = 0;
77 for (int n = DC_MAX_MOTE_NUMBER; n--; )
78 motes[n].active = false;
81 void SparkleManager::createBlockDeathSpark ( int x, int y, int color, int n )
83 while (n--) {
84 if (spark_count == DC_MAX_SPARK_NUMBER) return;
86 int n;
87 for (n = 0; sparks[n].active; n++);
88 Spark &spark = sparks[n];
90 spark_count++;
91 spark.active = true;
92 spark.x = x * DC_GRID_ELEMENT_LENGTH + DC_PLAY_OFFSET_X;
93 spark.y = y * DC_GRID_ELEMENT_LENGTH + Displayer::play_offset_y;
95 float v = DC_MIN_SPARK_VELOCITY + (Random::number() + Random::number())
96 * (0.5f * (DC_MAX_SPARK_VELOCITY - DC_MIN_SPARK_VELOCITY));
97 Random::deathSparkAngle(spark.v_x, spark.v_y);
98 spark.v_x *= v;
99 spark.v_y *= v;
101 spark.a = Random::number(360);
102 spark.v_a = DC_MIN_SPARK_ANGULAR_VELOCITY
103 + (Random::number() + Random::number())
104 * (0.5f * (DC_MAX_SPARK_ANGULAR_VELOCITY - DC_MIN_SPARK_ANGULAR_VELOCITY));
105 if (Random::chanceIn2(2))
106 spark.v_a = -spark.v_a;
108 switch (Random::number2(4)) {
109 case 0:
110 spark.size = DC_MIN_SPARK_SIZE;
111 break;
112 case 1:
113 spark.size = DC_MIN_SPARK_SIZE + Random::number()
114 * (1.0f - DC_MIN_SPARK_SIZE);
115 break;
116 default:
117 spark.size = 1.0f;
118 break;
121 spark.color = color;
123 if (Random::chanceIn(DC_CHANCE_LONG_SPARK_LIFE_TIME))
124 spark.life_time = Random::number(10 * DC_SPREAD_SPARK_LIFE_TIME)
125 + Random::number(10 * DC_SPREAD_SPARK_LIFE_TIME)
126 + 10 * (DC_MEDIUM_SPARK_LIFE_TIME - DC_SPREAD_SPARK_LIFE_TIME);
127 else
128 spark.life_time = Random::number(DC_SPREAD_SPARK_LIFE_TIME)
129 + Random::number(DC_SPREAD_SPARK_LIFE_TIME)
130 + (DC_MEDIUM_SPARK_LIFE_TIME - DC_SPREAD_SPARK_LIFE_TIME);
134 void SparkleManager::createCelebrationSpark ( int source, int color )
136 if (spark_count == DC_MAX_SPARK_NUMBER) return;
138 int n;
139 for (n = 0; sparks[n].active; n++);
140 Spark &spark = sparks[n];
142 spark_count++;
143 spark.active = true;
145 float v;
146 if (source != 4) {
147 Random::celebrationSpark1Angle(spark.v_x, spark.v_y);
148 v = DC_MIN_CSPARK_VELOCITY + DC_SPREAD_CSPARK_VELOCITY * Random::number();
149 } else {
150 Random::celebrationSpark2Angle(spark.v_x, spark.v_y);
151 v = (2.0f * DC_MIN_CSPARK_VELOCITY)
152 + (2.0f * DC_SPREAD_CSPARK_VELOCITY) * Random::number();
154 spark.v_x *= v;
155 spark.v_y *= v;
157 switch (source) {
158 case 0:
159 if (MetaState::mode & CM_SOLO) {
160 spark.x = DC_PLAY_OFFSET_X + DC_SOURCE_1_SOLO_OFFSET_X;
161 spark.y = DC_PLAY_OFFSET_Y + DC_SOURCE_1_SOLO_OFFSET_Y;
162 } else {
163 spark.x = DC_PLAY_OFFSET_X + DC_SOURCE_1_OFFSET_X;
164 spark.y = DC_PLAY_OFFSET_Y + DC_SOURCE_1_OFFSET_Y;
166 break;
167 case 1:
168 spark.x = DC_PLAY_OFFSET_X + DC_SOURCE_2_OFFSET_X;
169 spark.y = DC_PLAY_OFFSET_Y + DC_SOURCE_2_OFFSET_Y;
170 break;
171 case 2:
172 if (MetaState::mode & CM_SOLO) {
173 spark.x = DC_PLAY_OFFSET_X + DC_SOURCE_3_SOLO_OFFSET_X;
174 spark.y = DC_PLAY_OFFSET_Y + DC_SOURCE_3_SOLO_OFFSET_Y;
175 } else {
176 spark.x = DC_PLAY_OFFSET_X + DC_SOURCE_3_OFFSET_X;
177 spark.y = DC_PLAY_OFFSET_Y + DC_SOURCE_3_OFFSET_Y;
179 spark.v_x = -spark.v_x;
180 break;
181 case 3:
182 spark.x = DC_PLAY_OFFSET_X + DC_SOURCE_4_OFFSET_X;
183 spark.y = DC_PLAY_OFFSET_Y + DC_SOURCE_4_OFFSET_Y;
184 spark.v_x = -spark.v_x;
185 break;
186 case 4:
187 if (MetaState::mode & CM_SOLO) {
188 spark.x = DC_PLAY_OFFSET_X + DC_SOURCE_5_SOLO_OFFSET_X;
189 spark.y = DC_PLAY_OFFSET_Y + DC_SOURCE_5_SOLO_OFFSET_Y;
190 } else {
191 spark.x = DC_PLAY_OFFSET_X + DC_SOURCE_5_OFFSET_X;
192 spark.y = DC_PLAY_OFFSET_Y + DC_SOURCE_5_OFFSET_Y;
194 break;
197 spark.a = Random::number(360);
198 spark.v_a = DC_MIN_SPARK_ANGULAR_VELOCITY
199 + (Random::number() + Random::number())
200 * (0.5f * (DC_MAX_SPARK_ANGULAR_VELOCITY - DC_MIN_SPARK_ANGULAR_VELOCITY));
201 if (Random::chanceIn2(2))
202 spark.v_a = -spark.v_a;
204 if (Random::chanceIn(3))
205 spark.size = DC_MIN_SPARK_SIZE
206 + Random::number() * (1.0f - DC_MIN_SPARK_SIZE);
207 else
208 spark.size = DC_MIN_SPARK_SIZE;
210 spark.color = color;
212 if (Random::chanceIn(DC_CHANCE_LONG_SPARK_LIFE_TIME))
213 spark.life_time = Random::number(10 * DC_SPREAD_SPARK_LIFE_TIME)
214 + Random::number(10 * DC_SPREAD_SPARK_LIFE_TIME)
215 + 10 * (DC_MEDIUM_SPARK_LIFE_TIME - DC_SPREAD_SPARK_LIFE_TIME);
216 else
217 spark.life_time = Random::number(DC_SPREAD_SPARK_LIFE_TIME)
218 + Random::number(DC_SPREAD_SPARK_LIFE_TIME)
219 + (DC_MEDIUM_SPARK_LIFE_TIME - DC_SPREAD_SPARK_LIFE_TIME);
222 void SparkleManager::createRewardMote ( int x, int y, int level,
223 int sibling_number )
225 if (mote_count == DC_MAX_MOTE_NUMBER) return;
227 int n;
228 for (n = 0; motes[n].active; n++);
229 Mote &mote = motes[n];
231 if (n == 0)
232 glEnable(GL_LIGHT1);
234 mote_count++;
235 mote.active = true;
237 if (level >= DC_NUMBER_MOTE_LEVELS)
238 level = DC_NUMBER_MOTE_LEVELS - 1;
239 mote.color = mote_colors[level];
240 mote.light_color = mote_light_colors[level];
241 mote.type = mote_types[level];
242 mote.size = mote_sizes[level];
243 mote.inverse_mass = mote_inverse_masses[level];
245 mote.x = x * DC_GRID_ELEMENT_LENGTH + DC_PLAY_OFFSET_X
246 - (DC_GRID_ELEMENT_LENGTH / 2.0f)
247 + (float) Random::number(20) * ((float) DC_GRID_ELEMENT_LENGTH / 20.0f);
248 mote.y = y * DC_GRID_ELEMENT_LENGTH + Displayer::play_offset_y
249 - (DC_GRID_ELEMENT_LENGTH / 2.0f)
250 + (float) Random::number(20) * ((float) DC_GRID_ELEMENT_LENGTH / 20.0f);
252 // slow down big ones
253 float v = (DC_MEDIUM_MOTE_VELOCITY - DC_SPREAD_MOTE_VELOCITY
254 + Random::number() * (2.0f * DC_SPREAD_MOTE_VELOCITY)) * mote.inverse_mass;
255 if (x < GC_PLAY_WIDTH / 2)
256 mote.v_x = -0.707107 * v;
257 else
258 mote.v_x = 0.707107 * v;
259 mote.v_y = -0.707107 * v;
261 mote.a = mote.initial_a = Random::number(360);
262 mote.v_a = (DC_MEDIUM_MOTE_ANGULAR_VELOCITY
263 - DC_SPREAD_MOTE_ANGULAR_VELOCITY + Random::number()
264 * (2.0f * DC_SPREAD_MOTE_ANGULAR_VELOCITY)) * mote.inverse_mass;
265 if (Random::chanceIn2(2))
266 mote.v_a = -mote.v_a;
268 mote.life_time = 0;
269 mote.sibling_delay = sibling_number * DC_MULTI_MOTE_FIRE_DELAY;
271 mote.associated_light = -1;
274 void SparkleManager::timeStep ( )
276 int c = spark_count;
277 for (int n = 0; c; n++)
278 if (sparks[n].active) {
279 Spark &spark = sparks[n];
280 c--;
282 if (--spark.life_time == 0) {
283 spark.active = false;
284 spark_count--;
286 } else {
287 spark.x += spark.v_x;
288 spark.y += spark.v_y;
290 spark.a += spark.v_a;
292 spark.v_y -= DC_SPARK_GRAVITY + DC_SPARK_DRAG * spark.v_y;
293 spark.v_x -= DC_SPARK_DRAG * spark.v_x;
297 c = mote_count;
298 for (int n = 0; c; n++)
299 if (motes[n].active) {
300 Mote &mote = motes[n];
301 c--;
303 if (mote.life_time >= 0)
304 if (++mote.life_time - mote.sibling_delay < GC_DYING_DELAY) {
305 mote.a += mote.v_a;
306 if (mote.life_time <= GC_DYING_DELAY)
307 mote.brightness = DC_MAX_MOTE_LIGHT_BRIGHTNESS
308 * mote.life_time * (1.0f / (float) GC_DYING_DELAY);
309 continue;
310 } else
311 mote.life_time = -1;
312 else if (mote.color > 0 && mote.color < DC_FIRST_SPECIAL_MOTE_COLOR)
313 mote.life_time--;
315 mote.y += mote.v_y;
316 if (mote.y > DC_PLAY_HEIGHT + mote.size * (DC_SPARKLE_LENGTH / 2.0f)) {
317 mote.active = false;
318 mote_count--;
319 continue;
322 mote.x += mote.v_x;
324 mote.a += mote.v_a;
326 mote.v_y += mote.inverse_mass * DC_MOTE_UPWARD_FORCE
327 - DC_MOTE_DRAG * mote.v_y;
328 mote.v_x -= mote.inverse_mass * DC_MOTE_CENTER_SPRING * mote.x
329 + DC_MOTE_DRAG * mote.v_x;
331 mote.v_a -= mote.inverse_mass
332 * DC_MOTE_TWIST_SPRING * (mote.a - mote.initial_a);