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/blind_effect.h"
29 
30 #include <cstdlib>
31 
32 #include "systems/base/surface.h"
33 
34 // -----------------------------------------------------------------------
35 // BlindEffect
36 // -----------------------------------------------------------------------
37 
BlindEffect(RLMachine & machine,std::shared_ptr<Surface> src,std::shared_ptr<Surface> dst,const Size & screen_size,int time,int blindSize)38 BlindEffect::BlindEffect(RLMachine& machine,
39                          std::shared_ptr<Surface> src,
40                          std::shared_ptr<Surface> dst,
41                          const Size& screen_size,
42                          int time,
43                          int blindSize)
44     : Effect(machine, src, dst, screen_size, time), blind_size_(blindSize) {}
45 
~BlindEffect()46 BlindEffect::~BlindEffect() {}
47 
ComputeGrowing(RLMachine & machine,int maxSize,int currentTime)48 void BlindEffect::ComputeGrowing(RLMachine& machine,
49                                  int maxSize,
50                                  int currentTime) {
51   int num_blinds = maxSize / blind_size() + 1;
52   int rows_to_display =
53       int((float(currentTime) / duration()) * (blind_size() + num_blinds));
54 
55   for (int currentBlind = 0; currentBlind < num_blinds; ++currentBlind) {
56     if (currentBlind <= rows_to_display) {
57       int currentlyDisplayed = std::abs(currentBlind - rows_to_display);
58       if (currentlyDisplayed > blind_size())
59         currentlyDisplayed = blind_size();
60 
61       int polygonStart = currentBlind * blind_size();
62       RenderPolygon(polygonStart, polygonStart + currentlyDisplayed);
63     }
64   }
65 }
66 
ComputeDecreasing(RLMachine & machine,int maxSize,int currentTime)67 void BlindEffect::ComputeDecreasing(RLMachine& machine,
68                                     int maxSize,
69                                     int currentTime) {
70   int num_blinds = maxSize / blind_size() + 1;
71   int rows_to_display =
72       int((float(currentTime) / duration()) * (blind_size() + num_blinds));
73 
74   for (int currentBlind = num_blinds; currentBlind >= 0; --currentBlind) {
75     if ((num_blinds - currentBlind) < rows_to_display) {
76       int currentlyDisplayed =
77           std::abs(num_blinds - currentBlind - rows_to_display);
78       if (currentlyDisplayed > blind_size())
79         currentlyDisplayed = blind_size();
80 
81       int bottomOfPolygon = currentBlind * blind_size();
82 
83       RenderPolygon(bottomOfPolygon, bottomOfPolygon - currentlyDisplayed);
84     }
85   }
86 }
87 
BlitOriginalImage() const88 bool BlindEffect::BlitOriginalImage() const { return true; }
89 
90 // -----------------------------------------------------------------------
91 // BlindTopToBottomEffect
92 // -----------------------------------------------------------------------
93 
BlindTopToBottomEffect(RLMachine & machine,std::shared_ptr<Surface> src,std::shared_ptr<Surface> dst,const Size & screen_size,int time,int blindSize)94 BlindTopToBottomEffect::BlindTopToBottomEffect(RLMachine& machine,
95                                                std::shared_ptr<Surface> src,
96                                                std::shared_ptr<Surface> dst,
97                                                const Size& screen_size,
98                                                int time,
99                                                int blindSize)
100     : BlindEffect(machine, src, dst, screen_size, time, blindSize) {}
101 
~BlindTopToBottomEffect()102 BlindTopToBottomEffect::~BlindTopToBottomEffect() {}
103 
PerformEffectForTime(RLMachine & machine,int currentTime)104 void BlindTopToBottomEffect::PerformEffectForTime(RLMachine& machine,
105                                                   int currentTime) {
106   ComputeGrowing(machine, height(), currentTime);
107 }
108 
RenderPolygon(int polyStart,int polyEnd)109 void BlindTopToBottomEffect::RenderPolygon(int polyStart, int polyEnd) {
110   src_surface().RenderToScreen(Rect::GRP(0, polyStart, width(), polyEnd),
111                                Rect::GRP(0, polyStart, width(), polyEnd),
112                                255);
113 }
114 
115 // -----------------------------------------------------------------------
116 // BlindBottomToTopEffect
117 // -----------------------------------------------------------------------
118 
BlindBottomToTopEffect(RLMachine & machine,std::shared_ptr<Surface> src,std::shared_ptr<Surface> dst,const Size & screen_size,int time,int blindSize)119 BlindBottomToTopEffect::BlindBottomToTopEffect(RLMachine& machine,
120                                                std::shared_ptr<Surface> src,
121                                                std::shared_ptr<Surface> dst,
122                                                const Size& screen_size,
123                                                int time,
124                                                int blindSize)
125     : BlindEffect(machine, src, dst, screen_size, time, blindSize) {}
126 
~BlindBottomToTopEffect()127 BlindBottomToTopEffect::~BlindBottomToTopEffect() {}
128 
PerformEffectForTime(RLMachine & machine,int currentTime)129 void BlindBottomToTopEffect::PerformEffectForTime(RLMachine& machine,
130                                                   int currentTime) {
131   ComputeDecreasing(machine, height(), currentTime);
132 }
133 
RenderPolygon(int polyStart,int polyEnd)134 void BlindBottomToTopEffect::RenderPolygon(int polyStart, int polyEnd) {
135   // Render polygon
136   src_surface().RenderToScreen(Rect::GRP(0, polyEnd, width(), polyStart),
137                                Rect::GRP(0, polyEnd, width(), polyStart),
138                                255);
139 }
140 
141 // -----------------------------------------------------------------------
142 // BlindLeftToRightEffect
143 // -----------------------------------------------------------------------
144 
BlindLeftToRightEffect(RLMachine & machine,std::shared_ptr<Surface> src,std::shared_ptr<Surface> dst,const Size & screen_size,int time,int blindSize)145 BlindLeftToRightEffect::BlindLeftToRightEffect(RLMachine& machine,
146                                                std::shared_ptr<Surface> src,
147                                                std::shared_ptr<Surface> dst,
148                                                const Size& screen_size,
149                                                int time,
150                                                int blindSize)
151     : BlindEffect(machine, src, dst, screen_size, time, blindSize) {}
152 
~BlindLeftToRightEffect()153 BlindLeftToRightEffect::~BlindLeftToRightEffect() {}
154 
PerformEffectForTime(RLMachine & machine,int currentTime)155 void BlindLeftToRightEffect::PerformEffectForTime(RLMachine& machine,
156                                                   int currentTime) {
157   ComputeGrowing(machine, width(), currentTime);
158 }
159 
RenderPolygon(int polyStart,int polyEnd)160 void BlindLeftToRightEffect::RenderPolygon(int polyStart, int polyEnd) {
161   src_surface().RenderToScreen(Rect::GRP(polyStart, 0, polyEnd, height()),
162                                Rect::GRP(polyStart, 0, polyEnd, height()),
163                                255);
164 }
165 
166 // -----------------------------------------------------------------------
167 // BlindRightToLeftEffect
168 // -----------------------------------------------------------------------
169 
BlindRightToLeftEffect(RLMachine & machine,std::shared_ptr<Surface> src,std::shared_ptr<Surface> dst,const Size & screen_size,int time,int blindSize)170 BlindRightToLeftEffect::BlindRightToLeftEffect(RLMachine& machine,
171                                                std::shared_ptr<Surface> src,
172                                                std::shared_ptr<Surface> dst,
173                                                const Size& screen_size,
174                                                int time,
175                                                int blindSize)
176     : BlindEffect(machine, src, dst, screen_size, time, blindSize) {}
177 
~BlindRightToLeftEffect()178 BlindRightToLeftEffect::~BlindRightToLeftEffect() {}
179 
PerformEffectForTime(RLMachine & machine,int currentTime)180 void BlindRightToLeftEffect::PerformEffectForTime(RLMachine& machine,
181                                                   int currentTime) {
182   ComputeDecreasing(machine, width(), currentTime);
183 }
184 
RenderPolygon(int polyStart,int polyEnd)185 void BlindRightToLeftEffect::RenderPolygon(int polyStart, int polyEnd) {
186   src_surface().RenderToScreen(Rect::GRP(polyEnd, 0, polyStart, height()),
187                                Rect::GRP(polyEnd, 0, polyStart, height()),
188                                255);
189 }
190