1 /*
2 FADES.C
3
4 Copyright (C) 1991-2001 and beyond by Bungie Studios, Inc.
5 and the "Aleph One" developers.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
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.
16
17 This license is contained in the file "COPYING",
18 which is included with this source code; it is available online at
19 http://www.gnu.org/licenses/gpl.html
20
21 Friday, June 10, 1994 6:59:04 PM
22
23 Saturday, June 11, 1994 12:49:19 AM
24 not doing signed math on the color deltas resulted in some very cool static-ish effects
25 resulting from integer overflow.
26 Saturday, July 9, 1994 1:06:20 PM
27 fade_finished() was acting like fade_not_finished().
28 Sunday, September 25, 1994 12:50:34 PM (Jason')
29 cool new fades.
30 Monday, April 3, 1995 11:22:58 AM (Jason')
31 fade effects for underwater/lava/goo/sewage.
32 Monday, July 10, 1995 8:23:03 PM (Jason)
33 random transparencies
34 Thursday, August 24, 1995 6:20:06 PM (Jason)
35 removed macintosh dependencies
36 Monday, October 30, 1995 8:02:12 PM (Jason)
37 fade prioritites for juggernaut flash
38
39 Jan 30, 2000 (Loren Petrich):
40 Removed some "static" declarations that conflict with "extern"
41
42 May 17, 2000 (Loren Petrich):
43 Added separate under-JjaroGoo fade effects
44
45 May 20, 2000 (Loren Petrich):
46 Added XML-parser support.
47 Note: "transparency" here should be called the opacity,
48 since if it is zero, then colors will be unmodified.
49
50 May 29, 2000 (Loren Petrich):
51 Extended the ranges of the opacities (values > 1 and < 0 now OK)
52
53 May 30, 2000 (Loren Petrich):
54 Added stuff for transmitting fader info to OpenGL
55
56 Jul 1, 2000 (Loren Petrich):
57 Added some idiot-proofing to the fader accessors
58
59 Jan 31, 2001 (Loren Petrich):
60 Added delayed action for the fader effect, so as to get around certain MacOS oddities
61 */
62
63 #include "cseries.h"
64 #include "fades.h"
65 #include "screen.h"
66 #include "interface.h"
67 #include "map.h" // for TICKS_PER_SECOND
68 #include "InfoTree.h"
69
70 #include <string.h>
71 #include <stdlib.h>
72 #include <math.h>
73 #include <limits.h>
74
75 // LP additions:
76 #include <string.h>
77 #include "OGL_Faders.h"
78
79 #include "Music.h"
80 #include "Movie.h"
81
82 /* ---------- constants */
83
84 #define ADJUSTED_TRANSPARENCY_DOWNSHIFT 8
85
86 #define MINIMUM_FADE_RESTART (MACHINE_TICKS_PER_SECOND/2)
87
88 /* ---------- macros */
89
90 #define FADES_RANDOM() ((fades_random_seed&1) ? (fades_random_seed= (fades_random_seed>>1)^0xb400) : (fades_random_seed>>= 1))
91
92 /* ---------- types */
93
94 typedef void (*fade_proc)(struct color_table *original_color_table, struct color_table *animated_color_table, struct rgb_color *color, _fixed transparency);
95
96 /* ---------- structures */
97
98 /* an effect is something which is applied to the original color table before a fade begins */
99 struct fade_effect_definition
100 {
101 short fade_type;
102 _fixed transparency;
103 };
104
105 enum
106 {
107 _full_screen_flag= 0x0001,
108 _random_transparency_flag= 0x0002
109 };
110
111 struct fade_definition
112 {
113 fade_proc proc;
114 struct rgb_color color;
115 _fixed initial_transparency, final_transparency; /* in [0,FIXED_ONE] */
116
117 short period;
118
119 uint16 flags;
120 short priority; // higher is higher
121 };
122
123 #define FADE_IS_ACTIVE(f) ((f)->flags&(uint16)0x8000)
124 #define SET_FADE_ACTIVE_STATUS(f,s) ((void)((s)?((f)->flags|=(uint16)0x8000):((f)->flags&=(uint16)~0x8000)))
125
126 struct fade_data
127 {
128 uint16 flags; /* [active.1] [unused.15] */
129
130 short type;
131 short fade_effect_type;
132
133 uint32 last_update_tick;
134 uint32 last_update_game_tick;
135
136 struct color_table *original_color_table;
137 struct color_table *animated_color_table;
138 };
139
140 /* ---------- globals */
141
142 static struct fade_data *fade = NULL;
143 static short last_fade_type = NUMBER_OF_FADE_TYPES;
144
145 static uint16 fades_random_seed= 0x1;
146
147 // LP addition: pointer to OpenGL fader to be used in the color-table functions below
148 // It is NULL if OpenGL is inactive
149 static OGL_Fader *CurrentOGLFader = NULL;
150
151 static int FadeEffectDelay = 0;
152
153 /* ---------- fade definitions */
154
155 static void tint_color_table(struct color_table *original_color_table, struct color_table *animated_color_table, struct rgb_color *color, _fixed transparency);
156 static void randomize_color_table(struct color_table *original_color_table, struct color_table *animated_color_table, struct rgb_color *color, _fixed transparency);
157 static void negate_color_table(struct color_table *original_color_table, struct color_table *animated_color_table, struct rgb_color *color, _fixed transparency);
158 static void dodge_color_table(struct color_table *original_color_table, struct color_table *animated_color_table, struct rgb_color *color, _fixed transparency);
159 static void burn_color_table(struct color_table *original_color_table, struct color_table *animated_color_table, struct rgb_color *color, _fixed transparency);
160 static void soft_tint_color_table(struct color_table *original_color_table, struct color_table *animated_color_table, struct rgb_color *color, _fixed transparency);
161
162 static struct fade_definition fade_definitions[NUMBER_OF_FADE_TYPES]=
163 {
164 {tint_color_table, {0, 0, 0}, FIXED_ONE, FIXED_ONE, 0, _full_screen_flag, 0}, /* _start_cinematic_fade_in */
165 {tint_color_table, {0, 0, 0}, FIXED_ONE, 0, MACHINE_TICKS_PER_SECOND/2, _full_screen_flag, 0}, /* _cinematic_fade_in */
166 {tint_color_table, {0, 0, 0}, FIXED_ONE, 0, 3*MACHINE_TICKS_PER_SECOND/2, _full_screen_flag, 0}, /* _long_cinematic_fade_in */
167 {tint_color_table, {0, 0, 0}, 0, FIXED_ONE, MACHINE_TICKS_PER_SECOND/2, _full_screen_flag, 0}, /* _cinematic_fade_out */
168 {tint_color_table, {0, 0, 0}, 0, 0, 0, _full_screen_flag, 0}, /* _end_cinematic_fade_out */
169
170 {tint_color_table, {65535, 0, 0}, (3*FIXED_ONE)/4, 0, MACHINE_TICKS_PER_SECOND/4, 0, 0}, /* _fade_red */
171 {tint_color_table, {65535, 0, 0}, FIXED_ONE, 0, (3*MACHINE_TICKS_PER_SECOND)/4, 0, 0}, /* _fade_big_red */
172 {tint_color_table, {0, 65535, 0}, FIXED_ONE_HALF, 0, MACHINE_TICKS_PER_SECOND/4, 0, 0}, /* _fade_bonus */
173 {tint_color_table, {65535, 65535, 50000}, FIXED_ONE, 0, MACHINE_TICKS_PER_SECOND/3, 0, 0}, /* _fade_bright */
174 {tint_color_table, {65535, 65535, 50000}, FIXED_ONE, 0, 4*MACHINE_TICKS_PER_SECOND, 0, 1}, /* _fade_long_bright */
175 {tint_color_table, {65535, 65535, 0}, FIXED_ONE, 0, MACHINE_TICKS_PER_SECOND/2, 0, 0}, /* _fade_yellow */
176 {tint_color_table, {65535, 65535, 0}, FIXED_ONE, 0, MACHINE_TICKS_PER_SECOND, 0, 0}, /* _fade_big_yellow */
177 {tint_color_table, {215*256, 107*256, 65535}, (3*FIXED_ONE)/4, 0, MACHINE_TICKS_PER_SECOND/4, 0, 0}, /* _fade_purple */
178 {tint_color_table, {169*256, 65535, 224*256}, (3*FIXED_ONE)/4, 0, MACHINE_TICKS_PER_SECOND/2, 0, 0}, /* _fade_cyan */
179 {tint_color_table, {65535, 65535, 65535}, FIXED_ONE_HALF, 0, MACHINE_TICKS_PER_SECOND/4, 0, 0}, /* _fade_white */
180 {tint_color_table, {65535, 65535, 65535}, FIXED_ONE, 0, MACHINE_TICKS_PER_SECOND/2, 0, 0}, /* _fade_big_white */
181 {tint_color_table, {65535, 32768, 0}, FIXED_ONE, 0, MACHINE_TICKS_PER_SECOND/4, 0, 0}, /* _fade_orange */
182 {tint_color_table, {65535, 32768, 0}, FIXED_ONE/4, 0, 3*MACHINE_TICKS_PER_SECOND, 0, 0}, /* _fade_long_orange */
183 {tint_color_table, {0, 65535, 0}, 3*FIXED_ONE/4, 0, MACHINE_TICKS_PER_SECOND/2, 0, 0}, /* _fade_green */
184 {tint_color_table, {65535, 0, 65535}, FIXED_ONE/4, 0, 3*MACHINE_TICKS_PER_SECOND, 0, 0}, /* _fade_long_green */
185
186 {randomize_color_table, {0, 0, 0}, FIXED_ONE, 0, (3*MACHINE_TICKS_PER_SECOND)/8, 0, 0}, /* _fade_static */
187 {negate_color_table, {65535, 65535, 65535}, FIXED_ONE, 0, MACHINE_TICKS_PER_SECOND/2, 0, 0}, /* _fade_negative */
188 {negate_color_table, {65535, 65535, 65535}, FIXED_ONE, 0, (3*MACHINE_TICKS_PER_SECOND)/2, 0, 0}, /* _fade_big_negative */
189 {negate_color_table, {0, 65535, 0}, FIXED_ONE, 0, MACHINE_TICKS_PER_SECOND/2, _random_transparency_flag, 0}, /* _fade_flicker_negative */
190 {dodge_color_table, {0, 65535, 0}, FIXED_ONE, 0, (3*MACHINE_TICKS_PER_SECOND)/4, 0, 0}, /* _fade_dodge_purple */
191 {burn_color_table, {0, 65535, 65535}, FIXED_ONE, 0, MACHINE_TICKS_PER_SECOND, 0, 0}, /* _fade_burn_cyan */
192 {dodge_color_table, {0, 0, 65535}, FIXED_ONE, 0, (3*MACHINE_TICKS_PER_SECOND)/2, 0, 0}, /* _fade_dodge_yellow */
193 {burn_color_table, {0, 65535, 0}, FIXED_ONE, 0, 2*MACHINE_TICKS_PER_SECOND, 0, 0}, /* _fade_burn_green */
194
195 {soft_tint_color_table, {137*256, 0, 137*256}, FIXED_ONE, 0, 2*MACHINE_TICKS_PER_SECOND, 0, 0}, /* _fade_tint_purple */
196 {soft_tint_color_table, {0, 0, 65535}, FIXED_ONE, 0, 2*MACHINE_TICKS_PER_SECOND, 0, 0}, /* _fade_tint_blue */
197 {soft_tint_color_table, {65535, 16384, 0}, FIXED_ONE, 0, 2*MACHINE_TICKS_PER_SECOND, 0, 0}, /* _fade_tint_orange */
198 {soft_tint_color_table, {32768, 65535, 0}, FIXED_ONE, 0, 2*MACHINE_TICKS_PER_SECOND, 0, 0}, /* _fade_tint_gross */
199
200 // LP addition: underneath JjaroGoo (default: like sewage)
201 {soft_tint_color_table, {32768, 65535, 0}, FIXED_ONE, 0, 2*MACHINE_TICKS_PER_SECOND, 0, 0}, /* _fade_tint_gross */
202 };
203
204 // LP change: rearranged to get order: water, lava, sewage, jjaro, pfhor
205 struct fade_effect_definition fade_effect_definitions[NUMBER_OF_FADE_EFFECT_TYPES]=
206 {
207 {_fade_tint_blue, 3*FIXED_ONE/4}, /* _effect_under_water */
208 {_fade_tint_orange, 3*FIXED_ONE/4}, /* _effect_under_lava */
209 {_fade_tint_gross, 3*FIXED_ONE/4}, /* _effect_under_sewage */
210 {_fade_tint_jjaro, 3*FIXED_ONE/4}, /* _effect_under_jjaro */ // LP addition
211 {_fade_tint_green, 3*FIXED_ONE/4}, /* _effect_under_goo */
212 };
213
214 static float actual_gamma_values[NUMBER_OF_GAMMA_LEVELS]=
215 {
216 1.3F,
217 1.15F,
218 1.0F, // default
219 0.95F,
220 0.90F,
221 0.85F,
222 0.77F,
223 0.70F
224 };
225
226 /* ---------- private prototypes */
227
228 static fade_definition *get_fade_definition(
229 const short index);
230
231 static fade_effect_definition *get_fade_effect_definition(
232 const short index);
233
234 static void recalculate_and_display_color_table(short type, _fixed transparency,
235 struct color_table *original_color_table, struct color_table *animated_color_table, bool fade_active);
236
237 // LP additions for OpenGL fader support; both of them use the pointer to the current
238 // OpenGL fader defined above.
239
240 // Set up OpenGL fader-queue entry -- arg is which one (liquid or other);
241 // the fader type is set to NONE.
242 static void SetOGLFader(int Index);
243
244 // Translate the color and opacity values
245 static void TranslateToOGLFader(rgb_color &Color, _fixed Opacity);
246
247 /* ---------- code */
248
249 // Accessors:
get_fade_definition(const short index)250 fade_definition *get_fade_definition(
251 const short index)
252 {
253 return GetMemberWithBounds(fade_definitions,index,NUMBER_OF_FADE_TYPES);
254 }
255
get_fade_effect_definition(const short index)256 fade_effect_definition *get_fade_effect_definition(
257 const short index)
258 {
259 return GetMemberWithBounds(fade_effect_definitions,index,NUMBER_OF_FADE_EFFECT_TYPES);
260 }
261
initialize_fades(void)262 void initialize_fades(
263 void)
264 {
265 /* allocate and initialize space for our fade_data structure */
266 fade= new fade_data;
267 assert(fade);
268 fade->flags = 0;
269
270 SET_FADE_ACTIVE_STATUS(fade, false);
271 fade->fade_effect_type= NONE;
272 }
273
update_fades(bool game_in_progress)274 bool update_fades(
275 bool game_in_progress)
276 {
277 if (FADE_IS_ACTIVE(fade))
278 {
279 struct fade_definition *definition= get_fade_definition(fade->type);
280 // LP change: idiot-proofing
281 if (!definition) return false;
282
283 _fixed transparency;
284 short phase;
285 if (game_in_progress)
286 {
287 phase = (dynamic_world->tick_count - fade->last_update_game_tick) * MACHINE_TICKS_PER_SECOND/TICKS_PER_SECOND;
288 }
289 else
290 {
291 phase = machine_tick_count() - fade->last_update_tick;
292 }
293
294 if (phase>=definition->period)
295 {
296 transparency= definition->final_transparency;
297 SET_FADE_ACTIVE_STATUS(fade, false);
298 }
299 else
300 {
301 transparency= definition->initial_transparency + (phase*(definition->final_transparency-definition->initial_transparency))/definition->period;
302 if (definition->flags&_random_transparency_flag) transparency+= FADES_RANDOM()%(definition->final_transparency-transparency);
303 }
304
305 recalculate_and_display_color_table(fade->type, transparency, fade->original_color_table, fade->animated_color_table, FADE_IS_ACTIVE(fade));
306 Movie::instance()->AddFrame(Movie::FRAME_FADE);
307 }
308
309 return FADE_IS_ACTIVE(fade) ? true : false;
310 }
311
SetFadeEffectDelay(int _FadeEffectDelay)312 void SetFadeEffectDelay(int _FadeEffectDelay)
313 {
314 FadeEffectDelay = _FadeEffectDelay;
315 }
316
set_fade_effect(short type)317 void set_fade_effect(
318 short type)
319 {
320 bool ForceFEUpdate = false;
321 if (FadeEffectDelay > 0)
322 {
323 ForceFEUpdate = true;
324 FadeEffectDelay--;
325 }
326
327 if (ForceFEUpdate || fade->fade_effect_type!=type)
328 {
329 fade->fade_effect_type= type;
330
331 if (!FADE_IS_ACTIVE(fade))
332 {
333 if (type==NONE)
334 {
335 // LP addition: OpenGL-fader handling
336 for (int f=0; f<NUMBER_OF_FADER_QUEUE_ENTRIES; f++)
337 SetOGLFader(f);
338
339 // Only do the video-card fader if the OpenGL fader is inactive
340 #ifdef HAVE_OPENGL
341 if (!OGL_FaderActive())
342 #endif
343 animate_screen_clut(world_color_table, false);
344 }
345 else
346 {
347 recalculate_and_display_color_table(NONE, 0, world_color_table, visible_color_table, false);
348 }
349 }
350 }
351 }
352
start_fade(short type)353 void start_fade(
354 short type)
355 {
356 explicit_start_fade(type, world_color_table, visible_color_table, true);
357 }
358
explicit_start_fade(short type,struct color_table * original_color_table,struct color_table * animated_color_table,bool game_in_progress)359 void explicit_start_fade(
360 short type,
361 struct color_table *original_color_table,
362 struct color_table *animated_color_table,
363 bool game_in_progress)
364 {
365 struct fade_definition *definition= get_fade_definition(type);
366 // LP change: idiot-proofing
367 if (!definition) return;
368
369 uint32 machine_ticks= machine_tick_count();
370 bool do_fade= true;
371
372 if (FADE_IS_ACTIVE(fade))
373 {
374 struct fade_definition *old_definition= get_fade_definition(fade->type);
375 // LP change: idiot-proofing
376 if (old_definition)
377 {
378 if (old_definition->priority>definition->priority) do_fade= false;
379 if (fade->type==type)
380 {
381 short phase;
382 if (game_in_progress)
383 {
384 phase = (dynamic_world->tick_count - fade->last_update_game_tick) * MACHINE_TICKS_PER_SECOND/TICKS_PER_SECOND;
385 }
386 else
387 {
388 phase = machine_ticks - fade->last_update_tick;
389 }
390 if (phase<MINIMUM_FADE_RESTART) do_fade= false;
391 }
392 }
393 }
394
395 if (do_fade)
396 {
397 SET_FADE_ACTIVE_STATUS(fade, false);
398 last_fade_type = type;
399
400 recalculate_and_display_color_table(type, definition->initial_transparency, original_color_table, animated_color_table, definition->period);
401 if (definition->period)
402 {
403 fade->type= type;
404 fade->last_update_tick= machine_ticks;
405 fade->last_update_game_tick = game_in_progress ? dynamic_world->tick_count : 0;
406 fade->original_color_table= original_color_table;
407 fade->animated_color_table= animated_color_table;
408 SET_FADE_ACTIVE_STATUS(fade, true);
409 }
410 }
411 }
412
stop_fade(void)413 void stop_fade(
414 void)
415 {
416 if (FADE_IS_ACTIVE(fade))
417 {
418 struct fade_definition *definition= get_fade_definition(fade->type);
419 // LP change: idiot-proofing
420 if (!definition) return;
421
422 recalculate_and_display_color_table(fade->type, definition->final_transparency,
423 fade->original_color_table, fade->animated_color_table, false);
424
425 SET_FADE_ACTIVE_STATUS(fade, false);
426 }
427 }
428
fade_finished(void)429 bool fade_finished(
430 void)
431 {
432 return FADE_IS_ACTIVE(fade) ? false : true;
433 }
434
full_fade(short type,struct color_table * original_color_table)435 void full_fade(
436 short type,
437 struct color_table *original_color_table)
438 {
439 struct color_table animated_color_table;
440
441 obj_copy(animated_color_table, *original_color_table);
442
443 explicit_start_fade(type, original_color_table, &animated_color_table);
444 while (update_fades())
445 Music::instance()->Idle();
446 ;
447 }
448
get_fade_period(short type)449 short get_fade_period(
450 short type)
451 {
452 struct fade_definition *definition= get_fade_definition(type);
453 // LP change: idiot-proofing
454 if (!definition) return 0;
455
456 return definition->period;
457 }
458
gamma_correct_color_table(struct color_table * uncorrected_color_table,struct color_table * corrected_color_table,short gamma_level)459 void gamma_correct_color_table(
460 struct color_table *uncorrected_color_table,
461 struct color_table *corrected_color_table,
462 short gamma_level)
463 {
464 short i;
465 float gamma;
466 struct rgb_color *uncorrected= uncorrected_color_table->colors;
467 struct rgb_color *corrected= corrected_color_table->colors;
468
469 assert(gamma_level>=0 && gamma_level<NUMBER_OF_GAMMA_LEVELS);
470 gamma= actual_gamma_values[gamma_level];
471 if (Movie::instance()->IsRecording())
472 gamma = 1.0;
473 if (gamma > 0.999F && gamma < 1.001F) {
474 memcpy(corrected_color_table, uncorrected_color_table, sizeof(struct color_table));
475 return;
476 }
477
478 corrected_color_table->color_count= uncorrected_color_table->color_count;
479 for (i= 0; i<uncorrected_color_table->color_count; ++i, ++corrected, ++uncorrected)
480 {
481 corrected->red = static_cast<uint16>(pow(static_cast<float>(uncorrected->red/65535.0), gamma)*65535.0);
482 corrected->green = static_cast<uint16>(pow(static_cast<float>(uncorrected->green/65535.0), gamma)*65535.0);
483 corrected->blue = static_cast<uint16>(pow(static_cast<float>(uncorrected->blue/65535.0), gamma)*65535.0);
484 }
485 }
486
get_actual_gamma_adjust(short gamma_level)487 float get_actual_gamma_adjust(short gamma_level)
488 {
489 return actual_gamma_values[gamma_level];
490 }
491
fade_blacked_screen(void)492 bool fade_blacked_screen(void)
493 {
494 return (!FADE_IS_ACTIVE(fade) &&
495 (last_fade_type == _start_cinematic_fade_in ||
496 last_fade_type == _cinematic_fade_out));
497 }
498
499 /* ---------- private code */
500
501 /*
502 struct fade_definition *get_fade_definition(
503 short index)
504 {
505 assert(index>=0 && index<NUMBER_OF_FADE_TYPES);
506
507 return fade_definitions + index;
508 }
509
510 static struct fade_effect_definition *get_fade_effect_definition(
511 short index)
512 {
513 assert(index>=0 && index<NUMBER_OF_FADE_EFFECT_TYPES);
514
515 return fade_effect_definitions + index;
516 }
517 */
518
519 //void draw_intro_screen(void); // from screen.cpp
520
recalculate_and_display_color_table(short type,_fixed transparency,struct color_table * original_color_table,struct color_table * animated_color_table,bool fade_active)521 static void recalculate_and_display_color_table(
522 short type,
523 _fixed transparency,
524 struct color_table *original_color_table,
525 struct color_table *animated_color_table,
526 bool fade_active)
527 {
528 bool full_screen= false;
529
530 // LP addition: set up the OGL queue entry for the liquid effects
531 SetOGLFader(FaderQueue_Liquid);
532
533 /* if a fade effect is active, apply it first */
534 if (fade->fade_effect_type!=NONE)
535 {
536 struct fade_effect_definition *effect_definition= get_fade_effect_definition(fade->fade_effect_type);
537 // LP change: idiot-proofing
538 if (!effect_definition) return;
539
540 struct fade_definition *definition= get_fade_definition(effect_definition->fade_type);
541 // LP change: idiot-proofing
542 if (!definition) return;
543
544 definition->proc(original_color_table, animated_color_table, &definition->color, effect_definition->transparency);
545 original_color_table= animated_color_table;
546 }
547
548 // LP addition: set up the OGL queue entry for the other effects
549 SetOGLFader(FaderQueue_Other);
550
551 if (type!=NONE)
552 {
553 struct fade_definition *definition= get_fade_definition(type);
554
555 definition->proc(original_color_table, animated_color_table, &definition->color, transparency);
556 full_screen= (definition->flags&_full_screen_flag) ? true : false;
557
558 // cancel OGL fader if we've reached the end point for this fade
559 if (!fade_active)
560 SetOGLFader(FaderQueue_Other);
561 }
562
563 // Only do the video-card fader if the OpenGL fader is inactive
564 #ifdef HAVE_OPENGL
565 if (!OGL_FaderActive())
566 #endif
567 animate_screen_clut(animated_color_table, full_screen);
568
569 if (get_game_state() < _game_in_progress) // main menu or chapter screen
570 draw_intro_screen();
571 }
572
573 /* ---------- fade functions */
574
tint_color_table(struct color_table * original_color_table,struct color_table * animated_color_table,struct rgb_color * color,_fixed transparency)575 static void tint_color_table(
576 struct color_table *original_color_table,
577 struct color_table *animated_color_table,
578 struct rgb_color *color,
579 _fixed transparency)
580 {
581 // LP addition: support for OpenGL faders
582 if (CurrentOGLFader)
583 {
584 CurrentOGLFader->Type = _tint_fader_type;
585 TranslateToOGLFader(*color,transparency);
586 return;
587 }
588
589 short i;
590 struct rgb_color *unadjusted= original_color_table->colors;
591 struct rgb_color *adjusted= animated_color_table->colors;
592 short adjusted_transparency= transparency>>ADJUSTED_TRANSPARENCY_DOWNSHIFT;
593
594 animated_color_table->color_count= original_color_table->color_count;
595 for (i= 0; i<original_color_table->color_count; ++i, ++adjusted, ++unadjusted)
596 {
597 adjusted->red= unadjusted->red + (((color->red-unadjusted->red)*adjusted_transparency)>>(FIXED_FRACTIONAL_BITS-ADJUSTED_TRANSPARENCY_DOWNSHIFT));
598 adjusted->green= unadjusted->green + (((color->green-unadjusted->green)*adjusted_transparency)>>(FIXED_FRACTIONAL_BITS-ADJUSTED_TRANSPARENCY_DOWNSHIFT));
599 adjusted->blue= unadjusted->blue + (((color->blue-unadjusted->blue)*adjusted_transparency)>>(FIXED_FRACTIONAL_BITS-ADJUSTED_TRANSPARENCY_DOWNSHIFT));
600 }
601 }
602
randomize_color_table(struct color_table * original_color_table,struct color_table * animated_color_table,struct rgb_color * color,_fixed transparency)603 static void randomize_color_table(
604 struct color_table *original_color_table,
605 struct color_table *animated_color_table,
606 struct rgb_color *color,
607 _fixed transparency)
608 {
609 // LP addition: support for OpenGL faders
610 if (CurrentOGLFader)
611 {
612 CurrentOGLFader->Type = _randomize_fader_type;
613 // Create random colors, but transmit the opacity
614 CurrentOGLFader->Color[0] = FADES_RANDOM()/float(SHRT_MAX);
615 CurrentOGLFader->Color[1] = FADES_RANDOM()/float(SHRT_MAX);
616 CurrentOGLFader->Color[2] = FADES_RANDOM()/float(SHRT_MAX);
617 CurrentOGLFader->Color[3] = transparency/float(FIXED_ONE);
618 return;
619 }
620
621 short i;
622 struct rgb_color *unadjusted= original_color_table->colors;
623 struct rgb_color *adjusted= animated_color_table->colors;
624 uint16 mask, adjusted_transparency= PIN(transparency, 0, 0xffff);
625
626 (void) (color);
627
628 /* calculate a mask which has all bits including and lower than the high-bit in the
629 transparency set */
630 for (mask= 0; ~mask & adjusted_transparency; mask= (mask<<1)|1)
631 ;
632
633 animated_color_table->color_count= original_color_table->color_count;
634 for (i= 0; i<original_color_table->color_count; ++i, ++adjusted, ++unadjusted)
635 {
636 adjusted->red= unadjusted->red + (FADES_RANDOM()&mask);
637 adjusted->green= unadjusted->green + (FADES_RANDOM()&mask);
638 adjusted->blue= unadjusted->blue + (FADES_RANDOM()&mask);
639 }
640 }
641
642 /* unlike pathways, all colors won�t pass through 50% gray at the same time */
negate_color_table(struct color_table * original_color_table,struct color_table * animated_color_table,struct rgb_color * color,_fixed transparency)643 static void negate_color_table(
644 struct color_table *original_color_table,
645 struct color_table *animated_color_table,
646 struct rgb_color *color,
647 _fixed transparency)
648 {
649 // LP addition: support for OpenGL faders
650 if (CurrentOGLFader)
651 {
652 CurrentOGLFader->Type = _negate_fader_type;
653 TranslateToOGLFader(*color,transparency);
654 return;
655 }
656
657 short i;
658 struct rgb_color *unadjusted= original_color_table->colors;
659 struct rgb_color *adjusted= animated_color_table->colors;
660
661 transparency= FIXED_ONE-transparency;
662 animated_color_table->color_count= original_color_table->color_count;
663 for (i= 0; i<original_color_table->color_count; ++i, ++adjusted, ++unadjusted)
664 {
665 adjusted->red= (unadjusted->red>0x8000) ?
666 CEILING((unadjusted->red^color->red)+transparency, (int32)unadjusted->red) :
667 FLOOR((unadjusted->red^color->red)-transparency, (int32)unadjusted->red);
668 adjusted->green= (unadjusted->green>0x8000) ?
669 CEILING((unadjusted->green^color->green)+transparency, (int32)unadjusted->green) :
670 FLOOR((unadjusted->green^color->green)-transparency, (int32)unadjusted->green);
671 adjusted->blue= (unadjusted->blue>0x8000) ?
672 CEILING((unadjusted->blue^color->blue)+transparency, (int32)unadjusted->blue) :
673 FLOOR((unadjusted->blue^color->blue)-transparency, (int32)unadjusted->blue);
674 }
675 }
676
dodge_color_table(struct color_table * original_color_table,struct color_table * animated_color_table,struct rgb_color * color,_fixed transparency)677 static void dodge_color_table(
678 struct color_table *original_color_table,
679 struct color_table *animated_color_table,
680 struct rgb_color *color,
681 _fixed transparency)
682 {
683 // LP addition: support for OpenGL faders
684 if (CurrentOGLFader)
685 {
686 CurrentOGLFader->Type = _dodge_fader_type;
687 TranslateToOGLFader(*color,transparency);
688 return;
689 }
690
691 short i;
692 struct rgb_color *unadjusted= original_color_table->colors;
693 struct rgb_color *adjusted= animated_color_table->colors;
694
695 animated_color_table->color_count= original_color_table->color_count;
696 for (i= 0; i<original_color_table->color_count; ++i, ++adjusted, ++unadjusted)
697 {
698 int32 component;
699
700 component= 0xffff - (int32(1LL*(color->red^0xffff)*unadjusted->red)>>FIXED_FRACTIONAL_BITS) - transparency, adjusted->red= CEILING(component, unadjusted->red);
701 component= 0xffff - (int32(1LL*(color->green^0xffff)*unadjusted->green)>>FIXED_FRACTIONAL_BITS) - transparency, adjusted->green= CEILING(component, unadjusted->green);
702 component= 0xffff - (int32(1LL*(color->blue^0xffff)*unadjusted->blue)>>FIXED_FRACTIONAL_BITS) - transparency, adjusted->blue= CEILING(component, unadjusted->blue);
703 }
704 }
705
burn_color_table(struct color_table * original_color_table,struct color_table * animated_color_table,struct rgb_color * color,_fixed transparency)706 static void burn_color_table(
707 struct color_table *original_color_table,
708 struct color_table *animated_color_table,
709 struct rgb_color *color,
710 _fixed transparency)
711 {
712 // LP addition: support for OpenGL faders
713 if (CurrentOGLFader)
714 {
715 CurrentOGLFader->Type = _burn_fader_type;
716 TranslateToOGLFader(*color,transparency);
717 return;
718 }
719
720 short i;
721 struct rgb_color *unadjusted= original_color_table->colors;
722 struct rgb_color *adjusted= animated_color_table->colors;
723
724 transparency= FIXED_ONE-transparency;
725 animated_color_table->color_count= original_color_table->color_count;
726 for (i= 0; i<original_color_table->color_count; ++i, ++adjusted, ++unadjusted)
727 {
728 int32 component;
729
730 component= (int32(1LL*color->red*unadjusted->red)>>FIXED_FRACTIONAL_BITS) + transparency, adjusted->red= CEILING(component, unadjusted->red);
731 component= (int32(1LL*color->green*unadjusted->green)>>FIXED_FRACTIONAL_BITS) + transparency, adjusted->green= CEILING(component, unadjusted->green);
732 component= (int32(1LL*color->blue*unadjusted->blue)>>FIXED_FRACTIONAL_BITS) + transparency, adjusted->blue= CEILING(component, unadjusted->blue);
733 }
734 }
735
soft_tint_color_table(struct color_table * original_color_table,struct color_table * animated_color_table,struct rgb_color * color,_fixed transparency)736 static void soft_tint_color_table(
737 struct color_table *original_color_table,
738 struct color_table *animated_color_table,
739 struct rgb_color *color,
740 _fixed transparency)
741 {
742 // LP addition: support for OpenGL faders
743 if (CurrentOGLFader)
744 {
745 CurrentOGLFader->Type = _soft_tint_fader_type;
746 TranslateToOGLFader(*color,transparency);
747 return;
748 }
749
750 short i;
751 struct rgb_color *unadjusted= original_color_table->colors;
752 struct rgb_color *adjusted= animated_color_table->colors;
753 uint16 adjusted_transparency= transparency>>ADJUSTED_TRANSPARENCY_DOWNSHIFT;
754
755 animated_color_table->color_count= original_color_table->color_count;
756 for (i= 0; i<original_color_table->color_count; ++i, ++adjusted, ++unadjusted)
757 {
758 uint16 intensity;
759
760 intensity= MAX(unadjusted->red, unadjusted->green);
761 intensity= MAX(intensity, unadjusted->blue)>>ADJUSTED_TRANSPARENCY_DOWNSHIFT;
762
763 adjusted->red= unadjusted->red + (((((color->red*intensity)>>(FIXED_FRACTIONAL_BITS-ADJUSTED_TRANSPARENCY_DOWNSHIFT))-unadjusted->red)*adjusted_transparency)>>(FIXED_FRACTIONAL_BITS-ADJUSTED_TRANSPARENCY_DOWNSHIFT));
764 adjusted->green= unadjusted->green + (((((color->green*intensity)>>(FIXED_FRACTIONAL_BITS-ADJUSTED_TRANSPARENCY_DOWNSHIFT))-unadjusted->green)*adjusted_transparency)>>(FIXED_FRACTIONAL_BITS-ADJUSTED_TRANSPARENCY_DOWNSHIFT));
765 adjusted->blue= unadjusted->blue + (((((color->blue*intensity)>>(FIXED_FRACTIONAL_BITS-ADJUSTED_TRANSPARENCY_DOWNSHIFT))-unadjusted->blue)*adjusted_transparency)>>(FIXED_FRACTIONAL_BITS-ADJUSTED_TRANSPARENCY_DOWNSHIFT));
766 }
767 }
768
769
770 // Arg is location in the OpenGL fader queue
SetOGLFader(int Index)771 void SetOGLFader(int Index)
772 {
773 #ifdef HAVE_OPENGL
774 if (OGL_FaderActive())
775 {
776 CurrentOGLFader = GetOGL_FaderQueueEntry(Index);
777 CurrentOGLFader->Type = NONE;
778 } else
779 #endif
780 CurrentOGLFader = NULL;
781 }
782
783 // Translate the color and opacity values
TranslateToOGLFader(rgb_color & Color,_fixed Opacity)784 static void TranslateToOGLFader(rgb_color &Color, _fixed Opacity)
785 {
786 assert(CurrentOGLFader);
787 CurrentOGLFader->Color[0] = Color.red/float(FIXED_ONE-1);
788 CurrentOGLFader->Color[1] = Color.green/float(FIXED_ONE-1);
789 CurrentOGLFader->Color[2] = Color.blue/float(FIXED_ONE-1);
790 CurrentOGLFader->Color[3] = Opacity/float(FIXED_ONE);
791 }
792
793
794 struct fade_definition *original_fade_definitions = NULL;
795 struct fade_effect_definition *original_fade_effect_definitions = NULL;
796
reset_mml_faders()797 void reset_mml_faders()
798 {
799 if (original_fade_definitions) {
800 for (int i = 0; i < NUMBER_OF_FADE_TYPES; i++)
801 fade_definitions[i] = original_fade_definitions[i];
802 free(original_fade_definitions);
803 original_fade_definitions = NULL;
804 }
805
806 if (original_fade_effect_definitions) {
807 for (int i = 0; i < NUMBER_OF_FADE_EFFECT_TYPES; i++)
808 fade_effect_definitions[i] = original_fade_effect_definitions[i];
809 free(original_fade_effect_definitions);
810 original_fade_effect_definitions = NULL;
811 }
812 }
813
parse_mml_faders(const InfoTree & root)814 void parse_mml_faders(const InfoTree& root)
815 {
816 // back up old values first
817 if (!original_fade_definitions) {
818 original_fade_definitions = (struct fade_definition *) malloc(sizeof(struct fade_definition) * NUMBER_OF_FADE_TYPES);
819 assert(original_fade_definitions);
820 for (int i = 0; i < NUMBER_OF_FADE_TYPES; i++)
821 original_fade_definitions[i] = fade_definitions[i];
822 }
823
824 if (!original_fade_effect_definitions) {
825 original_fade_effect_definitions = (struct fade_effect_definition *) malloc(sizeof(struct fade_effect_definition) * NUMBER_OF_FADE_EFFECT_TYPES);
826 assert(original_fade_effect_definitions);
827 for (int i = 0; i < NUMBER_OF_FADE_EFFECT_TYPES; i++)
828 original_fade_effect_definitions[i] = fade_effect_definitions[i];
829 }
830
831 BOOST_FOREACH(InfoTree ftree, root.children_named("fader"))
832 {
833 int16 index;
834 if (!ftree.read_indexed("index", index, NUMBER_OF_FADE_TYPES))
835 continue;
836
837 fade_definition& def = fade_definitions[index];
838 int16 fade_type;
839 if (ftree.read_indexed("type", fade_type, NUMBER_OF_FADER_FUNCTIONS))
840 {
841 switch (fade_type) {
842 case _tint_fader_type:
843 def.proc = tint_color_table;
844 break;
845 case _randomize_fader_type:
846 def.proc = randomize_color_table;
847 break;
848 case _negate_fader_type:
849 def.proc = negate_color_table;
850 break;
851 case _dodge_fader_type:
852 def.proc = dodge_color_table;
853 break;
854 case _burn_fader_type:
855 def.proc = burn_color_table;
856 break;
857 case _soft_tint_fader_type:
858 def.proc = soft_tint_color_table;
859 break;
860 default:
861 break;
862 }
863 }
864
865 ftree.read_fixed("initial_opacity", def.initial_transparency);
866 ftree.read_fixed("final_opacity", def.final_transparency);
867 ftree.read_attr("flags", def.flags);
868 ftree.read_attr("priority", def.priority);
869 int16 period;
870 if (ftree.read_attr("period", period))
871 def.period = static_cast<int32>(period) * 1000 / MACHINE_TICKS_PER_SECOND;
872
873 BOOST_FOREACH(InfoTree color, ftree.children_named("color"))
874 color.read_color(def.color);
875 }
876
877 BOOST_FOREACH(InfoTree ltree, root.children_named("liquid"))
878 {
879 int16 index;
880 if (!ltree.read_indexed("index", index, NUMBER_OF_FADE_EFFECT_TYPES))
881 continue;
882
883 fade_effect_definition& def = fade_effect_definitions[index];
884 ltree.read_indexed("fader", def.fade_type, NUMBER_OF_FADE_TYPES, true);
885 ltree.read_fixed("opacity", def.transparency);
886 }
887 }
888