Each module now includes its own header first. Removed sstream.h and the definition...
[crack-attack.git] / src / LightManager.cxx
blob18549e71deeb593f40e72a91d08cfc37135c5de3
1 /*
2 * LightManager.cxx
3 * Daniel Nelson - 9/13/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 turning on and off the required lights during drawing.
28 #include "LightManager.h"
30 #include <GL/glut.h>
31 #include "glext.h"
33 #include "Game.h"
34 #include "Displayer.h"
35 #include "SparkleManager.h"
36 #include "CountDownManager.h"
37 #include "CelebrationManager.h"
39 // assumed to all be 1.0f in setupHeadLight()
40 const GLfloat headlight_normal_color[]
41 = { 1.0f, 1.0f, 1.0f, 1.0f };
43 GLfloat headlight_color[]
44 = { 0.0f, 0.0f, 0.0f, 1.0f };
46 Light LightManager::lights[DC_NUMBER_EXTRA_LIGHTS];
47 int LightManager::last_associated;
48 bool LightManager::headlight_normal;
50 void LightManager::initialize ( )
52 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS)) {
53 for (int n = DC_NUMBER_EXTRA_LIGHTS; n--; ) {
54 lights[n].location[2] = DC_PLAY_OFFSET_Z + DC_MOTE_LIGHT_OFFSET_Z;
55 lights[n].location[3] = 1.0f;
56 lights[n].enabled = false;
59 headlight_normal = false;
63 void LightManager::setupHeadLightPlay_inline_split_ ( )
65 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS)) {
67 GLfloat headlight_level;
69 headlight_normal = false;
71 if (!(Game::state & GS_SYNC_WAIT))
72 headlight_level = 1.0f;
73 else
74 headlight_level = DC_SYNC_WAIT_LIGHT_LEVEL;
76 if (CountDownManager::state != -1) {
77 float fade = (GC_START_PAUSE_DELAY - CountDownManager::start_pause_alarm)
78 * (1.0f / (float) GC_START_PAUSE_DELAY);
79 headlight_level *= Game::sqrt(fade);
82 headlight_color[0] = headlight_color[1] = headlight_color[2] =
83 headlight_level;
85 if (X::crazyLights())
86 X::modifyHeadlightColor(headlight_color);
88 glLightfv(GL_LIGHT0, GL_DIFFUSE, headlight_color);
89 glLightfv(GL_LIGHT0, GL_SPECULAR, headlight_color);
93 void LightManager::setupHeadLightMeta ( )
95 * Setup the headlight for the game end celebration fade out.
98 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS)) {
99 headlight_color[0] = headlight_color[1] = headlight_color[2]
100 = CelebrationManager::light_level;
102 glLightfv(GL_LIGHT0, GL_DIFFUSE, headlight_color);
103 glLightfv(GL_LIGHT0, GL_SPECULAR, headlight_color);
104 headlight_normal = false;
108 void LightManager::resetHeadLight_inline_split_ ( )
110 * If the headlight is not normal, reset it to standard values.
113 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS)) {
114 glLightfv(GL_LIGHT0, GL_DIFFUSE, headlight_normal_color);
115 glLightfv(GL_LIGHT0, GL_SPECULAR, headlight_normal_color);
116 headlight_normal = true;
120 void LightManager::setupBlockLights ( float x, float y )
122 * Here's an out line of the algorithm. We loop through the motes. If a
123 * mote is in range, we check to see if it has an associated light. If so,
124 * we make sure the light is enabled. If not, we find a light to associate
125 * with the mote. If the mote is out of range, we disable the light but we
126 * don't disassociate. This way, if we have space, we can use a minimum of
127 * light color and position reasignments.
129 * To find a light to associate with a mote, first we look for an unassociated
130 * light. If there are none, we look for a disabled light. If there are none,
131 * we disable a currently enabled light and use it.
134 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS)) {
135 for (int n = DC_NUMBER_EXTRA_LIGHTS; n--; )
136 lights[n].to_be_enabled = false;
138 int c = SparkleManager::mote_count;
139 for (int m = 0; c; m++)
140 if (SparkleManager::motes[m].active) {
141 Mote &mote = SparkleManager::motes[m];
142 c--;
144 float r = (x - mote.x) * (x - mote.x) + (y - mote.y) * (y - mote.y);
146 // if the mote's light needs to be on for this draw; note that range is
147 // not the light range but the range to the center of block any block
148 // effected
149 if (r < DC_MOTE_LIGHT_RANGE * DC_MOTE_LIGHT_RANGE) {
151 // if this mote has been previously associated with a light and that
152 // light's association still matches
153 if (mote.associated_light != -1
154 && lights[mote.associated_light].association == m) {
156 // make sure the light is enabled
157 lights[mote.associated_light].to_be_enabled = true;
158 configureBlockBrightness(lights[mote.associated_light],
159 mote.associated_light, mote, r);
161 // if this mote has no active association; we must try to find an
162 // unassociated light
163 } else {
165 // find an unassociated light
166 int a = -1;
167 int l = last_associated;
168 do {
169 if (++last_associated == DC_NUMBER_EXTRA_LIGHTS)
170 last_associated = 0;
172 if (lights[last_associated].association == -1) {
173 a = last_associated;
174 break;
176 } while (last_associated != l);
178 // if we found one
179 if (a != -1) {
181 // associate
182 associateLight(lights[a], a, mote, m);
184 // enable
185 lights[a].to_be_enabled = true;
186 configureBlockBrightness(lights[a], a, mote, r);
188 // if we couldn't find an unassociated light
189 } else {
191 // find an associated but disabled light
192 l = last_associated;
193 do {
194 if (++last_associated == DC_NUMBER_EXTRA_LIGHTS)
195 last_associated = 0;
197 if (!lights[last_associated].to_be_enabled) {
198 a = last_associated;
199 break;
201 } while (last_associated != l);
203 // if we found none
204 if (a != -1) {
206 // associate
207 associateLight(lights[a], a, mote, m);
209 // enable
210 lights[a].to_be_enabled = true;
211 configureBlockBrightness(lights[a], a, mote, r);
213 // if we couldn't find a disabled light
214 } else
216 // we have no choice but to steal an enabled one or give up
217 break;
223 for (int n = DC_NUMBER_EXTRA_LIGHTS; n--; )
224 if (lights[n].to_be_enabled) {
225 if (!lights[n].enabled) {
226 glEnable((GLenum) (DC_EXTRA_LIGHT_BASE + n));
227 lights[n].enabled = true;
229 } else {
230 if (lights[n].enabled) {
231 glDisable((GLenum) (DC_EXTRA_LIGHT_BASE + n));
232 lights[n].enabled = false;
238 void LightManager::setupGarbageLights ( float x, float y, int h, int w )
240 * We only hand dim the light for motes not in the garbage. Plus, we have to
241 * use an attenuated light source.
244 if (!(MetaState::mode & CM_REALLY_LOW_GRAPHICS)) {
246 for (int n = DC_NUMBER_EXTRA_LIGHTS; n--; )
247 lights[n].to_be_enabled = false;
249 int c = SparkleManager::mote_count;
250 for (int m = 0; c; m++)
251 if (SparkleManager::motes[m].active) {
252 Mote &mote = SparkleManager::motes[m];
253 c--;
255 float x_high = x + (w - 1) * DC_GRID_ELEMENT_LENGTH;
256 float y_high = y + (h - 1) * DC_GRID_ELEMENT_LENGTH;
258 float r = 0.0f;
260 if (mote.x < x)
261 r += (x - mote.x) * (x - mote.x);
262 else if (mote.x > x_high)
263 r += (x_high - mote.x) * (x_high - mote.x);
264 if (mote.y < y)
265 r += (y - mote.y) * (y - mote.y);
266 else if (mote.y > y_high)
267 r += (y_high - mote.y) * (y_high - mote.y);
269 // if the mote's light needs to be on for this draw
270 if (r < DC_MOTE_LIGHT_RANGE * DC_MOTE_LIGHT_RANGE) {
272 // if this mote has been previously associated with a light and that
273 // light's association still matches
274 if (mote.associated_light != -1
275 && lights[mote.associated_light].association == m) {
277 // make sure the light is enabled
278 lights[mote.associated_light].to_be_enabled = true;
279 configureGarbageBrightness(lights[mote.associated_light],
280 mote.associated_light, mote, r);
282 // if this mote has no active association; we must try to find an
283 // unassociated light
284 } else {
286 // find an unassociated light
287 int a = -1;
288 int l = last_associated;
289 do {
290 if (++last_associated == DC_NUMBER_EXTRA_LIGHTS)
291 last_associated = 0;
293 if (lights[last_associated].association == -1) {
294 a = last_associated;
295 break;
297 } while (last_associated != l);
299 // if we found one
300 if (a != -1) {
302 // associate
303 associateLight(lights[a], a, mote, m);
305 // enable
306 lights[a].to_be_enabled = true;
307 configureGarbageBrightness(lights[a], a, mote, r);
309 // if we couldn't find an unassociated light
310 } else {
312 // find an associated but disabled light
313 l = last_associated;
314 do {
315 if (++last_associated == DC_NUMBER_EXTRA_LIGHTS)
316 last_associated = 0;
318 if (!lights[last_associated].to_be_enabled) {
319 a = last_associated;
320 break;
322 } while (last_associated != l);
324 // if we found none
325 if (a != -1) {
327 // associate
328 associateLight(lights[a], a, mote, m);
330 // enable
331 lights[a].to_be_enabled = true;
332 configureGarbageBrightness(lights[a], a, mote, r);
334 // if we couldn't find a disabled light
335 } else
337 // we have no choice but to steal an enabled one or give up
338 break;
344 for (int n = DC_NUMBER_EXTRA_LIGHTS; n--; )
345 if (lights[n].to_be_enabled) {
346 if (!lights[n].enabled) {
347 glEnable((GLenum) (DC_EXTRA_LIGHT_BASE + n));
348 if (!lights[n].attenuated)
349 attenuateLight(lights[n], n);
350 lights[n].enabled = true;
352 } else {
353 if (lights[n].enabled) {
354 glDisable((GLenum) (DC_EXTRA_LIGHT_BASE + n));
355 lights[n].enabled = false;