ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

fireflies.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "engines/stark/visual/effects/fireflies.h"
00024 
00025 #include "common/random.h"
00026 #include "common/tokenizer.h"
00027 
00028 #include "graphics/surface.h"
00029 
00030 #include "engines/stark/gfx/driver.h"
00031 #include "engines/stark/gfx/surfacerenderer.h"
00032 #include "engines/stark/gfx/texture.h"
00033 
00034 #include "engines/stark/services/global.h"
00035 #include "engines/stark/services/services.h"
00036 #include "engines/stark/services/settings.h"
00037 
00038 namespace Stark {
00039 
00040 VisualEffectFireFlies::VisualEffectFireFlies(Gfx::Driver *gfx, const Common::Point &size) :
00041         VisualEffect(TYPE, size, gfx),
00042         _fireFlyCount(10),
00043         _mainColorR(44),
00044         _mainColorG(20),
00045         _mainColorB(33) {
00046 }
00047 
00048 VisualEffectFireFlies::~VisualEffectFireFlies() {
00049 }
00050 
00051 void VisualEffectFireFlies::render(const Common::Point &position) {
00052     // Stop rendering if special effect is off
00053     if (!StarkSettings->getBoolSetting(Settings::kSpecialFX)) return;
00054 
00055     _timeRemainingUntilNextUpdate -= StarkGlobal->getMillisecondsPerGameloop();
00056     if (_timeRemainingUntilNextUpdate <= 0) {
00057         update();
00058         _timeRemainingUntilNextUpdate = _timeBetweenTwoUpdates;
00059     }
00060 
00061     // Fill with transparent color
00062     _surface->fillRect(Common::Rect(_surface->w, _surface->h), 0);
00063 
00064     for (uint i = 0; i < _fireFlies.size(); i++) {
00065         drawFireFly(_fireFlies[i]);
00066     }
00067 
00068     _texture->update(_surface);
00069     _surfaceRenderer->render(_texture, position);
00070 }
00071 
00072 void VisualEffectFireFlies::setParams(const Common::String &params) {
00073     // Example input: GFX_FireFlies( 2, 70 )
00074     Common::StringTokenizer tokenizer(params, "(), ");
00075 
00076     int index = 0;
00077     while (!tokenizer.empty()) {
00078         Common::String token = tokenizer.nextToken();
00079         switch (index) {
00080         case 0:
00081             if (token != "GFX_FireFlies") {
00082                 error("Unexpected effect type '%s'", token.c_str());
00083             }
00084             break;
00085         case 1:
00086             _timeBetweenTwoUpdates = CLIP<uint>(strtol(token.c_str(), nullptr, 10), 0, 1000) * 33;
00087             break;
00088         case 2:
00089             _fireFlyCount = CLIP<uint>(strtol(token.c_str(), nullptr, 10), 1, 300);
00090             break;
00091         case 3:
00092             _mainColorR = strtol(token.c_str(), nullptr, 10);
00093             break;
00094         case 4:
00095             _mainColorG = strtol(token.c_str(), nullptr, 10);
00096             break;
00097         case 5:
00098             _mainColorB = strtol(token.c_str(), nullptr, 10);
00099             break;
00100         default:
00101             warning("Unexpected parameter %d: %s", index, token.c_str());
00102         }
00103 
00104         index++;
00105     }
00106 
00107     _frames.resize(40);
00108     for (uint i = 0; i < _frames.size(); i++) {
00109         Frame &frame = _frames[i];
00110 
00111         // Barycentric coordinates
00112         float t = (cos((_frames.size() - i) / (float)_frames.size() * 2.1415f + 0.5f) + 1.0f) * 0.5f;
00113         frame.weight1 = (1.0f - t) * (1.0f - t) * (1.0f - t) / 6.0f;
00114         frame.weight2 = (t * t * t * 3.0f - t * t * 6.0f + 4.0f) / 6.0f;
00115         frame.weight3 = (((3.0f - t * 3.0f) * t + 3.0f) * t + 1.0f) / 6.0f;
00116         frame.weight4 = t * t * t / 6.0f;
00117 
00118         int green;
00119         if (i < 5) {
00120             green = _mainColorG + (255 - _mainColorG) * (5 - i) / 5;
00121         } else if (i + 4 >= _frames.size()) {
00122             green = _mainColorG + (255 - _mainColorG) * (i + 4 - _frames.size()) / 5;
00123         } else {
00124             green = _mainColorG;
00125         }
00126         frame.color = _surface->format.RGBToColor(_mainColorR, green, _mainColorB);
00127     }
00128 
00129     _fireFlies.resize(_fireFlyCount);
00130     for (uint i = 0; i < _fireFlies.size(); i++) {
00131         FireFly &fireFly = _fireFlies[i];
00132 
00133         fireFly.point1.x = StarkRandomSource->getRandomNumber(_size.x - 1);
00134         fireFly.point1.y = StarkRandomSource->getRandomNumber(_size.y - 1);
00135         fireFly.point2.x = StarkRandomSource->getRandomNumber(_size.x - 1);
00136         fireFly.point2.y = StarkRandomSource->getRandomNumber(_size.y - 1);
00137         fireFly.point3.x = StarkRandomSource->getRandomNumber(_size.x - 1);
00138         fireFly.point3.y = StarkRandomSource->getRandomNumber(_size.y - 1);
00139         fireFly.point4.x = StarkRandomSource->getRandomNumber(_size.x - 1);
00140         fireFly.point4.y = StarkRandomSource->getRandomNumber(_size.y - 1);
00141         fireFly.currentFrame = StarkRandomSource->getRandomNumber(_frames.size() - 1);
00142     }
00143 }
00144 
00145 void VisualEffectFireFlies::update() {
00146     for (uint i = 0; i < _fireFlies.size(); i++) {
00147         FireFly &fireFly = _fireFlies[i];
00148         fireFly.currentFrame++;
00149 
00150         if (fireFly.currentFrame >= _frames.size()) {
00151             fireFly.currentFrame %= _frames.size();
00152 
00153             fireFly.point1 = fireFly.point2;
00154             fireFly.point2 = fireFly.point3;
00155             fireFly.point3 = fireFly.point4;
00156             fireFly.point4.x = StarkRandomSource->getRandomNumber(_size.x - 1);
00157             fireFly.point4.y = StarkRandomSource->getRandomNumber(_size.y - 1);
00158         }
00159     }
00160 
00161     for (uint i = 0; i < _fireFlies.size(); i++) {
00162         FireFly &fireFly = _fireFlies[i];
00163         const Frame &frame = _frames[fireFly.currentFrame];
00164 
00165         fireFly.currentPosition.x = fireFly.point1.x * frame.weight1 + fireFly.point2.x * frame.weight2
00166                                     + fireFly.point3.x * frame.weight3 + fireFly.point4.x * frame.weight4;
00167         fireFly.currentPosition.y = fireFly.point1.y * frame.weight1 + fireFly.point2.y * frame.weight2
00168                                     + fireFly.point3.y * frame.weight3 + fireFly.point4.y * frame.weight4;
00169     }
00170 }
00171 
00172 void VisualEffectFireFlies::drawFireFly(const FireFly &fly) {
00173     if (fly.currentPosition.x < 0 || fly.currentPosition.x >= _surface->w
00174         || fly.currentPosition.y < 0 || fly.currentPosition.y >= _surface->h) {
00175         return;
00176     }
00177 
00178     uint32 *pixel = static_cast<uint32 *>(_surface->getBasePtr(fly.currentPosition.x, fly.currentPosition.y));
00179     *pixel = _frames[fly.currentFrame].color;
00180 }
00181 
00182 } // End of namespace Stark


Generated on Sat Mar 16 2019 05:01:31 for ResidualVM by doxygen 1.7.1
curved edge   curved edge