3 * Daniel Nelson - 8/31/0
5 * Copyright (C) 2000 Daniel Nelson
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
25 * Handle's the displaying of the blocks.
31 // FIXME: may actually need GL/glext.h
37 #include "Displayer.h"
40 #include "BlockManager.h"
41 #include "LightManager.h"
45 const GLfloat
Displayer::block_colors
[BF_NUMBER
][3]
46 = { { 0.73f
, 0.0f
, 0.73f
}, // purple
47 { 0.2f
, 0.2f
, 0.8f
}, // blue
48 { 0.0f
, 0.6f
, 0.05f
}, // green
49 { 0.85f
, 0.85f
, 0.0f
}, // yellow
50 { 1.0f
, 0.4f
, 0.0f
}, // orange
51 { 1.0f
, 0.0f
, 0.0f
}, // wild
52 { 0.4f
, 0.4f
, 0.4f
}, // gray
53 { 0.05f
, 0.05f
, 0.05f
}, // black
54 { 0.95f
, 0.95f
, 0.95f
}, // white
55 { 2.0f
* 0.73f
, 2.0f
* 0.0f
, 2.0f
* 0.73f
}, // special purple
56 { 2.0f
* 0.2f
, 2.0f
* 0.2f
, 2.0f
* 0.8f
}, // special blue
57 { 2.0f
* 0.0f
, 2.0f
* 0.6f
, 2.0f
* 0.05f
}, // special green
58 { 2.0f
* 0.85f
, 2.0f
* 0.85f
, 2.0f
* 0.0f
}, // special yellow
59 { 2.0f
* 1.0f
, 2.0f
* 0.4f
, 2.0f
* 0.0f
} }; // special orange
61 const GLfloat creep_colors
[BF_NUMBER
][3]
62 = { { 0.25f
* 0.73f
, 0.25f
* 0.0f
, 0.25f
* 0.73f
}, // purple
63 { 0.25f
* 0.2f
, 0.25f
* 0.2f
, 0.25f
* 0.8f
}, // blue
64 { 0.25f
* 0.0f
, 0.25f
* 0.6f
, 0.25f
* 0.05f
}, // green
65 { 0.25f
* 0.85f
, 0.25f
* 0.85f
, 0.25f
* 0.0f
}, // yellow
66 { 0.25f
* 1.0f
, 0.25f
* 0.4f
, 0.25f
* 0.0f
}, // orange
67 { 0.25f
* 1.0f
, 0.25f
* 0.0f
, 0.25f
* 0.0f
}, // wild
68 { 0.25f
* 0.4f
, 0.25f
* 0.4f
, 0.25f
* 0.4f
}, // gray
69 { 0.25f
* 0.05f
, 0.25f
* 0.05f
, 0.25f
* 0.05f
}, // black
70 { 0.25f
* 0.95f
, 0.25f
* 0.95f
, 0.25f
* 0.95f
}, // white
71 { 0.5f
* 0.73f
, 0.5f
* 0.0f
, 0.5f
* 0.73f
}, // special purple
72 { 0.5f
* 0.2f
, 0.5f
* 0.2f
, 0.5f
* 0.8f
}, // special blue
73 { 0.5f
* 0.0f
, 0.5f
* 0.6f
, 0.5f
* 0.05f
}, // special green
74 { 0.5f
* 0.85f
, 0.5f
* 0.85f
, 0.5f
* 0.0f
}, // special yellow
75 { 0.5f
* 1.0f
, 0.5f
* 0.4f
, 0.5f
* 0.0f
} }; // special orange
77 void Displayer::setWildBlockColor ( Block
&block
, float flash
)
79 Wild
&wild
= X::wild(block
);
81 if (wild
.alarm
< GC_WILD_POLYMORPH_PERIOD
) {
82 GLfloat fade
= wild
.alarm
* (1.0f
/ (GLfloat
) GC_WILD_POLYMORPH_PERIOD
);
85 if (wild
.flavor
!= BF_NORMAL_1
)
86 next_color
= wild
.flavor
- 1;
92 color
[0] = fade
* block_colors
[wild
.flavor
][0]
93 + (1.0f
- fade
) * block_colors
[next_color
][0];
94 color
[1] = fade
* block_colors
[wild
.flavor
][1]
95 + (1.0f
- fade
) * block_colors
[next_color
][1];
96 color
[2] = fade
* block_colors
[wild
.flavor
][2]
97 + (1.0f
- fade
) * block_colors
[next_color
][2];
99 color
[0] = fade
* creep_colors
[wild
.flavor
][0]
100 + (1.0f
- fade
) * creep_colors
[next_color
][0];
101 color
[1] = fade
* creep_colors
[wild
.flavor
][1]
102 + (1.0f
- fade
) * creep_colors
[next_color
][1];
103 color
[2] = fade
* creep_colors
[wild
.flavor
][2]
104 + (1.0f
- fade
) * creep_colors
[next_color
][2];
107 glColor3f(color
[0] + flash
* (DC_FLASH_COLOR_RED
- color
[0]),
108 color
[1] + flash
* (DC_FLASH_COLOR_GREEN
- color
[1]),
109 color
[2] + flash
* (DC_FLASH_COLOR_BLUE
- color
[2]));
113 glColor3f(block_colors
[wild
.flavor
][0]
114 + flash
* (DC_FLASH_COLOR_RED
- block_colors
[wild
.flavor
][0]),
115 block_colors
[wild
.flavor
][1]
116 + flash
* (DC_FLASH_COLOR_GREEN
- block_colors
[wild
.flavor
][1]),
117 block_colors
[wild
.flavor
][2]
118 + flash
* (DC_FLASH_COLOR_BLUE
- block_colors
[wild
.flavor
][2]));
120 glColor3f(creep_colors
[wild
.flavor
][0]
121 + flash
* (DC_FLASH_COLOR_RED
- creep_colors
[wild
.flavor
][0]),
122 creep_colors
[wild
.flavor
][1]
123 + flash
* (DC_FLASH_COLOR_GREEN
- creep_colors
[wild
.flavor
][1]),
124 creep_colors
[wild
.flavor
][2]
125 + flash
* (DC_FLASH_COLOR_BLUE
- creep_colors
[wild
.flavor
][2]));
128 void Displayer::drawBlocks ( )
130 glColorMaterial(GL_FRONT
, GL_DIFFUSE
);
132 // GL_FRONT_AND_BACK because the garbage uses these material properties
133 // also and I don't think it hurts with cull face on.
135 color
[0] = 0.0f
; color
[1] = 0.0f
; color
[2] = 0.0f
; color
[3] = 1.0f
;
136 glMaterialfv(GL_FRONT_AND_BACK
, GL_AMBIENT
, color
);
137 color
[0] = 0.5f
; color
[1] = 0.5f
; color
[2] = 0.5f
; color
[3] = 1.0f
;
138 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, color
);
139 color
[0] = 0.0f
; color
[1] = 0.0f
; color
[2] = 0.0f
; color
[3] = 1.0f
;
140 glMaterialfv(GL_FRONT_AND_BACK
, GL_EMISSION
, color
);
141 glMaterialf(GL_FRONT_AND_BACK
, GL_SHININESS
, 10.0f
);
143 // First we'll draw the non-special color blocks.
145 int c
= BlockManager::block_count
;
146 for (int n
= 0; c
; n
++)
147 if (BlockManager::storeMap
[n
]) {
148 Block
&block
= BlockManager::blockStore
[n
];
151 if (BlockManager::isSpecialColorFlavor(block
.flavor
)) continue;
153 if (block
.y
> GC_SAFE_HEIGHT
) continue;
155 drawBlock(block
, false);
158 if (!X::specialColorActive()) return;
160 // Then we set things up for special color blocks and draw them.
162 if (opengl_version_1_2
)
163 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
, GL_SEPARATE_SPECULAR_COLOR
);
165 glEnable(GL_TEXTURE_1D
);
167 glBindTexture(GL_TEXTURE_1D
, special_block_lightmap
);
169 c
= X::special_color_count
;
170 for (int n
= 0; c
; n
++)
171 if (BlockManager::storeMap
[n
]) {
172 Block
&block
= BlockManager::blockStore
[n
];
174 if (!BlockManager::isSpecialColorFlavor(block
.flavor
)) continue;
177 glMatrixMode(GL_TEXTURE
);
180 glTranslatef(((Game::time_step
+ block
.X
) & (DC_GLEAM_PERIOD
- 1))
181 * (1.0f
/ (GLfloat
) DC_GLEAM_PERIOD
), 0.0f
, 0.0f
);
182 glRotatef(DC_GLEAM_ROTATION_RATE
* (Game::time_step
+ block
.X
),
183 DC_GLEAM_ROTATION_AXIS_X
, DC_GLEAM_ROTATION_AXIS_Y
,
184 DC_GLEAM_ROTATION_AXIS_Z
);
185 glMatrixMode(GL_MODELVIEW
);
187 drawBlock(block
, true);
189 glMatrixMode(GL_TEXTURE
);
191 glMatrixMode(GL_MODELVIEW
);
194 glDisable(GL_TEXTURE_1D
);
196 if (opengl_version_1_2
)
197 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
, GL_SINGLE_COLOR
);
200 inline void Displayer::drawBlock ( Block
&block
, bool special
)
207 y
= block
.y
* DC_GRID_ELEMENT_LENGTH
208 + block
.f_y
* (DC_GRID_ELEMENT_LENGTH
/ (GLfloat
) GC_STEPS_PER_GRID
)
212 if (block
.state
& (BS_STATIC
| BS_FALLING
)) {
213 x
= block
.x
* DC_GRID_ELEMENT_LENGTH
+ DC_PLAY_OFFSET_X
;
215 if (block
.flavor
!= BF_WILD
)
217 glColor3fv(block_colors
[block
.flavor
]);
219 glColor3fv(creep_colors
[block
.flavor
]);
221 setWildBlockColor(block
, 0.0f
);
223 LightManager::setupBlockLights(x
, y
);
224 glTranslatef(x
, y
, DC_PLAY_OFFSET_Z
);
227 glCallList(block_list
);
229 glCallList(special_block_list
);
231 // awaking and popping
232 } else if (block
.state
& BS_AWAKING
) {
233 x
= block
.x
* DC_GRID_ELEMENT_LENGTH
+ DC_PLAY_OFFSET_X
;
235 LightManager::setupBlockLights(x
, y
);
236 glTranslatef(x
, y
, DC_PLAY_OFFSET_Z
);
238 // if we haven't popped yet
239 if (block
.pop_alarm
!= 0) {
241 // if we're just about to pop
242 if (block
.pop_alarm
- Game::time_step
< DC_POP_ROTATE_TIME
) {
243 GLfloat p
= (block
.pop_alarm
- Game::time_step
)
244 * (1.0f
/ (GLfloat
) DC_POP_ROTATE_TIME
);
246 // each block rotates a different direction
247 if (block
.pop_direction
& BR_DIRECTION_1
) {
248 glRotatef(45.0f
* p
, 1.0f
, 0.0f
, 0.0f
);
249 glRotatef(45.0f
* p
, 0.0f
, 1.0f
, 0.0f
);
250 } else if (block
.pop_direction
& BR_DIRECTION_2
) {
251 glRotatef(90.0f
- 45.0f
* p
, 1.0f
, 0.0f
, 0.0f
);
252 glRotatef(45.0f
* p
, 0.0f
, 1.0f
, 0.0f
);
253 } else if (block
.pop_direction
& BR_DIRECTION_3
) {
254 glRotatef(90.0f
- 45.0f
* p
, 1.0f
, 0.0f
, 0.0f
);
255 glRotatef(-45.0f
* p
, 0.0f
, 1.0f
, 0.0f
);
257 glRotatef(45.0f
* p
, 1.0f
, 0.0f
, 0.0f
);
258 glRotatef(-45.0f
* p
, 0.0f
, 1.0f
, 0.0f
);
261 GLfloat scale
= 1.0f
- 0.5f
* p
;
262 glScalef(scale
, scale
, scale
);
264 glColor3f( (1.0f
- p
) * block_colors
[block
.flavor
][0]
265 + p
* garbage_colors
[block
.pop_color
][0],
266 (1.0f
- p
) * block_colors
[block
.flavor
][1]
267 + p
* garbage_colors
[block
.pop_color
][1],
268 (1.0f
- p
) * block_colors
[block
.flavor
][2]
269 + p
* garbage_colors
[block
.pop_color
][2]);
271 glEnable(rescale_method
);
272 glCallList(block_list
);
273 glDisable(rescale_method
);
275 // if we're not popping
278 glColor3fv(garbage_colors
[block
.pop_color
]);
280 // the small block is pre-rotated
281 glCallList(small_block_list
);
284 // if we've already popped
286 glColor3fv(block_colors
[block
.flavor
]);
288 glCallList(block_list
);
292 } else if (block
.state
& BS_SWAPPING
) {
293 x
= block
.x
* DC_GRID_ELEMENT_LENGTH
+ DC_PLAY_OFFSET_X
;
295 if (block
.state
& BS_SWAP_DIRECTION_MASK
) {
296 LightManager::setupBlockLights(x
+ Swapper::swap_factor
297 * DC_GRID_ELEMENT_LENGTH
, y
);
298 d_x
= -DC_GRID_ELEMENT_LENGTH
/ 2.0f
;
301 LightManager::setupBlockLights(x
- Swapper::swap_factor
302 * DC_GRID_ELEMENT_LENGTH
, y
);
303 d_x
= DC_GRID_ELEMENT_LENGTH
/ 2.0f
;
306 if (block
.flavor
!= BF_WILD
)
307 glColor3fv(block_colors
[block
.flavor
]);
309 setWildBlockColor(block
, 0.0f
);
311 glTranslatef(x
- d_x
, y
, DC_PLAY_OFFSET_Z
);
312 glRotatef(-180.0f
* (1.0f
- Swapper::swap_factor
), 0.0f
, 1.0f
, 0.0f
);
313 glTranslatef(d_x
, 0.0f
, 0.0f
);
316 glCallList(block_list
);
318 glCallList(special_block_list
);
321 } else if (block
.state
& BS_DYING
) {
322 x
= block
.x
* DC_GRID_ELEMENT_LENGTH
+ DC_PLAY_OFFSET_X
;
324 // when dying, first we flash
325 if (GC_DYING_DELAY
- block
.alarm
< DC_DYING_FLASH_TIME
) {
327 GLfloat flash
= ((GLfloat
) GC_DYING_DELAY
- block
.alarm
)
328 * (4.0f
/ (GLfloat
) DC_DYING_FLASH_TIME
);
329 if (flash
> 2.0f
) flash
= 4.0f
- flash
;
330 if (flash
> 1.0f
) flash
= 2.0f
- flash
;
332 if (block
.flavor
!= BF_WILD
)
333 glColor3f(block_colors
[block
.flavor
][0]
334 + flash
* (DC_FLASH_COLOR_RED
- block_colors
[block
.flavor
][0]),
335 block_colors
[block
.flavor
][1]
336 + flash
* (DC_FLASH_COLOR_GREEN
- block_colors
[block
.flavor
][1]),
337 block_colors
[block
.flavor
][2]
338 + flash
* (DC_FLASH_COLOR_BLUE
- block_colors
[block
.flavor
][2]));
340 setWildBlockColor(block
, flash
);
342 LightManager::setupBlockLights(x
, y
);
343 glTranslatef(x
, y
, DC_PLAY_OFFSET_Z
);
345 glCallList(block_list
);
347 glCallList(special_block_list
);
349 // then we shrink and spin
351 if (block
.flavor
!= BF_WILD
)
352 glColor3fv(block_colors
[block
.flavor
]);
354 setWildBlockColor(block
, 0.0f
);
356 LightManager::setupBlockLights(x
, y
);
357 glTranslatef(x
, y
, DC_PLAY_OFFSET_Z
);
358 glRotatef((GC_DYING_DELAY
- DC_DYING_FLASH_TIME
- block
.alarm
)
359 * (GC_DYING_DELAY
- DC_DYING_FLASH_TIME
- block
.alarm
)
360 * DC_DYING_ROTATE_SPEED
, block
.axis_x
, block
.axis_y
, 0.0f
);
362 GLfloat scale
= block
.alarm
* DC_DYING_SHRINK_SPEED
363 + DC_DYING_SHRINK_MIN_SIZE
;
364 glScalef(scale
, scale
, scale
);
366 glEnable(rescale_method
);
368 glCallList(block_list
);
370 glCallList(special_block_list
);
371 glDisable(rescale_method
);