1 ///////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2004-2011 by The Allacrost Project
3 //            Copyright (C) 2012-2016 by Bertram (Valyria Tear)
4 //                         All Rights Reserved
5 //
6 // This code is licensed under the GNU GPL version 2. It is free software
7 // and you may modify it and/or redistribute it under the terms of this license.
8 // See http://www.gnu.org/copyleft/gpl.html for details.
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 /** ****************************************************************************
12 *** \file    fade.h
13 *** \author  Raj Sharma, roos@allacrost.org
14 *** \author  Yohann Ferreira, yohann ferreira orange fr
15 *** \brief   Header file for ScreenFader class.
16 *** ***************************************************************************/
17 
18 #include "fade.h"
19 
20 #include "video.h"
21 
22 #include "engine/mode_manager.h"
23 
24 using namespace vt_utils;
25 using namespace vt_mode_manager;
26 
27 namespace vt_video
28 {
29 
30 namespace private_video
31 {
32 
ScreenFader()33 ScreenFader::ScreenFader() :
34     _current_color(0.0f, 0.0f, 0.0f, 0.0f),
35     _initial_color(0.0f, 0.0f, 0.0f, 0.0f),
36     _final_color(0.0f, 0.0f, 0.0f, 0.0f),
37     _current_time(0),
38     _end_time(0),
39     _is_fading(false),
40     _interpolate_rgb_values(false),
41     _transitional_fading(false)
42 {
43     // Fading overlay image
44     _fade_overlay_img.Load("", 1.0f, 1.0f);
45 }
46 
47 
BeginFade(const Color & final_color,uint32_t duration,bool transitional)48 void ScreenFader::BeginFade(const Color &final_color, uint32_t duration, bool transitional)
49 {
50     // If last fade is made by the system, don't permit to fade:
51     if(!transitional && _is_fading && _transitional_fading)
52         return;
53 
54     _transitional_fading = transitional;
55     _is_fading = true;
56 
57     _end_time = duration;
58 
59     _initial_color = _current_color;
60     _final_color = final_color;
61     _current_time = 0;
62 
63     // If we are fading to or from transparent, then the RGB values do not need to be interpolated
64     if(IsFloatEqual(_final_color[3], 0.0f)) {
65         _interpolate_rgb_values = true;
66         _current_color[0] = _initial_color[0];
67         _current_color[1] = _initial_color[1];
68         _current_color[2] = _initial_color[2];
69     } else if(IsFloatEqual(_initial_color[3], 0.0f)) {
70         _interpolate_rgb_values = true;
71         _current_color[0] = _final_color[0];
72         _current_color[1] = _final_color[1];
73         _current_color[2] = _final_color[2];
74     } else {
75         _interpolate_rgb_values = false;
76     }
77 
78     Update(0); // Do an initial update
79 } // void ScreenFader::BeginFade(const Color &final, uint32_t time)
80 
81 
82 
Update(uint32_t time)83 void ScreenFader::Update(uint32_t time)
84 {
85     if(!_is_fading)
86         return;
87 
88     // Don't update fading while in pause
89     if(ModeManager->GetGameType() == MODE_MANAGER_PAUSE_MODE)
90         return;
91 
92     // Check for fading finish condition
93     if(_current_time >= _end_time) {
94         _current_color = _final_color;
95         _fade_overlay_img.SetColor(_current_color);
96         _is_fading = false;
97         return;
98     }
99 
100     // Calculate the new interpolated color
101     float percent_complete = static_cast<float>(_current_time) / static_cast<float>(_end_time);
102 
103     if(_interpolate_rgb_values) {
104         _current_color[0] = Lerp(percent_complete, _initial_color[0], _final_color[0]);
105         _current_color[1] = Lerp(percent_complete, _initial_color[1], _final_color[1]);
106         _current_color[2] = Lerp(percent_complete, _initial_color[2], _final_color[2]);
107     }
108     _current_color[3] = Lerp(percent_complete, _initial_color[3], _final_color[3]);
109 
110     _fade_overlay_img.SetColor(_current_color);
111 
112     _current_time += time;
113 }
114 
Draw()115 void ScreenFader::Draw()
116 {
117     if (_current_color == Color::clear)
118         return;
119 
120     VideoManager->PushState();
121     VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_TOP, 0);
122     // We add a margin in case of screen shaking to avoid unlit parts.
123     VideoManager->SetCoordSys(0.1f, 0.9f, 0.9f, 0.1f);
124     VideoManager->Move(0.0f, 0.0f);
125     _fade_overlay_img.Draw();
126     VideoManager->PopState();
127 }
128 
129 } // namespace private_video
130 
131 }  // namespace vt_video
132