1 // -*- Mode: C++; tab-width:2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi:tw=80:et:ts=2:sts=2
3 //
4 // -----------------------------------------------------------------------
5 //
6 // This file is part of RLVM, a RealLive virtual machine clone.
7 //
8 // -----------------------------------------------------------------------
9 //
10 // Copyright (C) 2006, 2007 Elliot Glaysher
11 //
12 // This program is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU General Public License as published by
14 // the Free Software Foundation; either version 3 of the License, or
15 // (at your option) any later version.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
25 //
26 // -----------------------------------------------------------------------
27
28 #include "effects/wipe_effect.h"
29
30 #include <cmath>
31
32 #include "machine/rlmachine.h"
33 #include "systems/base/graphics_system.h"
34 #include "systems/base/surface.h"
35 #include "systems/base/system.h"
36
37 // -----------------------------------------------------------------------
38 // WipeEffect base class
39 // -----------------------------------------------------------------------
40
WipeEffect(RLMachine & machine,std::shared_ptr<Surface> src,std::shared_ptr<Surface> dst,const Size & screen_size,int time,int interpolation)41 WipeEffect::WipeEffect(RLMachine& machine,
42 std::shared_ptr<Surface> src,
43 std::shared_ptr<Surface> dst,
44 const Size& screen_size,
45 int time,
46 int interpolation)
47 : Effect(machine, src, dst, screen_size, time),
48 interpolation_(interpolation),
49 interpolation_in_pixels_(0) {
50 if (interpolation_)
51 interpolation_in_pixels_ = int(pow(float(2), interpolation) * 2.5);
52 }
53
~WipeEffect()54 WipeEffect::~WipeEffect() {}
55
56 // Calculates the size of the interpolation and main polygons.
57 //
58 // There are 3 possible stages:
59 // - [0, interpolation_in_pixels_) - Draw only the
60 // transition. (sizeOfMainPolygon == 0, sizeOfInterpolation ==
61 // amountVisible)
62 // - [interpolation_in_pixels_, sizeOfScreen) - Draw both
63 // polygons. (sizeOfMainPolygon == amountVisible -
64 // interpolation_in_pixels_, sizeOfInterpolation == amountVisible)
65 // - [height, height + interpolation_in_pixels_) - Draw both
66 // polygons, flooring the height of the transition to
CalculateSizes(int currentTime,int & sizeOfInterpolation,int & sizeOfMainPolygon,int sizeOfScreen)67 void WipeEffect::CalculateSizes(int currentTime,
68 int& sizeOfInterpolation,
69 int& sizeOfMainPolygon,
70 int sizeOfScreen) {
71 int amountVisible = int((float(currentTime) / duration()) *
72 (sizeOfScreen + interpolation_in_pixels_));
73 if (amountVisible < interpolation_in_pixels_) {
74 sizeOfInterpolation = amountVisible;
75 sizeOfMainPolygon = 0;
76 } else if (amountVisible < sizeOfScreen) {
77 sizeOfInterpolation = interpolation_in_pixels_;
78 sizeOfMainPolygon = amountVisible - interpolation_in_pixels_;
79 } else if (amountVisible < sizeOfScreen + interpolation_in_pixels_) {
80 sizeOfMainPolygon = amountVisible - interpolation_in_pixels_;
81 sizeOfInterpolation = sizeOfScreen - sizeOfMainPolygon;
82 }
83 }
84
BlitOriginalImage() const85 bool WipeEffect::BlitOriginalImage() const { return true; }
86
87 // -----------------------------------------------------------------------
88 // WipeTopToBottomEffect
89 // -----------------------------------------------------------------------
90
WipeTopToBottomEffect(RLMachine & machine,std::shared_ptr<Surface> src,std::shared_ptr<Surface> dst,const Size & screen_size,int time,int interpolation)91 WipeTopToBottomEffect::WipeTopToBottomEffect(RLMachine& machine,
92 std::shared_ptr<Surface> src,
93 std::shared_ptr<Surface> dst,
94 const Size& screen_size,
95 int time,
96 int interpolation)
97 : WipeEffect(machine, src, dst, screen_size, time, interpolation) {}
98
~WipeTopToBottomEffect()99 WipeTopToBottomEffect::~WipeTopToBottomEffect() {}
100
PerformEffectForTime(RLMachine & machine,int currentTime)101 void WipeTopToBottomEffect::PerformEffectForTime(RLMachine& machine,
102 int currentTime) {
103 int sizeOfInterpolation, sizeOfMainPolygon;
104 CalculateSizes(currentTime, sizeOfInterpolation, sizeOfMainPolygon, height());
105
106 if (sizeOfMainPolygon) {
107 src_surface().RenderToScreen(Rect::REC(0, 0, width(), sizeOfMainPolygon),
108 Rect::REC(0, 0, width(), sizeOfMainPolygon),
109 255);
110 }
111
112 if (sizeOfInterpolation) {
113 int opacity[4] = {255, 255, 0, 0};
114
115 src_surface().RenderToScreen(
116 Rect::GRP(0,
117 sizeOfMainPolygon,
118 width(),
119 sizeOfMainPolygon + sizeOfInterpolation),
120 Rect::GRP(0,
121 sizeOfMainPolygon,
122 width(),
123 sizeOfMainPolygon + sizeOfInterpolation),
124 opacity);
125 }
126 }
127
128 // -----------------------------------------------------------------------
129 // WipeBottomToTopEffect
130 // -----------------------------------------------------------------------
131
WipeBottomToTopEffect(RLMachine & machine,std::shared_ptr<Surface> src,std::shared_ptr<Surface> dst,const Size & screen_size,int time,int interpolation)132 WipeBottomToTopEffect::WipeBottomToTopEffect(RLMachine& machine,
133 std::shared_ptr<Surface> src,
134 std::shared_ptr<Surface> dst,
135 const Size& screen_size,
136 int time,
137 int interpolation)
138 : WipeEffect(machine, src, dst, screen_size, time, interpolation) {}
139
~WipeBottomToTopEffect()140 WipeBottomToTopEffect::~WipeBottomToTopEffect() {}
141
PerformEffectForTime(RLMachine & machine,int currentTime)142 void WipeBottomToTopEffect::PerformEffectForTime(RLMachine& machine,
143 int currentTime) {
144 int sizeOfInterpolation, sizeOfMainPolygon;
145 CalculateSizes(currentTime, sizeOfInterpolation, sizeOfMainPolygon, height());
146
147 // Render the sliding on frame
148 if (sizeOfMainPolygon) {
149 src_surface().RenderToScreen(
150 Rect::GRP(0, height() - sizeOfMainPolygon, width(), height()),
151 Rect::GRP(0, height() - sizeOfMainPolygon, width(), height()),
152 255);
153 }
154
155 if (sizeOfInterpolation) {
156 int opacity[4] = {0, 0, 255, 255};
157 src_surface().RenderToScreen(
158 Rect::GRP(0,
159 height() - sizeOfMainPolygon - sizeOfInterpolation,
160 width(),
161 height() - sizeOfMainPolygon),
162 Rect::GRP(0,
163 height() - sizeOfMainPolygon - sizeOfInterpolation,
164 width(),
165 height() - sizeOfMainPolygon),
166 opacity);
167 }
168 }
169
170 // -----------------------------------------------------------------------
171 // WipeFromLeftToRightEffect
172 // -----------------------------------------------------------------------
173
WipeLeftToRightEffect(RLMachine & machine,std::shared_ptr<Surface> src,std::shared_ptr<Surface> dst,const Size & screen_size,int time,int interpolation)174 WipeLeftToRightEffect::WipeLeftToRightEffect(RLMachine& machine,
175 std::shared_ptr<Surface> src,
176 std::shared_ptr<Surface> dst,
177 const Size& screen_size,
178 int time,
179 int interpolation)
180 : WipeEffect(machine, src, dst, screen_size, time, interpolation) {}
181
~WipeLeftToRightEffect()182 WipeLeftToRightEffect::~WipeLeftToRightEffect() {}
183
PerformEffectForTime(RLMachine & machine,int currentTime)184 void WipeLeftToRightEffect::PerformEffectForTime(RLMachine& machine,
185 int currentTime) {
186 int sizeOfInterpolation, sizeOfMainPolygon;
187 CalculateSizes(currentTime, sizeOfInterpolation, sizeOfMainPolygon, width());
188
189 // CONTINUE FIXING THE WIPES HERE!
190
191 if (sizeOfMainPolygon) {
192 src_surface().RenderToScreen(Rect::GRP(0, 0, sizeOfMainPolygon, height()),
193 Rect::GRP(0, 0, sizeOfMainPolygon, height()),
194 255);
195 }
196
197 if (sizeOfInterpolation) {
198 int opacity[4] = {255, 0, 0, 255};
199 src_surface().RenderToScreen(
200 Rect::GRP(sizeOfMainPolygon,
201 0,
202 sizeOfMainPolygon + sizeOfInterpolation,
203 height()),
204 Rect::GRP(sizeOfMainPolygon,
205 0,
206 sizeOfMainPolygon + sizeOfInterpolation,
207 height()),
208 opacity);
209 }
210 }
211
212 // -----------------------------------------------------------------------
213 // WipeFromRightToLeftEffect
214 // -----------------------------------------------------------------------
215
WipeRightToLeftEffect(RLMachine & machine,std::shared_ptr<Surface> src,std::shared_ptr<Surface> dst,const Size & screen_size,int time,int interpolation)216 WipeRightToLeftEffect::WipeRightToLeftEffect(RLMachine& machine,
217 std::shared_ptr<Surface> src,
218 std::shared_ptr<Surface> dst,
219 const Size& screen_size,
220 int time,
221 int interpolation)
222 : WipeEffect(machine, src, dst, screen_size, time, interpolation) {}
223
~WipeRightToLeftEffect()224 WipeRightToLeftEffect::~WipeRightToLeftEffect() {}
225
PerformEffectForTime(RLMachine & machine,int currentTime)226 void WipeRightToLeftEffect::PerformEffectForTime(RLMachine& machine,
227 int currentTime) {
228 int sizeOfInterpolation, sizeOfMainPolygon;
229 CalculateSizes(currentTime, sizeOfInterpolation, sizeOfMainPolygon, width());
230
231 if (sizeOfMainPolygon) {
232 src_surface().RenderToScreen(
233 Rect::GRP(width() - sizeOfMainPolygon, 0, width(), height()),
234 Rect::GRP(width() - sizeOfMainPolygon, 0, width(), height()),
235 255);
236 }
237
238 if (sizeOfInterpolation) {
239 int opacity[4] = {0, 255, 255, 0};
240 src_surface().RenderToScreen(
241 Rect::GRP(width() - sizeOfInterpolation - sizeOfMainPolygon,
242 0,
243 width() - sizeOfMainPolygon,
244 height()),
245 Rect::GRP(width() - sizeOfInterpolation - sizeOfMainPolygon,
246 0,
247 width() - sizeOfMainPolygon,
248 height()),
249 opacity);
250 }
251 }
252