1 /*
2 TODO:
3 * Get Roja working.
4 * New effect options.
5 * New effects.
6 */
7
8 #ifdef EYE_CANDY
9
10 #include "global.h"
11 #include "interface.h"
12 #include "elwindows.h"
13 #include "shadows.h"
14 #include "gui.h"
15 #include "editor.h"
16
17 #include "../eye_candy/eye_candy.h"
18 #include <vector>
19 #include "eye_candy_window.h"
20
21 extern "C"
22 {
23 int view_eye_candy_window=0;
24 int last_ec_index = -2; // None selected.
25 int eye_candy_window = -1;
26 int eye_candy_confirmed = 0;
27 int eye_candy_initialized = 0;
28 int eye_candy_ready_to_add = 0;
29 }
30
31 static int eye_candy_window_x=15;
32 static int eye_candy_window_y=50;
33 static int eye_candy_window_x_len=600;
34 static int eye_candy_window_y_len=470;
35 std::vector<EffectDefinition> effects;
36 EffectDefinition current_effect;
37
create_eye_candy_window()38 extern "C" void create_eye_candy_window ()
39 {
40 if (eye_candy_window < 0)
41 {
42 eye_candy_window = create_window ("eye_candy", 0, 0, eye_candy_window_x, eye_candy_window_y, eye_candy_window_x_len, eye_candy_window_y_len, ELW_WIN_DEFAULT & ~ELW_SHOW);
43
44 set_window_handler (eye_candy_window, ELW_HANDLER_DISPLAY, &display_eye_candy_window_handler);
45 set_window_handler (eye_candy_window, ELW_HANDLER_CLICK, &check_eye_candy_window_interface);
46 }
47 }
48
change_eye_candy_effect()49 extern "C" void change_eye_candy_effect()
50 {
51 if (!eye_candy_initialized)
52 return;
53 current_effect.effect = gtk_combo_box_get_active(GTK_COMBO_BOX(gtk_effect_list));
54 current_effect.hue = GTK_ADJUSTMENT(gtk_effect_hue_obj)->value;
55 current_effect.saturation = GTK_ADJUSTMENT(gtk_effect_saturation_obj)->value;
56 current_effect.scale = GTK_ADJUSTMENT(gtk_effect_scale_obj)->value;
57 current_effect.density = GTK_ADJUSTMENT(gtk_effect_density_obj)->value;
58 current_effect.base_height = atoi(gtk_entry_get_text(GTK_ENTRY(gtk_effect_base_height)));
59 if (current_effect.reference)
60 {
61 ec_recall_effect(current_effect.reference);
62 current_effect.reference = NULL;
63 }
64 switch (current_effect.effect)
65 {
66 case 0: // Fire
67 gtk_widget_show(gtk_effect_hue_box);
68 gtk_widget_show(gtk_effect_saturation_box);
69 gtk_widget_show(gtk_effect_scale_box);
70 gtk_widget_hide(gtk_effect_density_box);
71 gtk_widget_hide(gtk_effect_base_height_box);
72 current_effect.reference = ec_create_campfire(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation, 10, current_effect.scale);
73 break;
74 case 1: // Cloud/Fog
75 gtk_widget_show(gtk_effect_hue_box);
76 gtk_widget_show(gtk_effect_saturation_box);
77 gtk_widget_hide(gtk_effect_scale_box);
78 gtk_widget_show(gtk_effect_density_box);
79 gtk_widget_hide(gtk_effect_base_height_box);
80 current_effect.reference = ec_create_cloud(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation, current_effect.density, (current_effect.bounds.elements.size() > 1 ? ¤t_effect.bounds : &initial_bounds), 10);
81 break;
82 case 2: // Fireflies
83 gtk_widget_show(gtk_effect_hue_box);
84 gtk_widget_show(gtk_effect_saturation_box);
85 gtk_widget_show(gtk_effect_scale_box);
86 gtk_widget_show(gtk_effect_density_box);
87 gtk_widget_hide(gtk_effect_base_height_box);
88 current_effect.reference = ec_create_fireflies(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation, current_effect.density, current_effect.scale, (current_effect.bounds.elements.size() > 1 ? ¤t_effect.bounds : &initial_bounds));
89 break;
90 case 3: // Fountain
91 gtk_widget_show(gtk_effect_hue_box);
92 gtk_widget_show(gtk_effect_saturation_box);
93 gtk_widget_show(gtk_effect_scale_box);
94 gtk_widget_hide(gtk_effect_density_box);
95 gtk_widget_show(gtk_effect_base_height_box);
96 current_effect.reference = ec_create_fountain(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation, current_effect.base_height, false, current_effect.scale, 10);
97 break;
98 case 4: // Lamp/Torch
99 gtk_widget_show(gtk_effect_hue_box);
100 gtk_widget_show(gtk_effect_saturation_box);
101 gtk_widget_show(gtk_effect_scale_box);
102 gtk_widget_hide(gtk_effect_density_box);
103 gtk_widget_hide(gtk_effect_base_height_box);
104 current_effect.reference = ec_create_lamp(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation, current_effect.scale, 10);
105 break;
106 case 5: // Magic Protection
107 gtk_widget_show(gtk_effect_hue_box);
108 gtk_widget_show(gtk_effect_saturation_box);
109 gtk_widget_show(gtk_effect_scale_box);
110 gtk_widget_hide(gtk_effect_density_box);
111 gtk_widget_hide(gtk_effect_base_height_box);
112 current_effect.reference = ec_create_ongoing_magic_protection(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation, 10, current_effect.scale);
113 break;
114 case 6: // Shield
115 gtk_widget_show(gtk_effect_hue_box);
116 gtk_widget_show(gtk_effect_saturation_box);
117 gtk_widget_show(gtk_effect_scale_box);
118 gtk_widget_hide(gtk_effect_density_box);
119 gtk_widget_hide(gtk_effect_base_height_box);
120 current_effect.reference = ec_create_ongoing_shield(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation, 10, current_effect.scale);
121 break;
122 case 7: // Magic Immunity
123 gtk_widget_show(gtk_effect_hue_box);
124 gtk_widget_show(gtk_effect_saturation_box);
125 gtk_widget_show(gtk_effect_scale_box);
126 gtk_widget_hide(gtk_effect_density_box);
127 gtk_widget_hide(gtk_effect_base_height_box);
128 current_effect.reference = ec_create_ongoing_magic_immunity(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation, 10, current_effect.scale);
129 break;
130 case 8: // Poison
131 gtk_widget_show(gtk_effect_hue_box);
132 gtk_widget_show(gtk_effect_saturation_box);
133 gtk_widget_show(gtk_effect_scale_box);
134 gtk_widget_hide(gtk_effect_density_box);
135 gtk_widget_hide(gtk_effect_base_height_box);
136 current_effect.reference = ec_create_ongoing_poison(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation, 10, current_effect.scale);
137 break;
138 case 9: // Smoke
139 gtk_widget_show(gtk_effect_hue_box);
140 gtk_widget_show(gtk_effect_saturation_box);
141 gtk_widget_hide(gtk_effect_scale_box);
142 gtk_widget_show(gtk_effect_density_box);
143 gtk_widget_hide(gtk_effect_base_height_box);
144 current_effect.reference = ec_create_smoke(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation, current_effect.scale, 10);
145 break;
146 case 10: // Teleporter
147 gtk_widget_show(gtk_effect_hue_box);
148 gtk_widget_show(gtk_effect_saturation_box);
149 gtk_widget_show(gtk_effect_scale_box);
150 gtk_widget_hide(gtk_effect_density_box);
151 gtk_widget_hide(gtk_effect_base_height_box);
152 current_effect.reference = ec_create_teleporter(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation, current_effect.scale, 10);
153 break;
154 case 11: // Leaves
155 gtk_widget_show(gtk_effect_hue_box);
156 gtk_widget_show(gtk_effect_saturation_box);
157 gtk_widget_show(gtk_effect_scale_box);
158 gtk_widget_show(gtk_effect_density_box);
159 gtk_widget_hide(gtk_effect_base_height_box);
160 // std::cout << "1: " << current_effect.hue << " / " << current_effect.saturation << " / " << current_effect.scale << " / " << current_effect.density << std::endl;
161 current_effect.reference = ec_create_wind_leaves(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation, current_effect.scale, current_effect.density, (current_effect.bounds.elements.size() > 1 ? ¤t_effect.bounds : &initial_bounds), 1.0, 0.0, 0.0);
162 break;
163 case 12: // Flower Petals
164 gtk_widget_show(gtk_effect_hue_box);
165 gtk_widget_show(gtk_effect_saturation_box);
166 gtk_widget_show(gtk_effect_scale_box);
167 gtk_widget_show(gtk_effect_density_box);
168 gtk_widget_hide(gtk_effect_base_height_box);
169 current_effect.reference = ec_create_wind_petals(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation, current_effect.scale, current_effect.density, (current_effect.bounds.elements.size() > 1 ? ¤t_effect.bounds : &initial_bounds), 1.0, 0.0, 0.0);
170 break;
171 case 13: // Waterfall
172 gtk_widget_show(gtk_effect_hue_box);
173 gtk_widget_show(gtk_effect_saturation_box);
174 gtk_widget_show(gtk_effect_scale_box);
175 gtk_widget_hide(gtk_effect_density_box);
176 gtk_widget_show(gtk_effect_base_height_box);
177 // current_effect.reference = ec_create_waterfall(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation);
178 break;
179 case 14: // Bees
180 gtk_widget_show(gtk_effect_hue_box);
181 gtk_widget_show(gtk_effect_saturation_box);
182 gtk_widget_show(gtk_effect_scale_box);
183 gtk_widget_show(gtk_effect_density_box);
184 gtk_widget_hide(gtk_effect_base_height_box);
185 current_effect.reference = NULL;
186 // current_effect.reference = ec_create_bees(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation);
187 break;
188 case 15: // Portal
189 gtk_widget_show(gtk_effect_hue_box);
190 gtk_widget_show(gtk_effect_saturation_box);
191 gtk_widget_show(gtk_effect_scale_box);
192 gtk_widget_hide(gtk_effect_density_box);
193 gtk_widget_hide(gtk_effect_base_height_box);
194 current_effect.reference = NULL;
195 // current_effect.reference = ec_create_bees(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation);
196 break;
197 case 16: // Candle
198 gtk_widget_show(gtk_effect_hue_box);
199 gtk_widget_show(gtk_effect_saturation_box);
200 gtk_widget_show(gtk_effect_scale_box);
201 gtk_widget_hide(gtk_effect_density_box);
202 gtk_widget_hide(gtk_effect_base_height_box);
203 current_effect.reference = ec_create_candle(current_effect.position.x, current_effect.position.y, current_effect.position.z, current_effect.hue, current_effect.saturation, current_effect.scale, 10);
204 break;
205 }
206 }
207
remove_current_eye_candy_effect()208 extern "C" void remove_current_eye_candy_effect()
209 {
210 if (current_effect.reference)
211 {
212 ec_recall_effect(current_effect.reference);
213 current_effect.reference = NULL;
214 }
215 }
216
confirm_eye_candy_effect()217 void confirm_eye_candy_effect()
218 {
219 eye_candy_confirmed = 1;
220 change_eye_candy_effect();
221 gtk_widget_hide(gtk_effect_win);
222 switch (current_effect.effect)
223 {
224 case 1: // Cloud/Fog
225 case 2: // Fireflies
226 case 11: // Leaves
227 case 12: // Flower Petals
228 {
229 current_effect.position = ec::Vec3(-1.0, -1.0, 0.0);
230 minimap_on = 1;
231 break;
232 }
233 }
234 eye_candy_ready_to_add = 1;
235 }
236
display_eye_candy_window_handler()237 extern "C" int display_eye_candy_window_handler()
238 {
239 return 1;
240 }
241
check_eye_candy_window_interface()242 extern "C" int check_eye_candy_window_interface()
243 {
244 return 1;
245 }
246
update_eye_candy_position(float x,float y)247 extern "C" void update_eye_candy_position(float x, float y)
248 {
249 if (!minimap_on)
250 {
251 switch (current_effect.effect)
252 {
253 case 1: // Cloud/Fog
254 case 2: // Fireflies
255 case 11: // Leaves
256 case 12: // Flower Petals
257 {
258 if (current_effect.bounds.elements.size() > 1)
259 return;
260 }
261 }
262 current_effect.position.x = x;
263 current_effect.position.y = y;
264 if (current_effect.reference)
265 ec_set_position(current_effect.reference, x, y, current_effect.position.z);
266 }
267 }
268
add_eye_candy_point()269 extern "C" void add_eye_candy_point()
270 {
271 int x0, y0, y1, width, height;
272 get_minimap_dimensions(&x0, &y0, &width, &height);
273 y1 = y0 + height;
274
275 if (mouse_x < x0 || mouse_y < y0 || mouse_x > x0 + width || mouse_y > y1) return;
276
277 float x = float(mouse_x - x0) * 3 * tile_map_size_x / width;
278 float y = float(y1 - mouse_y) * 3 * tile_map_size_y / height;
279 int x_tile = int(x) / 3;
280 int y_tile = int(y) / 3;
281 const float z = -2.2f + tile_map[y_tile*tile_map_size_x + x_tile] * 0.2f;
282
283 if (left_click <= 1)
284 {
285 const bool ret = find_bounds_index(x, y);
286 if (!ret) // Didn't click on anything; create new.
287 {
288 if ((current_effect.bounds.elements.size() == 0) && (current_effect.position == ec::Vec3(-1.0, -1.0, 0.0)))
289 current_effect.position = ec::Vec3(x, y, z);
290 else if (current_effect.bounds.elements.size() < 13)
291 current_effect.bounds.elements.insert(current_effect.bounds.elements.begin() + last_ec_index, angle_to(current_effect.position.x, current_effect.position.y, x, y));
292 else
293 ; // Can't add any more; too many already.
294 }
295 }
296 else
297 {
298 if (last_ec_index == -1) // Clicked on the center; drag it.
299 current_effect.position = ec::Vec3(x, y, z);
300 else if (last_ec_index >= 0) // Clicked on another point; drag it.
301 {
302 const ec::SmoothPolygonElement new_angle = angle_to(current_effect.position.x, current_effect.position.y, x, y);
303 current_effect.bounds.elements.erase(current_effect.bounds.elements.begin() + last_ec_index);
304 int i;
305 for (i = 0; i < (int)current_effect.bounds.elements.size(); i++)
306 {
307 if (new_angle.angle < current_effect.bounds.elements[i].angle)
308 break;
309 }
310 current_effect.bounds.elements.insert(current_effect.bounds.elements.begin() + i, new_angle);
311 last_ec_index = i;
312 }
313 }
314 change_eye_candy_effect();
315 }
316
delete_eye_candy_point()317 extern "C" void delete_eye_candy_point()
318 {
319 int x0, y0, y1, width, height;
320 get_minimap_dimensions(&x0, &y0, &width, &height);
321 y1 = y0 + height;
322
323 if (mouse_x < x0 || mouse_y < y0 || mouse_x > x0 + width || mouse_y > y1) return;
324
325 float x = float(mouse_x - x0) * 3 * tile_map_size_x / width;
326 float y = float(y1 - mouse_y) * 3 * tile_map_size_y / height;
327
328 if (find_bounds_index(x, y))
329 {
330 if (last_ec_index >= 0) // Clicked on a bounds point; delete it
331 {
332 current_effect.bounds.elements.erase(current_effect.bounds.elements.begin() + last_ec_index);
333 }
334 else if (last_ec_index == -1) // Clicked on the center; cancel the effect
335 {
336 current_effect = EffectDefinition();
337 eye_candy_done_adding_effect();
338 cur_mode = mode_tile;
339 minimap_on = 0;
340 }
341 }
342 }
343
eye_candy_add_effect()344 extern "C" void eye_candy_add_effect()
345 {
346 if (eye_candy_initialized && eye_candy_ready_to_add)
347 {
348 effects.push_back(current_effect);
349 current_effect.reference = NULL;
350 switch (current_effect.effect)
351 {
352 case 1: // Cloud/Fog
353 case 2: // Fireflies
354 case 11: // Leaves
355 case 12: // Flower Petals
356 {
357 current_effect.effect = 0;
358 cur_mode = mode_tile;
359 return;
360 }
361 default:
362 {
363 change_eye_candy_effect();
364 current_effect.bounds = ec::SmoothPolygonBoundingRange();
365 }
366 }
367 }
368 }
369
eye_candy_done_adding_effect()370 extern "C" void eye_candy_done_adding_effect()
371 {
372 if (eye_candy_initialized)
373 {
374 eye_candy_ready_to_add = 0;
375 if (current_effect.reference)
376 {
377 switch (current_effect.effect)
378 {
379 case 1: // Cloud/Fog
380 case 2: // Fireflies
381 case 11: // Leaves
382 case 12: // Flower Petals
383 {
384 effects.push_back(current_effect);
385 break;
386 }
387 default:
388 {
389 remove_current_eye_candy_effect();
390 }
391 }
392 current_effect.reference = NULL;
393 current_effect.bounds = ec::SmoothPolygonBoundingRange();
394 current_effect.position = ec::Vec3(-1.0, -1.0, 0.0);
395 }
396 }
397 }
398
eye_candy_get_effect()399 extern "C" int eye_candy_get_effect()
400 {
401 return current_effect.effect;
402 }
403
eye_candy_adjust_z(float offset)404 void eye_candy_adjust_z(float offset)
405 {
406 current_effect.position.z += offset;
407 change_eye_candy_effect();
408 }
409
draw_bounds_on_minimap()410 extern "C" void draw_bounds_on_minimap()
411 {
412 glDisable(GL_TEXTURE_2D);
413 glEnable(GL_BLEND);
414 for (std::vector<EffectDefinition>::iterator iter = effects.begin(); iter != effects.end(); iter++)
415 draw_bound(*iter, false);
416 if (eye_candy_ready_to_add)
417 draw_bound(current_effect, true);
418 glDisable(GL_BLEND);
419 glEnable(GL_TEXTURE_2D);
420 }
421
draw_bound(EffectDefinition & eff,bool selected)422 void draw_bound(EffectDefinition& eff, bool selected)
423 {
424 int x0, y0, y1, width, height, tile_size;
425 get_minimap_dimensions(&x0, &y0, &width, &height);
426 y1 = y0 + height;
427 tile_size = width / tile_map_size_x;
428
429 int scale = min2i(window_width, window_height) / 256;
430 glLineWidth(1.3 * scale);
431
432 if (selected)
433 glColor4f(0.65, 0.55, 0.45, 0.7);
434 else
435 glColor4f(0.65, 0.55, 0.45, 0.25);
436
437 glBegin(GL_LINE_LOOP);
438 if (eff.bounds.elements.size() >= 2)
439 {
440 std::vector<ec::SmoothPolygonElement>::const_iterator prev_iter = eff.bounds.elements.begin() + (eff.bounds.elements.size() - 1);
441 std::vector<ec::SmoothPolygonElement>::const_iterator next_iter = eff.bounds.elements.begin();
442 bool wrapped = false;
443 for (float f = 0; f < 2 * ec::PI; f += (2 * ec::PI) / 360.0)
444 {
445 if ((f > next_iter->angle) && (!wrapped))
446 {
447 prev_iter = next_iter;
448 next_iter++;
449 if (next_iter == eff.bounds.elements.end())
450 {
451 wrapped = true;
452 next_iter = eff.bounds.elements.begin();
453 }
454 }
455 float percent;
456 if (wrapped)
457 percent = (f - prev_iter->angle) / (next_iter->angle + (2 * ec::PI) - prev_iter->angle);
458 else if (f > prev_iter->angle)
459 percent = (f - prev_iter->angle) / (next_iter->angle - prev_iter->angle);
460 else
461 percent = (f + 2 * ec::PI - prev_iter->angle) / (next_iter->angle + (2 * ec::PI) - prev_iter->angle);
462 const float dist = prev_iter->radius * (1.0 - percent) + next_iter->radius * percent;
463 const float temp_x = x0 + ((eff.position.x - dist * sin(f)) * tile_size) / 3;
464 const float temp_y = y1 - ((eff.position.y + dist * cos(f)) * tile_size) / 3;
465 glVertex2f(temp_x, temp_y);
466 }
467 }
468 glEnd();
469
470 if (selected)
471 {
472 glColor4f(1.0, 1.0, 1.0, 0.7);
473 glBegin(GL_QUADS);
474 for (std::vector<ec::SmoothPolygonElement>::const_iterator iter = eff.bounds.elements.begin(); iter != eff.bounds.elements.end(); iter++)
475 {
476 const float temp_x = x0 + ((eff.position.x - iter->radius * sin(iter->angle)) * tile_size) / 3;
477 const float temp_y = y1 - ((eff.position.y + iter->radius * cos(iter->angle)) * tile_size) / 3;
478 glVertex2f(temp_x - 2.0 * scale, temp_y - 2.0 * scale);
479 glVertex2f(temp_x - 2.0 * scale, temp_y + 2.0 * scale);
480 glVertex2f(temp_x + 2.0 * scale, temp_y + 2.0 * scale);
481 glVertex2f(temp_x + 2.0 * scale, temp_y - 2.0 * scale);
482 }
483
484 glColor4f(1.0, 0.8, 0.6, 1.0);
485 const float temp_x = x0 + (eff.position.x * tile_size) / 3;
486 const float temp_y = y1 - (eff.position.y * tile_size) / 3;
487 glVertex2f(temp_x - 2.0 * scale, temp_y - 2.0 * scale);
488 glVertex2f(temp_x - 2.0 * scale, temp_y + 2.0 * scale);
489 glVertex2f(temp_x + 2.0 * scale, temp_y + 2.0 * scale);
490 glVertex2f(temp_x + 2.0 * scale, temp_y - 2.0 * scale);
491 glEnd();
492 }
493 }
494
find_bounds_index(float x,float y)495 bool find_bounds_index(float x, float y)
496 {
497 if ((current_effect.position.x == -1.0) && (current_effect.position.y == -1.0))
498 {
499 last_ec_index = -1;
500 return false;
501 }
502
503 if ((fabs(x - current_effect.position.x) < 9.0) && (fabs(y - current_effect.position.y) < 9.0))
504 {
505 last_ec_index = -1;
506 return true;
507 }
508
509 for (int i = 0; i < (int)current_effect.bounds.elements.size(); i++)
510 {
511 std::vector<ec::SmoothPolygonElement>::const_iterator iter = current_effect.bounds.elements.begin() + i;
512 const float temp_x = current_effect.position.x - iter->radius * sin(iter->angle);
513 const float temp_y = current_effect.position.y + iter->radius * cos(iter->angle);
514 if ((fabs(x - temp_x) < 9.0) && (fabs(y - temp_y) < 9.0))
515 {
516 last_ec_index = i;
517 return true;
518 }
519 }
520
521 float cur_angle = angle_to(current_effect.position.x, current_effect.position.y, x, y).angle;
522 last_ec_index = current_effect.bounds.elements.size();
523 for (int i = 0; i < (int)current_effect.bounds.elements.size(); i++)
524 {
525 const float angle = current_effect.bounds.elements[i].angle;
526 if (cur_angle < angle)
527 {
528 last_ec_index = i;
529 break;
530 }
531 }
532
533 return false;
534 }
535
angle_to(float start_x,float start_y,float end_x,float end_y)536 ec::SmoothPolygonElement angle_to(float start_x, float start_y, float end_x, float end_y)
537 {
538 const float diff_x = -(end_x - start_x);
539 const float diff_y = end_y - start_y;
540 float angle = atan2(diff_x, diff_y);
541 if (angle < 0)
542 angle += 2.0 * ec::PI;
543 const float dist = sqrt(diff_x * diff_x + diff_y * diff_y);
544 return ec::SmoothPolygonElement(angle, dist);
545 }
546
draw_eye_candy_obj_info()547 void draw_eye_candy_obj_info()
548 {
549 unsigned char str[128];
550 int x_menu,y_menu;
551 if (cur_mode!=mode_eye_candy || !eye_candy_confirmed)
552 return;
553
554 x_menu=0;
555 y_menu=window_height-72;
556 //draw a black rectangle
557 glEnable(GL_BLEND);
558 glBlendFunc(GL_ONE,GL_SRC_ALPHA);
559 glDisable(GL_TEXTURE_2D);
560 glBegin(GL_QUADS);
561 glColor4f(0.0f,0.0f,0.0f,0.5f);
562 glVertex3i(x_menu,y_menu+70,0);
563 glVertex3i(x_menu,y_menu,0);
564 glVertex3i(x_menu+600,y_menu,0);
565 glVertex3i(x_menu+600,y_menu+70,0);
566 glColor3f(1.0f,1.0f,1.0f);
567 glEnd();
568 glEnable(GL_TEXTURE_2D);
569 glDisable(GL_BLEND);
570
571 x_menu+=2;
572 y_menu+=2;
573
574 sprintf((char *)str, "X Pos: %03.2f",current_effect.position.x);
575 draw_string(x_menu,y_menu,str,1);
576
577 y_menu+=17;
578 sprintf((char *)str, "Y Pos: %03.2f",current_effect.position.y);
579 draw_string(x_menu,y_menu,str,1);
580
581 y_menu+=17;
582 sprintf((char *)str, "Z Pos: %03.2f",current_effect.position.z);
583 draw_string(x_menu,y_menu,str,1);
584 /////////////////////////////////////////////////
585 x_menu+=15*12;
586 y_menu-=17*2;
587
588 sprintf((char *)str, "Angle : %03.2f",current_effect.angle);
589 draw_string(x_menu,y_menu,str,1);
590
591 y_menu+=17;
592 sprintf((char *)str, "Density : %03.2f",current_effect.density);
593 draw_string(x_menu,y_menu,str,1);
594
595 y_menu+=17;
596 sprintf((char *)str, "Scale : %03.2f",current_effect.scale);
597 draw_string(x_menu,y_menu,str,1);
598 /////////////////////////////////////////////////
599 x_menu+=17*12;
600 y_menu-=17*2;
601
602 sprintf((char *)str, "Hue : %03.2f",current_effect.hue);
603 draw_string(x_menu,y_menu,str,1);
604
605 y_menu+=17;
606 sprintf((char *)str, "Saturation: %03.2f",current_effect.saturation);
607 draw_string(x_menu,y_menu,str,1);
608
609 y_menu+=17;
610 sprintf((char *)str, "Height : %03.2f",current_effect.base_height);
611 draw_string(x_menu,y_menu,str,1);
612 }
613
draw_eye_candy_selectors()614 void draw_eye_candy_selectors()
615 {
616 glEnable(GL_COLOR);
617 glEnable(GL_LIGHTING);
618 glDisable(GL_TEXTURE_2D);
619 glColor4f(0.5, 0.5, 0.5, 1.0);
620 int i=0;
621 if (eye_candy_ready_to_add)
622 draw_eye_candy_selector(¤t_effect, i);
623 i++;
624 for (std::vector<EffectDefinition>::const_iterator iter = effects.begin(); iter != effects.end(); iter++, i++)
625 draw_eye_candy_selector(&(*iter), i);
626 glDisable(GL_COLOR);
627 glDisable(GL_LIGHTING);
628 glEnable(GL_TEXTURE_2D);
629 }
630
draw_eye_candy_selector(const EffectDefinition * const effect,const int i)631 void draw_eye_candy_selector(const EffectDefinition*const effect, const int i)
632 {
633 glPushMatrix();
634 glTranslatef(effect->position.x, effect->position.y, effect->position.z);
635 glLoadName (MAX_OBJ_3D + i);
636 glBegin(GL_QUADS);
637 {
638 // Front Face
639 glNormal3f(0.0, 0.0, 1.0);
640 glVertex3f(-0.15f, -0.15f, 0.15f);
641 glVertex3f( 0.15f, -0.15f, 0.15f);
642 glVertex3f( 0.15f, 0.15f, 0.15f);
643 glVertex3f(-0.15f, 0.15f, 0.15f);
644 // Back Face
645 glNormal3f(0.0, 0.0, -1.0);
646 glVertex3f(-0.15f, -0.15f, -0.15f);
647 glVertex3f(-0.15f, 0.15f, -0.15f);
648 glVertex3f( 0.15f, 0.15f, -0.15f);
649 glVertex3f( 0.15f, -0.15f, -0.15f);
650 // Top Face
651 glNormal3f(0.0, 1.0, 0.0);
652 glVertex3f(-0.15f, 0.15f, -0.15f);
653 glVertex3f(-0.15f, 0.15f, 0.15f);
654 glVertex3f( 0.15f, 0.15f, 0.15f);
655 glVertex3f( 0.15f, 0.15f, -0.15f);
656 // Bottom Face
657 glNormal3f(0.0, -1.0, 0.0);
658 glVertex3f(-0.15f, -0.15f, -0.15f);
659 glVertex3f( 0.15f, -0.15f, -0.15f);
660 glVertex3f( 0.15f, -0.15f, 0.15f);
661 glVertex3f(-0.15f, -0.15f, 0.15f);
662 // Right face
663 glNormal3f(1.0, 0.0, 0.0);
664 glVertex3f( 0.15f, -0.15f, -0.15f);
665 glVertex3f( 0.15f, 0.15f, -0.15f);
666 glVertex3f( 0.15f, 0.15f, 0.15f);
667 glVertex3f( 0.15f, -0.15f, 0.15f);
668 // Left Face
669 glNormal3f(-1.0, 0.0, 0.0);
670 glVertex3f(-0.15f, -0.15f, -0.15f);
671 glVertex3f(-0.15f, -0.15f, 0.15f);
672 glVertex3f(-0.15f, 0.15f, 0.15f);
673 glVertex3f(-0.15f, 0.15f, -0.15f);
674 }
675 glEnd();
676 glPopMatrix();
677 }
678
select_eye_candy_effect(int i)679 void select_eye_candy_effect(int i)
680 {
681 if (i == MAX_OBJ_3D) // The current selection
682 return;
683
684 std::vector<EffectDefinition>::iterator iter = effects.begin() + (i - MAX_OBJ_3D - 1);
685 if (current_effect.reference)
686 {
687 ec_recall_effect(current_effect.reference);
688 current_effect.reference = NULL;
689 }
690 current_effect = *iter;
691 effects.erase(iter);
692 eye_candy_ready_to_add = 1;
693 }
694
kill_eye_candy_effect()695 void kill_eye_candy_effect()
696 {
697 if (current_effect.reference)
698 {
699 ec_recall_effect(current_effect.reference);
700 current_effect.reference = NULL;
701 }
702 eye_candy_ready_to_add = 0;
703 }
704
get_eye_candy_count()705 int get_eye_candy_count()
706 {
707 return effects.size();
708 }
709
deserialize_eye_candy_effect(particles_io * data)710 void deserialize_eye_candy_effect(particles_io* data)
711 {
712 const unsigned char*const code = (const unsigned char*const)data->file_name + 5;
713
714 // std::cout << "Deserialize" << std::endl;
715
716 EffectDefinition dest;
717
718 unsigned char raw_code[54];
719 int i = 0;
720
721 while (i < 18)
722 {
723 raw_code[i * 3] = ((code[i * 4 + 0] - ' ') >> 0) | ((code[i * 4 + 1] - ' ') << 6);
724 raw_code[i * 3 + 1] = ((code[i * 4 + 1] - ' ') >> 2) | ((code[i * 4 + 2] - ' ') << 4);
725 raw_code[i * 3 + 2] = ((code[i * 4 + 2] - ' ') >> 4) | ((code[i * 4 + 3] - ' ') << 2);
726 i++;
727 }
728
729 int bounds_count = raw_code[1];
730 if (bounds_count > 19)
731 bounds_count = 19;
732 for (i = 0; i < bounds_count; i++)
733 {
734 const float angle = raw_code[i * 2 + 2] * (2 * ec::PI) / 256.0f;
735 const float dist = raw_code[i * 2 + 3];
736 dest.bounds.elements.push_back(ec::SmoothPolygonElement(angle, dist));
737 }
738
739 dest.position.x = data->x_pos;
740 dest.position.y = data->y_pos;
741 dest.position.z = data->z_pos;
742
743 switch (raw_code[0])
744 {
745 case 0x00: // Campfire
746 {
747 const float hue = raw_code[41] / 256.0;
748 const float saturation = raw_code[42] / 16.0;
749 const float scale = raw_code[43] + raw_code[44] / 256.0;
750 dest.effect = 0x00;
751 dest.hue = hue;
752 dest.saturation = saturation;
753 dest.scale = scale;
754 dest.reference = ec_create_campfire(dest.position.x, dest.position.y, dest.position.z, hue, saturation, 10, scale);
755 break;
756 }
757 case 0x01: // Cloud
758 {
759 const float hue = raw_code[41] / 256.0;
760 const float saturation = raw_code[42] / 16.0;
761 const float density = raw_code[43] + raw_code[44] / 256.0;
762 dest.effect = 0x01;
763 dest.hue = hue;
764 dest.saturation = saturation;
765 dest.density = density;
766 dest.reference = ec_create_cloud(dest.position.x, dest.position.y, dest.position.z, hue, saturation, density, (ec_bounds)(&dest.bounds), 10);
767 break;
768 }
769 case 0x02: // Fireflies
770 {
771 const float hue = raw_code[41] / 256.0;
772 const float saturation = raw_code[42] / 16.0;
773 const float density = raw_code[43] + raw_code[44] / 256.0;
774 const float scale = raw_code[45] + raw_code[46] / 256.0;
775 dest.effect = 0x02;
776 dest.hue = hue;
777 dest.saturation = saturation;
778 dest.scale = scale;
779 dest.density = density;
780 dest.reference = ec_create_fireflies(dest.position.x, dest.position.y, dest.position.z, hue, saturation, density, scale, (ec_bounds)(&dest.bounds));
781 break;
782 }
783 case 0x03: // Fountain
784 {
785 const float hue = raw_code[41] / 256.0;
786 const float saturation = raw_code[42] / 16.0;
787 const float scale = raw_code[43] + raw_code[44] / 256.0;
788 const float base_height = raw_code[45] * 8.0 + raw_code[46] / 32.0;
789 const int backlit = raw_code[47];
790 dest.effect = 0x03;
791 dest.hue = hue;
792 dest.saturation = saturation;
793 dest.scale = scale;
794 dest.base_height = base_height;
795 dest.reference = ec_create_fountain(dest.position.x, dest.position.y, dest.position.z, hue, saturation, base_height, backlit, scale, 10);
796 break;
797 }
798 case 0x04: // Lamp
799 {
800 const float hue = raw_code[41] / 256.0;
801 const float saturation = raw_code[42] / 16.0;
802 const float scale = raw_code[43] + raw_code[44] / 256.0;
803 dest.effect = 0x04;
804 dest.hue = hue;
805 dest.saturation = saturation;
806 dest.scale = scale;
807 dest.reference = ec_create_lamp(dest.position.x, dest.position.y, dest.position.z, hue, saturation, scale, 10);
808 break;
809 }
810 case 0x05: // Magic protection
811 {
812 const float hue = raw_code[41] / 256.0;
813 const float saturation = raw_code[42] / 16.0;
814 const float scale = raw_code[43] + raw_code[44] / 256.0;
815 dest.effect = 0x05;
816 dest.hue = hue;
817 dest.saturation = saturation;
818 dest.scale = scale;
819 dest.reference = ec_create_ongoing_magic_protection(dest.position.x, dest.position.y, dest.position.z, hue, saturation, 10, scale);
820 break;
821 }
822 case 0x06: // Shield
823 {
824 const float hue = raw_code[41] / 256.0;
825 const float saturation = raw_code[42] / 16.0;
826 const float scale = raw_code[43] + raw_code[44] / 256.0;
827 dest.effect = 0x06;
828 dest.hue = hue;
829 dest.saturation = saturation;
830 dest.scale = scale;
831 dest.reference = ec_create_ongoing_shield(dest.position.x, dest.position.y, dest.position.z, hue, saturation, 10, scale);
832 break;
833 }
834 case 0x07: // Magic immunity
835 {
836 const float hue = raw_code[41] / 256.0;
837 const float saturation = raw_code[42] / 16.0;
838 const float scale = raw_code[43] + raw_code[44] / 256.0;
839 dest.effect = 0x07;
840 dest.hue = hue;
841 dest.saturation = saturation;
842 dest.scale = scale;
843 dest.reference = ec_create_ongoing_magic_immunity(dest.position.x, dest.position.y, dest.position.z, hue, saturation, 10, scale);
844 break;
845 }
846 case 0x08: // Poison
847 {
848 const float hue = raw_code[41] / 256.0;
849 const float saturation = raw_code[42] / 16.0;
850 const float scale = raw_code[43] + raw_code[44] / 256.0;
851 dest.effect = 0x08;
852 dest.hue = hue;
853 dest.saturation = saturation;
854 dest.scale = scale;
855 dest.reference = ec_create_ongoing_poison(dest.position.x, dest.position.y, dest.position.z, hue, saturation, 10, scale);
856 break;
857 }
858 case 0x09: // Smoke
859 {
860 const float hue = raw_code[41] / 256.0;
861 const float saturation = raw_code[42] / 16.0;
862 const float density = raw_code[43] + raw_code[44] / 256.0;
863 dest.effect = 0x09;
864 dest.hue = hue;
865 dest.saturation = saturation;
866 dest.density = density;
867 dest.reference = ec_create_smoke(dest.position.x, dest.position.y, dest.position.z, hue, saturation, density, 10);
868 break;
869 }
870 case 0x0A: // Teleporter
871 {
872 const float hue = raw_code[41] / 256.0;
873 const float saturation = raw_code[42] / 16.0;
874 const float scale = raw_code[43] + raw_code[44] / 256.0;
875 dest.effect = 0x0A;
876 dest.hue = hue;
877 dest.saturation = saturation;
878 dest.scale = scale;
879 dest.reference = ec_create_teleporter(dest.position.x, dest.position.y, dest.position.z, hue, saturation, scale, 10);
880 break;
881 }
882 case 0x0B: // Leaves
883 {
884 const float hue = raw_code[41] / 256.0;
885 const float saturation = raw_code[42] / 16.0;
886 const float density = raw_code[43] + raw_code[44] / 256.0;
887 const float scale = raw_code[45] + raw_code[46] / 256.0;
888 dest.effect = 0x0B;
889 dest.hue = hue;
890 dest.saturation = saturation;
891 dest.scale = scale;
892 dest.density = density;
893 dest.reference = ec_create_wind_leaves(dest.position.x, dest.position.y, dest.position.z, hue, saturation, scale, density, (ec_bounds)(&dest.bounds), 1.0, 0.0, 0.0);
894 break;
895 }
896 case 0x0C: // Petals
897 {
898 const float hue = raw_code[41] / 256.0;
899 const float saturation = raw_code[42] / 16.0;
900 const float density = raw_code[43] + raw_code[44] / 256.0;
901 const float scale = raw_code[45] + raw_code[46] / 256.0;
902 dest.effect = 0x0C;
903 dest.hue = hue;
904 dest.saturation = saturation;
905 dest.scale = scale;
906 dest.density = density;
907 dest.reference = ec_create_wind_petals(dest.position.x, dest.position.y, dest.position.z, hue, saturation, scale, density, (ec_bounds)(&dest.bounds), 1.0, 0.0, 0.0);
908 break;
909 }
910 case 0x0D: // Waterfall
911 {
912 const float hue = raw_code[41] / 256.0;
913 const float saturation = raw_code[42] / 16.0;
914 const float density = raw_code[43] + raw_code[44] / 256.0;
915 const float base_height = raw_code[45] * 8.0 + raw_code[46] / 32.0;
916 const float angle = raw_code[47] * ec::PI / 128.0;
917 dest.effect = 0x0D;
918 dest.hue = hue;
919 dest.saturation = saturation;
920 dest.density = density;
921 dest.base_height = base_height;
922 dest.angle = angle;
923 // dest.reference = ec_create_waterfall(dest.position.x, dest.position.y, dest.position.z, hue, saturation);
924 break;
925 }
926 case 0x0E: // Bees
927 {
928 const float hue = raw_code[41] / 256.0;
929 const float saturation = raw_code[42] / 16.0;
930 const float density = raw_code[43] + raw_code[44] / 256.0;
931 const float scale = raw_code[45] + raw_code[46] / 256.0;
932 dest.effect = 0x0E;
933 dest.hue = hue;
934 dest.saturation = saturation;
935 dest.scale = scale;
936 dest.density = density;
937 // dest.reference = ec_create_bees(dest.position.x, dest.position.y, dest.position.z, hue, saturation);
938 break;
939 }
940 case 0x0F: // Portal
941 {
942 const float hue = raw_code[41] / 256.0;
943 const float saturation = raw_code[42] / 16.0;
944 const float scale = raw_code[43] + raw_code[44] / 256.0;
945 const float angle = raw_code[45] * ec::PI / 128.0;
946 dest.effect = 0x0F;
947 dest.hue = hue;
948 dest.saturation = saturation;
949 dest.scale = scale;
950 dest.angle = angle;
951 // dest.reference = ec_create_portal(dest.position.x, dest.position.y, dest.position.z, hue, saturation);
952 break;
953 }
954 case 0x10: // Candle
955 {
956 const float hue = raw_code[41] / 256.0;
957 const float saturation = raw_code[42] / 16.0;
958 const float scale = raw_code[43] + raw_code[44] / 256.0;
959 dest.effect = 0x10;
960 dest.hue = hue;
961 dest.saturation = saturation;
962 dest.scale = scale;
963 dest.reference = ec_create_candle(dest.position.x, dest.position.y, dest.position.z, hue, saturation, scale, 10);
964 break;
965 }
966 }
967 effects.push_back(dest);
968 }
969
serialize_eye_candy_effect(int index,particles_io * data)970 void serialize_eye_candy_effect(int index, particles_io* data)
971 {
972 // std::cout << "Serialize" << std::endl;
973
974 memset((char*)data, 0, sizeof(particles_io));
975
976 std::string unformatted_data(80, '\0');
977 unformatted_data[0] = effects[index].effect;
978 unformatted_data[1] = effects[index].bounds.elements.size();
979 if (unformatted_data[1] > 19)
980 unformatted_data[1] = 19;
981 for (int i = 0; i < unformatted_data[1]; i++)
982 {
983 unformatted_data[i * 2 + 2] = (char)((unsigned char)(effects[index].bounds.elements[i].angle / (2 * ec::PI) * 256.0f));
984 unformatted_data[i * 2 + 3] = (char)((unsigned char)(effects[index].bounds.elements[i].radius));
985 }
986 switch (effects[index].effect)
987 {
988 case 0: // Fire
989 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
990 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
991 unformatted_data[43] = (char)((unsigned char)(effects[index].scale));
992 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].scale * 256.0) % 256));
993 break;
994 case 1: // Cloud/Fog
995 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
996 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
997 unformatted_data[43] = (char)((unsigned char)(effects[index].density));
998 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].density * 256.0) % 256));
999 break;
1000 case 2: // Fireflies
1001 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
1002 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
1003 unformatted_data[43] = (char)((unsigned char)(effects[index].density));
1004 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].density * 256.0) % 256));
1005 unformatted_data[45] = (char)((unsigned char)(effects[index].scale));
1006 unformatted_data[46] = (char)((unsigned char)((int)(effects[index].scale * 256.0) % 256));
1007 break;
1008 case 3: // Fountain
1009 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
1010 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
1011 unformatted_data[43] = (char)((unsigned char)(effects[index].scale));
1012 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].scale * 256.0) % 256));
1013 unformatted_data[47] = 0; // Backlit
1014 break;
1015 case 4: // Lamp/Torch
1016 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
1017 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
1018 unformatted_data[43] = (char)((unsigned char)(effects[index].scale));
1019 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].scale * 256.0) % 256));
1020 break;
1021 case 5: // Magic Protection
1022 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
1023 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
1024 unformatted_data[43] = (char)((unsigned char)(effects[index].scale));
1025 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].scale * 256.0) % 256));
1026 break;
1027 case 6: // Shield
1028 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
1029 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
1030 unformatted_data[43] = (char)((unsigned char)(effects[index].scale));
1031 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].scale * 256.0) % 256));
1032 break;
1033 case 7: // Magic Immunity
1034 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
1035 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
1036 unformatted_data[43] = (char)((unsigned char)(effects[index].scale));
1037 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].scale * 256.0) % 256));
1038 break;
1039 case 8: // Poison
1040 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
1041 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
1042 unformatted_data[43] = (char)((unsigned char)(effects[index].scale));
1043 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].scale * 256.0) % 256));
1044 break;
1045 case 9: // Smoke
1046 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
1047 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
1048 unformatted_data[43] = (char)((unsigned char)(effects[index].density));
1049 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].density * 256.0) % 256));
1050 break;
1051 case 10: // Teleporter
1052 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
1053 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
1054 unformatted_data[43] = (char)((unsigned char)(effects[index].scale));
1055 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].scale * 256.0) % 256));
1056 break;
1057 case 11: // Leaves
1058 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
1059 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
1060 unformatted_data[43] = (char)((unsigned char)(effects[index].density));
1061 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].density * 256.0) % 256));
1062 unformatted_data[45] = (char)((unsigned char)(effects[index].scale));
1063 unformatted_data[46] = (char)((unsigned char)((int)(effects[index].scale * 256.0) % 256));
1064 break;
1065 case 12: // Flower Petals
1066 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
1067 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
1068 unformatted_data[43] = (char)((unsigned char)(effects[index].density));
1069 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].density * 256.0) % 256));
1070 unformatted_data[45] = (char)((unsigned char)(effects[index].scale));
1071 unformatted_data[46] = (char)((unsigned char)((int)(effects[index].scale * 256.0) % 256));
1072 break;
1073 case 13: // Waterfall
1074 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
1075 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
1076 unformatted_data[43] = (char)((unsigned char)(effects[index].density));
1077 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].density * 256.0) % 256));
1078 unformatted_data[45] = (char)((unsigned char)(effects[index].base_height / 8.0));
1079 unformatted_data[46] = (char)((unsigned char)((int)(effects[index].base_height * 32.0) % 256));
1080 unformatted_data[47] = (char)((unsigned char)(effects[index].angle * 256.0));
1081 break;
1082 case 14: // Bees
1083 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
1084 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
1085 unformatted_data[43] = (char)((unsigned char)(effects[index].density));
1086 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].density * 256.0) % 256));
1087 unformatted_data[45] = (char)((unsigned char)(effects[index].scale));
1088 unformatted_data[46] = (char)((unsigned char)((int)(effects[index].scale * 256.0) % 256));
1089 break;
1090 case 15: // Portal
1091 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
1092 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
1093 unformatted_data[43] = (char)((unsigned char)(effects[index].scale));
1094 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].scale * 256.0) % 256));
1095 unformatted_data[45] = (char)((unsigned char)(effects[index].angle * 256.0));
1096 break;
1097 case 16: // Candle
1098 unformatted_data[41] = (char)((unsigned char)(effects[index].hue * 256.0));
1099 unformatted_data[42] = (char)((unsigned char)(effects[index].saturation * 16.0));
1100 unformatted_data[43] = (char)((unsigned char)(effects[index].scale));
1101 unformatted_data[44] = (char)((unsigned char)((int)(effects[index].scale * 256.0) % 256));
1102 break;
1103 }
1104
1105 std::string data_str = "ec://";
1106 for (int i = 0; i < 18; i++)
1107 {
1108 data_str += ' ' + (char)((((unsigned char)unformatted_data[i * 3 + 0] & 0x3F)));
1109 data_str += ' ' + (char)((((unsigned char)unformatted_data[i * 3 + 0] & 0xC0) >> 6) | (((unsigned char)unformatted_data[i * 3 + 1] & 0x0F) << 2));
1110 data_str += ' ' + (char)((((unsigned char)unformatted_data[i * 3 + 1] & 0xF0) >> 4) | (((unsigned char)unformatted_data[i * 3 + 2] & 0x03) << 4));
1111 data_str += ' ' + (char)((((unsigned char)unformatted_data[i * 3 + 2] & 0xFC) >> 2));
1112 }
1113
1114 sprintf(data->file_name, "%s", data_str.c_str());
1115 data->x_pos = effects[index].position.x;
1116 data->y_pos = effects[index].position.y;
1117 data->z_pos = effects[index].position.z;
1118 }
1119
destroy_all_eye_candy()1120 void destroy_all_eye_candy()
1121 {
1122 for (std::vector<EffectDefinition>::iterator iter = effects.begin(); iter != effects.end(); iter++)
1123 {
1124 if (iter->reference)
1125 {
1126 ec_recall_effect(iter->reference);
1127 iter->reference = NULL;
1128 }
1129 }
1130 effects.clear();
1131 }
1132
1133 #endif // EYE_CANDY
1134