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

bubbles.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/bubbles.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 VisualEffectBubbles::VisualEffectBubbles(Gfx::Driver *gfx, const Common::Point &size) :
00041         VisualEffect(TYPE, size, gfx),
00042         _bubbleCount(50),
00043         _kind(kSmall),
00044         _sourcePositionRatioX(50),
00045         _maxVerticalSpeed(3),
00046         _maxHorizontalSpeed(1),
00047         _mainColorR(128),
00048         _mainColorG(128),
00049         _mainColorB(180),
00050         _mainColor(0),
00051         _darkColor(0) {
00052 }
00053 
00054 VisualEffectBubbles::~VisualEffectBubbles() {
00055 }
00056 
00057 void VisualEffectBubbles::render(const Common::Point &position) {
00058     // Stop rendering if special effect is off
00059     if (!StarkSettings->getBoolSetting(Settings::kSpecialFX)) return;
00060 
00061     _timeRemainingUntilNextUpdate -= StarkGlobal->getMillisecondsPerGameloop();
00062     if (_timeRemainingUntilNextUpdate <= 0) {
00063         update();
00064         _timeRemainingUntilNextUpdate = _timeBetweenTwoUpdates;
00065     }
00066 
00067     // Fill with transparent color
00068     _surface->fillRect(Common::Rect(_surface->w, _surface->h), 0);
00069 
00070     for (uint i = 0; i < _bubbles.size(); i++) {
00071         drawBubble(_bubbles[i]);
00072     }
00073 
00074     _texture->update(_surface);
00075     _surfaceRenderer->render(_texture, position);
00076 }
00077 
00078 void VisualEffectBubbles::setParams(const Common::String &params) {
00079     Common::StringTokenizer tokenizer(params, "(), ");
00080 
00081     // Example input: GFX_Bubbles( 1, 25, 3, 50, 3, 2, (50, 50, 75))
00082 
00083     int index = 0;
00084     while (!tokenizer.empty()) {
00085         Common::String token = tokenizer.nextToken();
00086         switch (index) {
00087         case 0:
00088             if (token != "GFX_Bubbles") {
00089                 error("Unexpected effect type '%s'", token.c_str());
00090             }
00091             break;
00092         case 1:
00093             _timeBetweenTwoUpdates = CLIP<uint>(strtol(token.c_str(), nullptr, 10), 0, 1000) * 33;
00094             break;
00095         case 2:
00096             _bubbleCount = CLIP<uint>(strtol(token.c_str(), nullptr, 10), 1, 300);
00097             break;
00098         case 3:
00099             _kind = static_cast<Kind>(CLIP<int>(strtol(token.c_str(), nullptr, 10), 1, 3));
00100             break;
00101         case 4:
00102             _sourcePositionRatioX = CLIP<int>(strtol(token.c_str(), nullptr, 10), 0, 100);
00103             break;
00104         case 5:
00105             _maxVerticalSpeed = CLIP<int>(strtol(token.c_str(), nullptr, 10), 1, 5);
00106             break;
00107         case 6:
00108             _maxHorizontalSpeed = CLIP<int>(strtol(token.c_str(), nullptr, 10), 1, 10);
00109             break;
00110         case 7:
00111             _mainColorR = strtol(token.c_str(), nullptr, 10);
00112             break;
00113         case 8:
00114             _mainColorG = strtol(token.c_str(), nullptr, 10);
00115             break;
00116         case 9:
00117             _mainColorB = strtol(token.c_str(), nullptr, 10);
00118             break;
00119         default:
00120             warning("Unexpected parameter %d: %s", index, token.c_str());
00121         }
00122 
00123         index++;
00124     }
00125 
00126     _sourcePosition.x = _size.x * _sourcePositionRatioX / 100;
00127     _sourcePosition.y = _size.y;
00128 
00129     _mainColor = _surface->format.RGBToColor(_mainColorR, _mainColorG, _mainColorB);
00130 
00131     byte darkColorR =  3 * (_mainColorR >> 2);
00132     byte darkColorG =  3 * (_mainColorG >> 2);
00133     byte darkColorB =  3 * (_mainColorB >> 2);
00134     _darkColor = _surface->format.RGBToColor(darkColorR, darkColorG, darkColorB);
00135 
00136     _bubbles.resize(_bubbleCount);
00137     for (uint i = 0; i < _bubbles.size(); i++) {
00138         Bubble &bubble = _bubbles[i];
00139         bubble.position.x = -1;
00140         bubble.position.y = -1;
00141 
00142         if (_kind == kRandom) {
00143             bubble.kind = (StarkRandomSource->getRandomNumber(255) & 3) ? kLarge : kSmall;
00144         } else {
00145             bubble.kind = _kind;
00146         }
00147     }
00148 }
00149 
00150 void VisualEffectBubbles::update() {
00151     for (uint i = 0; i < _bubbles.size(); i++) {
00152         Bubble &bubble = _bubbles[i];
00153 
00154         if (bubble.position.x == -1 && bubble.position.y == -1) {
00155             bubble.position = _sourcePosition;
00156             break;
00157         }
00158 
00159         if (bubble.position.y <= 1) {
00160             bubble.position = _sourcePosition;
00161         } else {
00162             uint deltaUp = StarkRandomSource->getRandomNumberRng(1, _maxVerticalSpeed);
00163             int deltaLeft =  (bubble.position.x > _maxHorizontalSpeed)           * StarkRandomSource->getRandomNumberRng(0, _maxHorizontalSpeed);
00164             int deltaRight = (bubble.position.x < _size.x - _maxHorizontalSpeed) * StarkRandomSource->getRandomNumberRng(0, _maxHorizontalSpeed);
00165 
00166             bubble.position.x += deltaRight - deltaLeft;
00167             bubble.position.y -= deltaUp;
00168         }
00169     }
00170 }
00171 
00172 void VisualEffectBubbles::drawBubble(const Bubble &bubble) const {
00173     if (bubble.position.x == -1 && bubble.position.y == -1) {
00174         return;
00175     }
00176 
00177     if (bubble.kind == kSmall) {
00178         drawSmallBubble(bubble);
00179     } else {
00180         drawLargeBubble(bubble);
00181     }
00182 }
00183 
00184 void VisualEffectBubbles::drawSmallBubble(const Bubble &bubble) const {
00185     if (bubble.position.x < 0 || bubble.position.x >= _surface->w
00186         || bubble.position.y < 0 || bubble.position.y >= _surface->h) {
00187             return;
00188     }
00189 
00190     uint32 *pixel = static_cast<uint32 *>(_surface->getBasePtr(bubble.position.x, bubble.position.y));
00191     *pixel = _mainColor;
00192 }
00193 
00194 void VisualEffectBubbles::drawLargeBubble(const Bubble &bubble) const {
00195     if (bubble.position.x < 1 || bubble.position.x >= _surface->w - 1
00196         || bubble.position.y < 1 || bubble.position.y >= _surface->h - 1) {
00197         return;
00198     }
00199 
00200     uint32 *pixel = static_cast<uint32 *>(_surface->getBasePtr(bubble.position.x, bubble.position.y - 1));
00201     *pixel = _darkColor;
00202 
00203     pixel = static_cast<uint32 *>(_surface->getBasePtr(bubble.position.x - 1, bubble.position.y));
00204     *pixel++ = _darkColor;
00205     *pixel++ = _mainColor;
00206     *pixel = _darkColor;
00207 
00208     pixel = static_cast<uint32 *>(_surface->getBasePtr(bubble.position.x, bubble.position.y + 1));
00209     *pixel = _darkColor;
00210 }
00211 
00212 } // End of namespace Stark


Generated on Sat Jul 13 2019 05:01:14 for ResidualVM by doxygen 1.7.1
curved edge   curved edge