aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorBastien Bouclet2016-08-15 15:16:22 +0200
committerEugene Sandulenko2017-07-03 08:50:10 +0200
commitab2d151541f5d4ae12aeeba6ec5e928109be84f5 (patch)
treea4551255e05de479655a81658702321c1a473b47 /engines
parent85712e56c8e2cf8a6e04110646f4345c153211fd (diff)
downloadscummvm-rg350-ab2d151541f5d4ae12aeeba6ec5e928109be84f5.tar.gz
scummvm-rg350-ab2d151541f5d4ae12aeeba6ec5e928109be84f5.tar.bz2
scummvm-rg350-ab2d151541f5d4ae12aeeba6ec5e928109be84f5.zip
MOHAWK: Implement the (fire)flies effect mainly used in jungle island
Diffstat (limited to 'engines')
-rw-r--r--engines/mohawk/riven.cpp2
-rw-r--r--engines/mohawk/riven_card.cpp1
-rw-r--r--engines/mohawk/riven_external.cpp3
-rw-r--r--engines/mohawk/riven_graphics.cpp463
-rw-r--r--engines/mohawk/riven_graphics.h103
5 files changed, 570 insertions, 2 deletions
diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index 2536b0246f..485d4bb174 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -204,6 +204,7 @@ void MohawkEngine_Riven::handleEvents() {
// Update background running things
checkTimer();
_sound->updateSLST();
+ _gfx->runFliesEffect();
bool needsUpdate = _gfx->runScheduledWaterEffects();
needsUpdate |= _video->updateMovies();
@@ -495,6 +496,7 @@ void MohawkEngine_Riven::delayAndUpdate(uint32 ms) {
while (_system->getMillis() < startTime + ms && !shouldQuit()) {
_sound->updateSLST();
+ _gfx->runFliesEffect();
bool needsUpdate = _gfx->runScheduledWaterEffects();
needsUpdate |= _video->updateMovies();
diff --git a/engines/mohawk/riven_card.cpp b/engines/mohawk/riven_card.cpp
index 4b6feae5ae..894cb4c62a 100644
--- a/engines/mohawk/riven_card.cpp
+++ b/engines/mohawk/riven_card.cpp
@@ -51,6 +51,7 @@ RivenCard::~RivenCard() {
}
_vm->_gfx->clearWaterEffects();
+ _vm->_gfx->clearFliesEffect();
_vm->_video->stopVideos();
}
diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp
index c5426dccf7..3855123c3a 100644
--- a/engines/mohawk/riven_external.cpp
+++ b/engines/mohawk/riven_external.cpp
@@ -2806,8 +2806,7 @@ void RivenExternal::xtatboundary(uint16 argc, uint16 *argv) {
// ------------------------------------------------------------------------------------
void RivenExternal::xflies(uint16 argc, uint16 *argv) {
- // TODO: Activate the "flies" effect
- debug(1, "STUB: xflies(): create %d %s fl%s", argv[1], (argv[0] == 0) ? "black" : "glowing", (argv[1] == 1) ? "y" : "ies");
+ _vm->_gfx->setFliesEffect(argv[1], argv[0] == 1);
}
} // End of namespace Mohawk
diff --git a/engines/mohawk/riven_graphics.cpp b/engines/mohawk/riven_graphics.cpp
index d5cb3536a1..573eddf7d8 100644
--- a/engines/mohawk/riven_graphics.cpp
+++ b/engines/mohawk/riven_graphics.cpp
@@ -57,6 +57,7 @@ RivenGraphics::RivenGraphics(MohawkEngine_Riven* vm) : GraphicsManager(), _vm(vm
_creditsPos = 0;
_transitionSpeed = 0;
+ _fliesEffect = nullptr;
}
RivenGraphics::~RivenGraphics() {
@@ -65,6 +66,7 @@ RivenGraphics::~RivenGraphics() {
_mainScreen->free();
delete _mainScreen;
delete _bitmapDecoder;
+ delete _fliesEffect;
}
MohawkSurface *RivenGraphics::decodeImage(uint16 id) {
@@ -447,4 +449,465 @@ void RivenGraphics::applyScreenUpdate(bool force) {
}
}
+void RivenGraphics::setFliesEffect(uint16 count, bool fireflies) {
+ delete _fliesEffect;
+ _fliesEffect = new FliesEffect(_vm, count, fireflies);
+}
+
+void RivenGraphics::clearFliesEffect() {
+ delete _fliesEffect;
+ _fliesEffect = nullptr;
+}
+
+void RivenGraphics::runFliesEffect() {
+ if (_fliesEffect) {
+ _fliesEffect->update();
+ }
+}
+
+Graphics::Surface *RivenGraphics::getBackScreen() {
+ return _mainScreen;
+}
+
+Graphics::Surface *RivenGraphics::getEffectScreen() {
+ return _effectScreen;
+}
+
+const FliesEffect::FliesEffectData FliesEffect::_firefliesParameters = {
+ true,
+ true,
+ true,
+ true,
+ 3.0,
+ 0.7,
+ 40,
+ 2.0,
+ 1.0,
+ 8447718,
+ 30,
+ 10
+};
+
+const FliesEffect::FliesEffectData FliesEffect::_fliesParameters = {
+ false,
+ false,
+ false,
+ true,
+ 8.0,
+ 3.0,
+ 80,
+ 3.0,
+ 1.0,
+ 661528,
+ 30,
+ 10
+};
+
+FliesEffect::FliesEffect(MohawkEngine_Riven *vm, uint16 count, bool fireflies) :
+ _vm(vm) {
+
+ _effectSurface = _vm->_gfx->getEffectScreen();
+ _backSurface = _vm->_gfx->getBackScreen();
+ _gameRect = Common::Rect(608, 392);
+
+ if (fireflies) {
+ _parameters = &_firefliesParameters;
+ } else {
+ _parameters = &_fliesParameters;
+ }
+
+ _updatePeriodMs = 66;
+ _nextUpdateTime = _vm->_system->getMillis();
+
+ initFlies(count);
+}
+
+FliesEffect::~FliesEffect() {
+
+}
+
+void FliesEffect::initFlies(uint16 count) {
+ _fly.resize(count);
+ for (uint16 i = 0; i < _fly.size(); i++) {
+ initFlyRandomPosition(i);
+ }
+}
+
+void FliesEffect::initFlyRandomPosition(uint index) {
+ int posX = _vm->_rnd->getRandomNumber(_gameRect.right - 3);
+ int posY = _vm->_rnd->getRandomNumber(_gameRect.bottom - 3);
+
+ if (posY < 100) {
+ posY = 100;
+ }
+
+ initFlyAtPosition(index, posX, posY, 15);
+}
+
+int FliesEffect::randomBetween(int min, int max) {
+ return _vm->_rnd->getRandomNumber(max - min) + min;
+}
+
+void FliesEffect::initFlyAtPosition(uint index, int posX, int posY, int posZ) {
+ FliesEffectEntry &fly = _fly[index];
+
+ fly.posX = posX;
+ fly.posXFloat = posX;
+ fly.posY = posY;
+ fly.posYFloat = posY;
+ fly.posZ = posZ;
+ fly.light = true;
+
+ fly.framesTillLightSwitch = randomBetween(_parameters->minFramesLit, _parameters->minFramesLit + _parameters->maxLightDuration);
+
+ fly.hasBlur = false;
+ fly.directionAngleRad = randomBetween(0, 300) / 100.0f;
+ fly.directionAngleRadZ = randomBetween(0, 300) / 100.0f;
+ fly.speed = randomBetween(0, 100) / 100.0f;
+}
+
+void FliesEffect::update() {
+ if (_nextUpdateTime <= _vm->_system->getMillis()) {
+ _nextUpdateTime = _updatePeriodMs + _vm->_system->getMillis();
+
+ updateFlies();
+ draw();
+ updateScreen();
+ }
+}
+
+void FliesEffect::updateFlies() {
+ for (uint i = 0; i < _fly.size(); i++) {
+ updateFlyPosition(i);
+
+ if (_fly[i].posX < 1 || _fly[i].posX > _gameRect.right - 4 || _fly[i].posY > _gameRect.bottom - 4) {
+ initFlyRandomPosition(i);
+ }
+
+ if (_parameters->lightable) {
+ _fly[i].framesTillLightSwitch--;
+
+ if (_fly[i].framesTillLightSwitch <= 0) {
+ _fly[i].light = !_fly[i].light;
+ _fly[i].framesTillLightSwitch = randomBetween(_parameters->minFramesLit, _parameters->minFramesLit + _parameters->maxLightDuration);
+ _fly[i].hasBlur = false;
+ }
+ }
+ }
+}
+
+void FliesEffect::updateFlyPosition(uint index) {
+ FliesEffectEntry &fly = _fly[index];
+
+ if (fly.directionAngleRad > 2.0f * M_PI) {
+ fly.directionAngleRad = fly.directionAngleRad - 2.0f * M_PI;
+ }
+ if (fly.directionAngleRad < 0.0f) {
+ fly.directionAngleRad = fly.directionAngleRad + 2.0f * M_PI;
+ }
+ if (fly.directionAngleRadZ > 2.0f * M_PI) {
+ fly.directionAngleRadZ = fly.directionAngleRadZ - 2.0f * M_PI;
+ }
+ if (fly.directionAngleRadZ < 0.0f) {
+ fly.directionAngleRadZ = fly.directionAngleRadZ + 2.0f * M_PI;
+ }
+ fly.posXFloat += cos(fly.directionAngleRad) * fly.speed;
+ fly.posYFloat += sin(fly.directionAngleRad) * fly.speed;
+ fly.posX = fly.posXFloat;
+ fly.posY = fly.posYFloat;
+ selectAlphaMap(
+ fly.posXFloat - fly.posX >= 0.5,
+ fly.posYFloat - fly.posY >= 0.5,
+ &fly.alphaMap,
+ &fly.width,
+ &fly.height);
+ fly.posZFloat += cos(fly.directionAngleRadZ) * (fly.speed / 2.0f);
+ fly.posZ = fly.posZFloat;
+ if (_parameters->canBlur && fly.speed > _parameters->blurSpeedTreshold) {
+ fly.hasBlur = true;
+ float blurPosXFloat = cos(fly.directionAngleRad + M_PI) * _parameters->blurDistance + fly.posXFloat;
+ float blurPosYFloat = sin(fly.directionAngleRad + M_PI) * _parameters->blurDistance + fly.posYFloat;
+
+ fly.blurPosX = blurPosXFloat;
+ fly.blurPosY = blurPosYFloat;
+ selectAlphaMap(
+ blurPosXFloat - fly.blurPosX >= 0.5,
+ blurPosYFloat - fly.blurPosY >= 0.5,
+ &fly.blurAlphaMap,
+ &fly.blurWidth,
+ &fly.blurHeight);
+ }
+ if (fly.posY >= 100) {
+ int maxAngularSpeed = _parameters->maxAcceleration;
+ if (fly.posZ > 15) {
+ maxAngularSpeed /= 2;
+ }
+ int angularSpeed = randomBetween(-maxAngularSpeed, maxAngularSpeed);
+ fly.directionAngleRad += angularSpeed / 100.0f;
+ } else {
+ // Make the flies go down if they are too high in the screen
+ int angularSpeed = randomBetween(0, 50);
+ if (fly.directionAngleRad >= M_PI / 2.0f && fly.directionAngleRad <= 3.0f * M_PI / 2.0f) {
+ // Going down
+ fly.directionAngleRad -= angularSpeed / 100.0f;
+ } else {
+ // Going up
+ fly.directionAngleRad += angularSpeed / 100.0f;
+ }
+ if (fly.posY < 1) {
+ initFlyRandomPosition(index);
+ }
+ }
+ if (fly.posZ >= 0) {
+ int distanceToScreenEdge;
+ if (fly.posX / 10 >= (_gameRect.right - fly.posX) / 10) {
+ distanceToScreenEdge = (_gameRect.right - fly.posX) / 10;
+ } else {
+ distanceToScreenEdge = fly.posX / 10;
+ }
+ if (distanceToScreenEdge > (_gameRect.bottom - fly.posY) / 10) {
+ distanceToScreenEdge = (_gameRect.bottom - fly.posY) / 10;
+ }
+ if (distanceToScreenEdge > 30) {
+ distanceToScreenEdge = 30;
+ }
+ if (fly.posZ <= distanceToScreenEdge) {
+ fly.directionAngleRadZ += randomBetween(-_parameters->maxAcceleration, _parameters->maxAcceleration) / 100.0f;
+ } else {
+ fly.posZ = distanceToScreenEdge;
+ fly.directionAngleRadZ += M_PI;
+ }
+ } else {
+ fly.posZ = 0;
+ fly.directionAngleRadZ += M_PI;
+ }
+ float minSpeed = _parameters->minSpeed - fly.posZ / 40.0f;
+ float maxSpeed = _parameters->maxSpeed - fly.posZ / 20.0f;
+ fly.speed += randomBetween(-_parameters->maxAcceleration, _parameters->maxAcceleration) / 100.0f;
+ if (fly.speed > maxSpeed) {
+ fly.speed -= randomBetween(0, 50) / 100.0f;
+ }
+ if (fly.speed < minSpeed) {
+ fly.speed += randomBetween(0, 50) / 100.0f;
+ }
+}
+
+void FliesEffect::selectAlphaMap(bool horGridOffset, bool vertGridoffset, const uint16 **alphaMap, uint *width, uint *height) {
+ static const uint16 alpha1[12] = {
+ 8, 16, 8,
+ 16, 32, 16,
+ 8, 16, 8,
+ 0, 0, 0
+ };
+
+ static const uint16 alpha2[12] = {
+ 4, 12, 12, 4,
+ 8, 24, 24, 8,
+ 4, 12, 12, 4
+ };
+
+ static const uint16 alpha3[12] = {
+ 4, 8, 4,
+ 12, 24, 12,
+ 12, 24, 12,
+ 4, 8, 4
+ };
+
+ static const uint16 alpha4[16] = {
+ 2, 6, 6, 2,
+ 6, 18, 18, 6,
+ 6, 18, 18, 6,
+ 2, 6, 6, 2
+ };
+
+ static const uint16 alpha5[12] = {
+ 4, 8, 4,
+ 8, 32, 8,
+ 4, 8, 4,
+ 0, 0, 0
+ };
+
+ static const uint16 alpha6[12] = {
+ 2, 6, 6, 2,
+ 4, 24, 24, 4,
+ 2, 6, 6, 2
+ };
+
+ static const uint16 alpha7[12] = {
+ 2, 4, 2,
+ 6, 24, 6,
+ 6, 24, 6,
+ 2, 4, 2
+ };
+
+ static const uint16 alpha8[16] = {
+ 1, 3, 3, 1,
+ 3, 18, 18, 3,
+ 3, 18, 18, 3,
+ 1, 3, 3, 1
+ };
+
+ struct AlphaMap {
+ bool horizontalGridOffset;
+ bool verticalGridOffset;
+ bool isLarge;
+ uint16 width;
+ uint16 height;
+ const uint16 *pixels;
+ };
+
+ static const AlphaMap alphaSelector[] = {
+ { true, true, true, 4, 4, alpha4 },
+ { true, true, false, 4, 4, alpha8 },
+ { true, false, true, 4, 3, alpha2 },
+ { true, false, false, 4, 3, alpha6 },
+ { false, true, true, 3, 4, alpha3 },
+ { false, true, false, 3, 4, alpha7 },
+ { false, false, true, 3, 3, alpha1 },
+ { false, false, false, 3, 3, alpha5 }
+ };
+
+ for (uint i = 0; i < ARRAYSIZE(alphaSelector); i++) {
+ if (alphaSelector[i].horizontalGridOffset == horGridOffset
+ && alphaSelector[i].verticalGridOffset == vertGridoffset
+ && alphaSelector[i].isLarge == _parameters->isLarge) {
+ *alphaMap = alphaSelector[i].pixels;
+ *width = alphaSelector[i].width;
+ *height = alphaSelector[i].height;
+ return;
+ }
+ }
+
+ error("Unknown flies alpha map case");
+}
+
+void FliesEffect::draw() {
+ const Graphics::PixelFormat format = _effectSurface->format;
+
+ for (uint i = 0; i < _fly.size(); i++) {
+ FliesEffectEntry &fly = _fly[i];
+ uint32 color = _parameters->color32;
+ if (!fly.light) {
+ color = _fliesParameters.color32;
+ }
+
+ bool hoveringBrightBackground = false;
+ for (uint y = 0; y < fly.height; y++) {
+ uint16 *pixel = (uint16 *) _effectSurface->getBasePtr(fly.posX, fly.posY + y);
+
+ for (uint x = 0; x < fly.width; x++) {
+ byte r, g, b;
+ format.colorToRGB(*pixel, r, g, b);
+
+ if (_parameters->unlightIfTooBright) {
+ if (r >= 192 || g >= 192 || b >= 192) {
+ hoveringBrightBackground = true;
+ }
+ }
+ colorBlending(color, r, g, b, fly.alphaMap[fly.width * y + x] - fly.posZ);
+
+ *pixel = format.RGBToColor(r, g, b);
+ ++pixel;
+ }
+ }
+
+ Common::Rect drawRect = Common::Rect(fly.width, fly.height);
+ drawRect.translate(fly.posX, fly.posY);
+ addToScreenDirtyRects(drawRect);
+ addToEffectsDirtyRects(drawRect);
+
+ if (fly.hasBlur) {
+ for (uint y = 0; y < fly.blurHeight; y++) {
+ uint16 *pixel = (uint16 *) _effectSurface->getBasePtr(fly.blurPosX, fly.blurPosY + y);
+ for (uint x = 0; x < fly.blurWidth; x++) {
+ byte r, g, b;
+ format.colorToRGB(*pixel, r, g, b);
+
+ colorBlending(color, r, g, b, fly.blurAlphaMap[fly.blurWidth * y + x] - fly.posZ);
+
+ *pixel = format.RGBToColor(r, g, b);
+ ++pixel;
+ }
+ }
+
+ Common::Rect drawRect2 = Common::Rect(fly.blurWidth, fly.blurHeight);
+ drawRect2.translate(fly.blurPosX, fly.blurPosY);
+ addToScreenDirtyRects(drawRect2);
+ addToEffectsDirtyRects(drawRect2);
+
+ fly.hasBlur = false;
+ }
+
+ if (hoveringBrightBackground) {
+ fly.hasBlur = false;
+ if (_parameters->lightable) {
+ fly.light = false;
+ fly.framesTillLightSwitch = randomBetween(_parameters->minFramesLit, _parameters->minFramesLit + _parameters->maxLightDuration);
+ }
+
+ if (_vm->_rnd->getRandomBit()) {
+ fly.directionAngleRad += M_PI / 2.0;
+ } else {
+ fly.directionAngleRad -= M_PI / 2.0;
+ }
+ }
+ }
+}
+
+void FliesEffect::colorBlending(uint32 flyColor, byte &r, byte &g, byte &b, int alpha) {
+ alpha = CLIP(alpha, 0, 32);
+ byte flyR = (flyColor & 0x000000FF) >> 0;
+ byte flyG = (flyColor & 0x0000FF00) >> 8;
+ byte flyB = (flyColor & 0x00FF0000) >> 16;
+
+ r = (32 * r + alpha * (flyR - r)) / 32;
+ g = (32 * g + alpha * (flyG - g)) / 32;
+ b = (32 * b + alpha * (flyB - b)) / 32;
+}
+
+void FliesEffect::updateScreen() {
+ for (uint i = 0; i < _screenSurfaceDirtyRects.size(); i++) {
+ const Common::Rect &rect = _screenSurfaceDirtyRects[i];
+ _vm->_system->copyRectToScreen(_effectSurface->getBasePtr(rect.left, rect.top),
+ _effectSurface->pitch, rect.left, rect.top,
+ rect.width(), rect.height()
+ );
+ }
+ _screenSurfaceDirtyRects.clear();
+
+ restoreEffectsSurface();
+}
+
+void FliesEffect::addToScreenDirtyRects(const Common::Rect &rect) {
+ for (uint i = 0; i < _screenSurfaceDirtyRects.size(); i++) {
+ if (rect.intersects(_screenSurfaceDirtyRects[i])) {
+ _screenSurfaceDirtyRects[i].extend(rect);
+ return;
+ }
+ }
+
+ _screenSurfaceDirtyRects.push_back(rect);
+}
+
+void FliesEffect::addToEffectsDirtyRects(const Common::Rect &rect) {
+ for (uint i = 0; i < _effectsSurfaceDirtyRects.size(); i++) {
+ if (rect.intersects(_effectsSurfaceDirtyRects[i])) {
+ _effectsSurfaceDirtyRects[i].extend(rect);
+ return;
+ }
+ }
+
+ _effectsSurfaceDirtyRects.push_back(rect);
+}
+
+void FliesEffect::restoreEffectsSurface() {
+ for (uint i = 0; i < _effectsSurfaceDirtyRects.size(); i++) {
+ const Common::Rect &rect = _effectsSurfaceDirtyRects[i];
+ _effectSurface->copyRectToSurface(*_backSurface, rect.left, rect.top, rect);
+ addToScreenDirtyRects(rect);
+ }
+
+ _effectsSurfaceDirtyRects.clear();
+}
+
} // End of namespace Mohawk
diff --git a/engines/mohawk/riven_graphics.h b/engines/mohawk/riven_graphics.h
index 2802c8402e..8120879310 100644
--- a/engines/mohawk/riven_graphics.h
+++ b/engines/mohawk/riven_graphics.h
@@ -28,6 +28,7 @@
namespace Mohawk {
class MohawkEngine_Riven;
+class FliesEffect;
class RivenGraphics : public GraphicsManager {
public:
@@ -44,11 +45,19 @@ public:
void drawImageRect(uint16 id, Common::Rect srcRect, Common::Rect dstRect);
void drawExtrasImage(uint16 id, Common::Rect dstRect);
+ Graphics::Surface *getEffectScreen();
+ Graphics::Surface *getBackScreen();
+
// Water Effect
void scheduleWaterEffect(uint16);
void clearWaterEffects();
bool runScheduledWaterEffects();
+ // Flies Effect
+ void setFliesEffect(uint16 count, bool fireflies);
+ void clearFliesEffect();
+ void runFliesEffect();
+
// Transitions
void scheduleTransition(uint16 id, Common::Rect rect = Common::Rect(0, 0, 608, 392));
void runScheduledTransition();
@@ -88,6 +97,9 @@ private:
};
Common::Array<SFXERecord> _waterEffects;
+ // Flies Effect
+ FliesEffect *_fliesEffect;
+
// Transitions
int16 _scheduledTransition;
Common::Rect _transitionRect;
@@ -102,6 +114,7 @@ private:
Graphics::Surface *_mainScreen;
Graphics::Surface *_effectScreen;
bool _dirtyScreen;
+
Graphics::PixelFormat _pixelFormat;
void clearMainScreen();
@@ -109,6 +122,96 @@ private:
uint _creditsImage, _creditsPos;
};
+/**
+ * The flies effect draws flies in the scene
+ *
+ * It can draw either regular flies or fireflies.
+ * The flies' movement is simulated in 3 dimensions.
+ */
+class FliesEffect {
+public:
+ FliesEffect(MohawkEngine_Riven *vm, uint16 count, bool fireflies);
+ ~FliesEffect();
+
+ /** Simulate the flies' movement and draw them to the screen */
+ void update();
+
+private:
+ struct FliesEffectEntry {
+ bool light;
+ int posX;
+ int posY;
+ int posZ;
+ const uint16 *alphaMap;
+ uint width;
+ uint height;
+ int framesTillLightSwitch;
+ bool hasBlur;
+ int blurPosX;
+ int blurPosY;
+ const uint16 *blurAlphaMap;
+ uint blurWidth;
+ uint blurHeight;
+ float posXFloat;
+ float posYFloat;
+ float posZFloat;
+ float directionAngleRad;
+ float directionAngleRadZ;
+ float speed;
+ };
+
+ struct FliesEffectData {
+ bool lightable;
+ bool unlightIfTooBright;
+ bool isLarge;
+ bool canBlur;
+ float maxSpeed;
+ float minSpeed;
+ int maxAcceleration;
+ float blurSpeedTreshold;
+ float blurDistance;
+ uint32 color32;
+ int minFramesLit;
+ int maxLightDuration;
+ };
+
+ MohawkEngine_Riven *_vm;
+
+ uint _nextUpdateTime;
+ int _updatePeriodMs;
+
+ Common::Rect _gameRect;
+ Graphics::Surface *_effectSurface;
+ Graphics::Surface *_backSurface;
+ Common::Array<Common::Rect> _screenSurfaceDirtyRects;
+ Common::Array<Common::Rect> _effectsSurfaceDirtyRects;
+
+ const FliesEffectData *_parameters;
+ static const FliesEffectData _firefliesParameters;
+ static const FliesEffectData _fliesParameters;
+
+ Common::Array<FliesEffectEntry> _fly;
+
+ void initFlies(uint16 count);
+ void initFlyRandomPosition(uint index);
+ void initFlyAtPosition(uint index, int posX, int posY, int posZ);
+
+ void updateFlies();
+ void updateFlyPosition(uint index);
+
+ void draw();
+ void updateScreen();
+
+ void selectAlphaMap(bool horGridOffset, bool vertGridoffset, const uint16 **alphaMap, uint *width, uint *height);
+ void colorBlending(uint32 flyColor, byte &r, byte &g, byte &b, int alpha);
+
+ void addToScreenDirtyRects(const Common::Rect &rect);
+ void addToEffectsDirtyRects(const Common::Rect &rect);
+ void restoreEffectsSurface();
+
+ int randomBetween(int min, int max);
+};
+
} // End of namespace Mohawk
#endif