aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/zvision/graphics/effect.h83
-rw-r--r--engines/zvision/graphics/effects/fog.cpp174
-rw-r--r--engines/zvision/graphics/effects/fog.h52
-rw-r--r--engines/zvision/graphics/effects/light.cpp110
-rw-r--r--engines/zvision/graphics/effects/light.h53
-rw-r--r--engines/zvision/graphics/effects/wave.cpp146
-rw-r--r--engines/zvision/graphics/effects/wave.h51
-rw-r--r--engines/zvision/graphics/render_manager.cpp218
-rw-r--r--engines/zvision/graphics/render_manager.h14
-rw-r--r--engines/zvision/module.mk4
-rw-r--r--engines/zvision/scripting/actions.cpp80
-rw-r--r--engines/zvision/scripting/actions.h16
-rw-r--r--engines/zvision/scripting/scr_file_handling.cpp2
-rw-r--r--engines/zvision/scripting/script_manager.h4
-rw-r--r--engines/zvision/scripting/sidefx/region_node.cpp56
-rw-r--r--engines/zvision/scripting/sidefx/region_node.h57
16 files changed, 1115 insertions, 5 deletions
diff --git a/engines/zvision/graphics/effect.h b/engines/zvision/graphics/effect.h
new file mode 100644
index 0000000000..c6653c6037
--- /dev/null
+++ b/engines/zvision/graphics/effect.h
@@ -0,0 +1,83 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef EFFECT_H_INCLUDED
+#define EFFECT_H_INCLUDED
+
+#include "common/rect.h"
+#include "common/list.h"
+#include "graphics/surface.h"
+
+#include "zvision/zvision.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class Effect {
+public:
+
+ Effect(ZVision *engine, uint32 key, Common::Rect region, bool ported) : _engine(engine), _key(key), _region(region), _ported(ported) {
+ _surface.create(_region.width(), _region.height(), _engine->_pixelFormat);
+ }
+ virtual ~Effect() {}
+
+ uint32 getKey() {
+ return _key;
+ }
+
+ Common::Rect getRegion() {
+ return _region;
+ }
+
+ bool isPort() {
+ return _ported;
+ }
+
+ virtual const Graphics::Surface *draw(const Graphics::Surface &srcSubRect) {
+ return &_surface;
+ }
+
+ virtual void update() {}
+
+protected:
+ ZVision *_engine;
+ uint32 _key;
+ Common::Rect _region;
+ bool _ported;
+ Graphics::Surface _surface;
+
+// Static member functions
+public:
+
+};
+
+struct EffectMapUnit {
+ uint32 count;
+ bool inEffect;
+};
+
+typedef Common::List<EffectMapUnit> EffectMap;
+
+} // End of namespace ZVision
+
+#endif // EFFECT_H_INCLUDED
diff --git a/engines/zvision/graphics/effects/fog.cpp b/engines/zvision/graphics/effects/fog.cpp
new file mode 100644
index 0000000000..b6c5e7b011
--- /dev/null
+++ b/engines/zvision/graphics/effects/fog.cpp
@@ -0,0 +1,174 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/graphics/effects/fog.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/scripting/script_manager.h"
+
+
+namespace ZVision {
+
+FogFx::FogFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, EffectMap *Map, const Common::String &clouds):
+ Effect(engine, key, region, ported) {
+
+ _map = Map;
+
+ _r = 0;
+ _g = 0;
+ _b = 0;
+
+ _pos = 0;
+
+ if (_engine->getSearchManager()->hasFile(clouds))
+ _engine->getRenderManager()->readImageToSurface(clouds, _fog);
+ else
+ _engine->getRenderManager()->readImageToSurface("cloud.tga", _fog);
+
+ _mp.resize(_fog.h);
+ for (int16 i = 0; i < _fog.h; i++) {
+ _mp[i].resize(_fog.w);
+ for (int16 j = 0; j < _fog.w; j++)
+ _mp[i][j] = true;
+ }
+
+ for (uint8 i = 0; i < 32; i++)
+ _colorMap[i] = 0;
+}
+
+FogFx::~FogFx() {
+ if (_map)
+ delete _map;
+
+ for (uint16 i = 0; i < _mp.size(); i++)
+ _mp[i].clear();
+ _mp.clear();
+}
+
+const Graphics::Surface *FogFx::draw(const Graphics::Surface &srcSubRect) {
+ _surface.copyFrom(srcSubRect);
+ EffectMap::iterator it = _map->begin();
+
+ uint32 cnt = 0;
+
+ for (uint16 j = 0; j < _surface.h; j++) {
+ uint16 *lineBuf = (uint16 *)_surface.getBasePtr(0, j);
+
+ for (uint16 i = 0; i < _surface.w; i++) {
+ if (it->inEffect) {
+ // Not 100% equivalent, but looks nice and not buggy
+ uint8 sr, sg, sb;
+ _engine->_pixelFormat.colorToRGB(lineBuf[i], sr, sg, sb);
+ uint16 fogColor = *(uint16 *)_fog.getBasePtr((i + _pos) % _fog.w, j);
+ uint8 dr, dg, db;
+ _engine->_pixelFormat.colorToRGB(_colorMap[fogColor & 0x1F], dr, dg, db);
+ uint16 fr = dr + sr;
+ if (fr > 255)
+ fr = 255;
+ uint16 fg = dg + sg;
+ if (fg > 255)
+ fg = 255;
+ uint16 fb = db + sb;
+ if (fb > 255)
+ fb = 255;
+ lineBuf[i] = _engine->_pixelFormat.RGBToColor(fr, fg, fb);
+ }
+ cnt++;
+ if (cnt >= it->count) {
+ it++;
+ cnt = 0;
+ }
+ if (it == _map->end())
+ break;
+ }
+ if (it == _map->end())
+ break;
+ }
+
+ return &_surface;
+}
+
+void FogFx::update() {
+ _pos += _engine->getScriptManager()->getStateValue(StateKey_EF9_Speed);
+ _pos %= _fog.w;
+
+ uint8 dr = _engine->getScriptManager()->getStateValue(StateKey_EF9_R);
+ uint8 dg = _engine->getScriptManager()->getStateValue(StateKey_EF9_G);
+ uint8 db = _engine->getScriptManager()->getStateValue(StateKey_EF9_B);
+ dr = CLIP((int)dr, 0, 31);
+ dg = CLIP((int)dg, 0, 31);
+ db = CLIP((int)db, 0, 31);
+
+ if (dr != _r || dg != _g || db != _b) {
+ if (_r > dr)
+ _r--;
+ else if (_r < dr)
+ _r++;
+
+ if (_g > dg)
+ _g--;
+ else if (_g < dg)
+ _g++;
+
+ if (_b > db)
+ _b--;
+ else if (_b < db)
+ _b++;
+
+ // Not 100% equivalent, but looks nice and not buggy
+
+ _colorMap[31] = _engine->_pixelFormat.RGBToColor(_r << 3, _g << 3, _b << 3);
+
+ for (uint8 i = 0; i < 31; i++) {
+ float perc = (float)i / 31.0;
+ uint8 cr = (float)_r * perc;
+ uint8 cg = (float)_g * perc;
+ uint8 cb = (float)_b * perc;
+ _colorMap[i] = _engine->_pixelFormat.RGBToColor(cr << 3, cg << 3, cb << 3);
+ }
+ }
+
+ for (uint16 j = 0; j < _fog.h; j++) {
+ uint16 *pix = (uint16 *)_fog.getBasePtr(0, j);
+
+ for (uint16 i = 0; i < _fog.w; i++) {
+ if (_mp[j][i]) {
+ if ((pix[i] & 0x1F) == 0x1F) {
+ pix[i]--;
+ _mp[j][i] = false;
+ } else
+ pix[i]++;
+ } else {
+ if ((pix[i] & 0x1F) == 0) {
+ pix[i]++;
+ _mp[j][i] = true;
+ } else
+ pix[i]--;
+ }
+ }
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/graphics/effects/fog.h b/engines/zvision/graphics/effects/fog.h
new file mode 100644
index 0000000000..62dd1f9473
--- /dev/null
+++ b/engines/zvision/graphics/effects/fog.h
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FOGFX_H_INCLUDED
+#define FOGFX_H_INCLUDED
+
+#include "zvision/graphics/effect.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class FogFx : public Effect {
+public:
+
+ FogFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, EffectMap *Map, const Common::String &clouds);
+ ~FogFx();
+
+ const Graphics::Surface *draw(const Graphics::Surface &srcSubRect);
+
+ void update();
+
+private:
+ EffectMap *_map;
+ Graphics::Surface _fog;
+ uint8 _r, _g, _b;
+ int32 _pos;
+ Common::Array< Common::Array< bool > > _mp;
+ uint16 _colorMap[32];
+};
+} // End of namespace ZVision
+
+#endif // FOGFX_H_INCLUDED
diff --git a/engines/zvision/graphics/effects/light.cpp b/engines/zvision/graphics/effects/light.cpp
new file mode 100644
index 0000000000..9bff077051
--- /dev/null
+++ b/engines/zvision/graphics/effects/light.cpp
@@ -0,0 +1,110 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/graphics/effects/light.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+
+
+namespace ZVision {
+
+LightFx::LightFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, EffectMap *Map, int8 delta, int8 minD, int8 maxD):
+ Effect(engine, key, region, ported) {
+ _map = Map;
+ _delta = delta;
+ _up = true;
+ _pos = 0;
+
+ _minD = minD;
+ if (_minD < -delta)
+ _minD = -delta;
+
+ _maxD = maxD;
+ if (_maxD > delta)
+ _maxD = delta;
+}
+
+LightFx::~LightFx() {
+ if (_map)
+ delete _map;
+}
+
+const Graphics::Surface *LightFx::draw(const Graphics::Surface &srcSubRect) {
+ _surface.copyFrom(srcSubRect);
+ EffectMap::iterator it = _map->begin();
+ uint32 cnt = 0;
+
+ uint32 dcolor = 0;
+
+ if (_pos < 0) {
+ uint8 cc = ((-_pos) & 0x1F) << 3;
+ dcolor = _engine->_pixelFormat.RGBToColor(cc, cc, cc);
+ } else {
+ uint8 cc = (_pos & 0x1F) << 3;
+ dcolor = _engine->_pixelFormat.RGBToColor(cc, cc, cc);
+ }
+
+ for (uint16 j = 0; j < _surface.h; j++) {
+ uint16 *lineBuf = (uint16 *)_surface.getBasePtr(0, j);
+
+ for (uint16 i = 0; i < _surface.w; i++) {
+ if (it->inEffect) {
+ if (_pos < 0) {
+ lineBuf[i] -= dcolor;
+ } else {
+ lineBuf[i] += dcolor;
+ }
+ }
+ cnt++;
+ if (cnt >= it->count) {
+ it++;
+ cnt = 0;
+ }
+ if (it == _map->end())
+ break;
+ }
+ if (it == _map->end())
+ break;
+ }
+
+ return &_surface;
+}
+
+void LightFx::update() {
+ if (_up)
+ _pos++;
+ else
+ _pos--;
+
+ if (_pos <= _minD) {
+ _up = !_up;
+ _pos = _minD;
+ } else if (_pos >= _maxD) {
+ _up = !_up;
+ _pos = _maxD;
+ }
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/graphics/effects/light.h b/engines/zvision/graphics/effects/light.h
new file mode 100644
index 0000000000..ae87d66cb3
--- /dev/null
+++ b/engines/zvision/graphics/effects/light.h
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LIGHTFX_H_INCLUDED
+#define LIGHTFX_H_INCLUDED
+
+#include "zvision/graphics/effect.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class LightFx : public Effect {
+public:
+
+ LightFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, EffectMap *Map, int8 delta, int8 minD = -127, int8 maxD = 127);
+ ~LightFx();
+
+ const Graphics::Surface *draw(const Graphics::Surface &srcSubRect);
+
+ void update();
+
+private:
+ EffectMap *_map;
+ int32 _delta;
+ bool _up;
+ int32 _pos;
+
+ int8 _minD;
+ int8 _maxD;
+};
+} // End of namespace ZVision
+
+#endif // LIGHTFX_H_INCLUDED
diff --git a/engines/zvision/graphics/effects/wave.cpp b/engines/zvision/graphics/effects/wave.cpp
new file mode 100644
index 0000000000..88239f3cad
--- /dev/null
+++ b/engines/zvision/graphics/effects/wave.cpp
@@ -0,0 +1,146 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/graphics/effects/wave.h"
+
+#include "zvision/zvision.h"
+#include "zvision/graphics/render_manager.h"
+
+
+namespace ZVision {
+
+WaveFx::WaveFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, int16 frames, int16 s_x, int16 s_y, float ampl, float waveln, float spd):
+ Effect(engine, key, region, ported) {
+
+ _frame = 0;
+ _frame_cnt = frames;
+
+ _ampls.resize(_frame_cnt);
+ _hw = _region.width() / 2;
+ _hh = _region.height() / 2;
+
+ int32 frmsize = _hw * _hh;
+
+ float phase = 0;
+
+ int16 w_4 = _hw / 2;
+ int16 h_4 = _hh / 2;
+
+ for (int16 i = 0; i < _frame_cnt; i++) {
+ _ampls[i].resize(frmsize);
+
+ for (int16 y = 0; y < _hh; y++)
+ for (int16 x = 0; x < _hw; x++) {
+ int16 dx = (x - w_4);
+ int16 dy = (y - h_4);
+
+ _ampls[i][x + y * _hw] = ampl * sin(sqrt(dx * dx / (float)s_x + dy * dy / (float)s_y) / (-waveln * 3.1415926) + phase);
+ }
+ phase += spd;
+ }
+}
+
+WaveFx::~WaveFx() {
+ for (uint16 i = 0; i < _ampls.size(); i++)
+ _ampls[i].clear();
+ _ampls.clear();
+}
+
+const Graphics::Surface *WaveFx::draw(const Graphics::Surface &srcSubRect) {
+ for (int16 y = 0; y < _hh; y++) {
+ uint16 *abc = (uint16 *)_surface.getBasePtr(0, y);
+ uint16 *abc2 = (uint16 *)_surface.getBasePtr(0, _hh + y);
+ uint16 *abc3 = (uint16 *)_surface.getBasePtr(_hw, y);
+ uint16 *abc4 = (uint16 *)_surface.getBasePtr(_hw, _hh + y);
+
+ for (int16 x = 0; x < _hw; x++) {
+ int8 amnt = _ampls[_frame][x + _hw * y];
+
+ int16 n_x = x + amnt;
+ int16 n_y = y + amnt;
+
+ if (n_x < 0)
+ n_x = 0;
+ if (n_x >= _region.width())
+ n_x = _region.width() - 1;
+ if (n_y < 0)
+ n_y = 0;
+ if (n_y >= _region.height())
+ n_y = _region.height() - 1;
+ *abc = *(const uint16 *)srcSubRect.getBasePtr(n_x, n_y);
+
+ n_x = x + amnt + _hw;
+ n_y = y + amnt;
+
+ if (n_x < 0)
+ n_x = 0;
+ if (n_x >= _region.width())
+ n_x = _region.width() - 1;
+ if (n_y < 0)
+ n_y = 0;
+ if (n_y >= _region.height())
+ n_y = _region.height() - 1;
+ *abc3 = *(const uint16 *)srcSubRect.getBasePtr(n_x, n_y);
+
+ n_x = x + amnt;
+ n_y = y + amnt + _hh;
+
+ if (n_x < 0)
+ n_x = 0;
+ if (n_x >= _region.width())
+ n_x = _region.width() - 1;
+ if (n_y < 0)
+ n_y = 0;
+ if (n_y >= _region.height())
+ n_y = _region.height() - 1;
+ *abc2 = *(const uint16 *)srcSubRect.getBasePtr(n_x, n_y);
+
+ n_x = x + amnt + _hw;
+ n_y = y + amnt + _hh;
+
+ if (n_x < 0)
+ n_x = 0;
+ if (n_x >= _region.width())
+ n_x = _region.width() - 1;
+ if (n_y < 0)
+ n_y = 0;
+ if (n_y >= _region.height())
+ n_y = _region.height() - 1;
+ *abc4 = *(const uint16 *)srcSubRect.getBasePtr(n_x, n_y);
+
+ abc++;
+ abc2++;
+ abc3++;
+ abc4++;
+ }
+ }
+
+ return &_surface;
+}
+
+void WaveFx::update() {
+ _frame = (_frame + 1) % _frame_cnt;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/graphics/effects/wave.h b/engines/zvision/graphics/effects/wave.h
new file mode 100644
index 0000000000..0046dfceec
--- /dev/null
+++ b/engines/zvision/graphics/effects/wave.h
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef WAVEFX_H_INCLUDED
+#define WAVEFX_H_INCLUDED
+
+#include "common/array.h"
+#include "zvision/graphics/effect.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class WaveFx : public Effect {
+public:
+
+ WaveFx(ZVision *engine, uint32 key, Common::Rect region, bool ported, int16 frames, int16 s_x, int16 s_y, float ampl, float waveln, float spd);
+ ~WaveFx();
+
+ const Graphics::Surface *draw(const Graphics::Surface &srcSubRect);
+
+ void update();
+
+private:
+ int16 _frame;
+ int16 _frame_cnt;
+ int16 _hw, _hh;
+ Common::Array< Common::Array< int8 > > _ampls;
+};
+} // End of namespace ZVision
+
+#endif // WAVEFX_H_INCLUDED
diff --git a/engines/zvision/graphics/render_manager.cpp b/engines/zvision/graphics/render_manager.cpp
index 5aa0d752d0..0aa062214f 100644
--- a/engines/zvision/graphics/render_manager.cpp
+++ b/engines/zvision/graphics/render_manager.cpp
@@ -54,6 +54,7 @@ RenderManager::RenderManager(ZVision *engine, uint32 windowWidth, uint32 windowH
_renderTable(_wrkWidth, _wrkHeight) {
_wrkWnd.create(_wrkWidth, _wrkHeight, _pixelFormat);
+ _effectWnd.create(_wrkWidth, _wrkHeight, _pixelFormat);
_outWnd.create(_wrkWidth, _wrkHeight, _pixelFormat);
_menuWnd.create(windowWidth, workingWindow.top, _pixelFormat);
_subWnd.create(windowWidth, windowHeight - workingWindow.bottom, _pixelFormat);
@@ -67,21 +68,55 @@ RenderManager::RenderManager(ZVision *engine, uint32 windowWidth, uint32 windowH
RenderManager::~RenderManager() {
_curBkg.free();
_wrkWnd.free();
+ _effectWnd.free();
_outWnd.free();
+ _menuWnd.free();
+ _subWnd.free();
}
void RenderManager::renderBackbufferToScreen() {
Graphics::Surface *out = &_outWnd;
+ Graphics::Surface *in = &_wrkWnd;
+
+ if (!_effects.empty()) {
+ bool copied = false;
+ Common::Rect windRect(_wrkWidth, _wrkHeight);
+ for (effectsList::iterator it = _effects.begin(); it != _effects.end(); it++) {
+ Common::Rect rect = (*it)->getRegion();
+ Common::Rect scrPlace = rect;
+ if ((*it)->isPort())
+ scrPlace = bkgRectToScreen(scrPlace);
+ if (windRect.intersects(scrPlace)) {
+ if (!copied) {
+ copied = true;
+ _effectWnd.copyFrom(_wrkWnd);
+ in = &_effectWnd;
+ }
+ const Graphics::Surface *post;
+ if ((*it)->isPort())
+ post = (*it)->draw(_curBkg.getSubArea(rect));
+ else
+ post = (*it)->draw(_effectWnd.getSubArea(rect));
+ blitSurfaceToSurface(*post, _effectWnd, scrPlace.left, scrPlace.top);
+ scrPlace.clip(windRect);
+ if (_wrkWndDirtyRect .isEmpty()) {
+ _wrkWndDirtyRect = scrPlace;
+ } else {
+ _wrkWndDirtyRect.extend(scrPlace);
+ }
+ }
+ }
+ }
RenderTable::RenderState state = _renderTable.getRenderState();
if (state == RenderTable::PANORAMA || state == RenderTable::TILT) {
if (!_wrkWndDirtyRect.isEmpty()) {
- _renderTable.mutateImage(&_outWnd, &_wrkWnd);
+ _renderTable.mutateImage(&_outWnd, in);
out = &_outWnd;
_outWndDirtyRect = Common::Rect(_wrkWidth, _wrkHeight);
}
} else {
- out = &_wrkWnd;
+ out = in;
_outWndDirtyRect = _wrkWndDirtyRect;
}
@@ -832,4 +867,183 @@ Common::Point RenderManager::getBkgSize() {
return Common::Point(_bkgWidth, _bkgHeight);
}
+void RenderManager::addEffect(Effect *_effect) {
+ _effects.push_back(_effect);
+}
+
+void RenderManager::deleteEffect(uint32 ID) {
+ for (effectsList::iterator it = _effects.begin(); it != _effects.end(); it++) {
+ if ((*it)->getKey() == ID) {
+ delete *it;
+ it = _effects.erase(it);
+ }
+ }
+}
+
+Common::Rect RenderManager::bkgRectToScreen(const Common::Rect &src) {
+ Common::Rect tmp = src;
+ RenderTable::RenderState state = _renderTable.getRenderState();
+
+ if (state == RenderTable::PANORAMA) {
+ if (_bkgOff < _screenCenterX) {
+ Common::Rect rScreen(_screenCenterX + _bkgOff, _wrkHeight);
+ Common::Rect lScreen(_wrkWidth - rScreen.width(), _wrkHeight);
+ lScreen.translate(_bkgWidth - lScreen.width(), 0);
+ lScreen.clip(src);
+ rScreen.clip(src);
+ if (rScreen.width() < lScreen.width()) {
+ tmp.translate(_screenCenterX - _bkgOff - _bkgWidth, 0);
+ } else {
+ tmp.translate(_screenCenterX - _bkgOff, 0);
+ }
+ } else if (_bkgWidth - _bkgOff < _screenCenterX) {
+ Common::Rect rScreen(_screenCenterX - (_bkgWidth - _bkgOff), _wrkHeight);
+ Common::Rect lScreen(_wrkWidth - rScreen.width(), _wrkHeight);
+ lScreen.translate(_bkgWidth - lScreen.width(), 0);
+ lScreen.clip(src);
+ rScreen.clip(src);
+ if (lScreen.width() < rScreen.width()) {
+ tmp.translate(_screenCenterX + (_bkgWidth - _bkgOff), 0);
+ } else {
+ tmp.translate(_screenCenterX - _bkgOff, 0);
+ }
+ } else {
+ tmp.translate(_screenCenterX - _bkgOff, 0);
+ }
+ } else if (state == RenderTable::TILT) {
+ tmp.translate(0, (_screenCenterY - _bkgOff));
+ }
+
+ return tmp;
+}
+
+EffectMap *RenderManager::makeEffectMap(const Common::Point &xy, int16 depth, const Common::Rect &rect, int8 *_minComp, int8 *_maxComp) {
+ Common::Rect bkgRect(_bkgWidth, _bkgHeight);
+ if (!bkgRect.contains(xy))
+ return NULL;
+
+ if (!bkgRect.intersects(rect))
+ return NULL;
+
+ uint16 color = *(uint16 *)_curBkg.getBasePtr(xy.x, xy.y);
+ uint8 stC1, stC2, stC3;
+ _curBkg.format.colorToRGB(color, stC1, stC2, stC3);
+ EffectMap *newMap = new EffectMap;
+
+ EffectMapUnit unit;
+ unit.count = 0;
+ unit.inEffect = false;
+
+ int16 w = rect.width();
+ int16 h = rect.height();
+
+ bool first = true;
+
+ uint8 minComp = MIN(MIN(stC1, stC2), stC3);
+ uint8 maxComp = MAX(MAX(stC1, stC2), stC3);
+
+ uint8 depth8 = depth << 3;
+
+ for (int16 j = 0; j < h; j++) {
+ uint16 *pix = (uint16 *)_curBkg.getBasePtr(rect.left, rect.top + j);
+ for (int16 i = 0; i < w; i++) {
+ uint16 curClr = pix[i];
+ uint8 cC1, cC2, cC3;
+ _curBkg.format.colorToRGB(curClr, cC1, cC2, cC3);
+
+ bool use = false;
+
+ if (curClr == color)
+ use = true;
+ else if (curClr > color) {
+ if ((cC1 - stC1 < depth8) &&
+ (cC2 - stC2 < depth8) &&
+ (cC3 - stC3 < depth8))
+ use = true;
+ } else { /* if (curClr < color) */
+ if ((stC1 - cC1 < depth8) &&
+ (stC2 - cC2 < depth8) &&
+ (stC3 - cC3 < depth8))
+ use = true;
+ }
+
+ if (first) {
+ unit.inEffect = use;
+ first = false;
+ }
+
+ if (use) {
+ uint8 cMinComp = MIN(MIN(cC1, cC2), cC3);
+ uint8 cMaxComp = MAX(MAX(cC1, cC2), cC3);
+ if (cMinComp < minComp)
+ minComp = cMinComp;
+ if (cMaxComp > maxComp)
+ maxComp = cMaxComp;
+ }
+
+ if (unit.inEffect == use)
+ unit.count++;
+ else {
+ newMap->push_back(unit);
+ unit.count = 1;
+ unit.inEffect = use;
+ }
+ }
+ }
+ newMap->push_back(unit);
+
+ if (_minComp) {
+ if (minComp - depth8 < 0)
+ *_minComp = -(minComp >> 3);
+ else
+ *_minComp = -depth;
+ }
+ if (_maxComp) {
+ if ((int16)maxComp + (int16)depth8 > 255)
+ *_maxComp = (255 - maxComp) >> 3;
+ else
+ *_maxComp = depth;
+ }
+
+ return newMap;
+}
+
+EffectMap *RenderManager::makeEffectMap(const Graphics::Surface &surf, uint16 transp) {
+ EffectMapUnit unit;
+ unit.count = 0;
+ unit.inEffect = false;
+
+ int16 w = surf.w;
+ int16 h = surf.h;
+
+ EffectMap *newMap = new EffectMap;
+
+ bool first = true;
+
+ for (int16 j = 0; j < h; j++) {
+ const uint16 *pix = (const uint16 *)surf.getBasePtr(0, j);
+ for (int16 i = 0; i < w; i++) {
+ bool use = false;
+ if (pix[i] != transp)
+ use = true;
+
+ if (first) {
+ unit.inEffect = use;
+ first = false;
+ }
+
+ if (unit.inEffect == use)
+ unit.count++;
+ else {
+ newMap->push_back(unit);
+ unit.count = 1;
+ unit.inEffect = use;
+ }
+ }
+ }
+ newMap->push_back(unit);
+
+ return newMap;
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/graphics/render_manager.h b/engines/zvision/graphics/render_manager.h
index 24234e28e1..665a27bf64 100644
--- a/engines/zvision/graphics/render_manager.h
+++ b/engines/zvision/graphics/render_manager.h
@@ -31,6 +31,8 @@
#include "graphics/surface.h"
+#include "effect.h"
+
class OSystem;
@@ -68,6 +70,7 @@ private:
// };
//
typedef Common::HashMap<uint16, oneSub> subMap;
+ typedef Common::List<Effect *> effectsList;
private:
ZVision *_engine;
@@ -93,6 +96,8 @@ private:
Common::Rect _menuWndDirtyRect;
+ Graphics::Surface _effectWnd;
+
// A buffer the exact same size as the workingWindow
// This buffer stores everything un-warped, then does a warp at the end of the frame
@@ -151,6 +156,8 @@ private:
/** Holds any 'leftover' milliseconds between frames */
//uint _accumulatedVelocityMilliseconds;
+ effectsList _effects;
+
public:
void initialize();
@@ -267,6 +274,13 @@ public:
*/
void readImageToSurface(const Common::String &fileName, Graphics::Surface &destination);
void readImageToSurface(const Common::String &fileName, Graphics::Surface &destination, bool transposed);
+
+ void addEffect(Effect *_effect);
+ void deleteEffect(uint32 ID);
+ EffectMap *makeEffectMap(const Common::Point &xy, int16 depth, const Common::Rect &rect, int8 *minD, int8 *maxD);
+ EffectMap *makeEffectMap(const Graphics::Surface &surf, uint16 transp);
+
+ Common::Rect bkgRectToScreen(const Common::Rect &src);
};
} // End of namespace ZVision
diff --git a/engines/zvision/module.mk b/engines/zvision/module.mk
index 6734fde6e2..872b48f775 100644
--- a/engines/zvision/module.mk
+++ b/engines/zvision/module.mk
@@ -13,6 +13,9 @@ MODULE_OBJS := \
cursors/cursor.o \
detection.o \
fonts/truetype_font.o \
+ graphics/effects/fog.o \
+ graphics/effects/light.o \
+ graphics/effects/wave.o \
graphics/render_manager.o \
graphics/render_table.o \
scripting/actions.o \
@@ -33,6 +36,7 @@ MODULE_OBJS := \
scripting/sidefx.o \
scripting/sidefx/animation_node.o \
scripting/sidefx/music_node.o \
+ scripting/sidefx/region_node.o \
scripting/sidefx/syncsound_node.o \
scripting/sidefx/timer_node.o \
scripting/sidefx/ttytext_node.o \
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp
index 399a81d898..839eb1f92c 100644
--- a/engines/zvision/scripting/actions.cpp
+++ b/engines/zvision/scripting/actions.cpp
@@ -34,7 +34,13 @@
#include "zvision/scripting/sidefx/syncsound_node.h"
#include "zvision/scripting/sidefx/animation_node.h"
#include "zvision/scripting/sidefx/ttytext_node.h"
+#include "zvision/scripting/sidefx/region_node.h"
#include "zvision/scripting/controls/titler_control.h"
+#include "zvision/graphics/render_table.h"
+#include "zvision/graphics/effect.h"
+#include "zvision/graphics/effects/fog.h"
+#include "zvision/graphics/effects/light.h"
+#include "zvision/graphics/effects/wave.h"
#include "common/file.h"
@@ -476,6 +482,80 @@ bool ActionQuit::execute() {
return true;
}
+//////////////////////////////////////////////////////////////////////////////
+// ActionRegion
+//////////////////////////////////////////////////////////////////////////////
+
+ActionRegion::ActionRegion(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey) {
+
+ char art[64];
+ char custom[64];
+
+ int32 x1, x2, y1, y2;
+
+ sscanf(line.c_str(), "%s %d %d %d %d %hu %hu %hu %hu %s", art, &x1, &y1, &x2, &y2, &_delay, &_type, &_unk1, &_unk2, custom);
+ _art = Common::String(art);
+ _custom = Common::String(custom);
+ _rect = Common::Rect(x1, y1, x2 + 1, y2 + 1);
+}
+
+ActionRegion::~ActionRegion() {
+ _engine->getScriptManager()->killSideFx(_slotkey);
+}
+
+bool ActionRegion::execute() {
+ if (_engine->getScriptManager()->getSideFX(_slotkey))
+ return true;
+
+ Effect *effct = NULL;
+ switch (_type) {
+ case 0: {
+ uint16 s_x, s_y, frames;
+ double amplitude, waveln, speed;
+ sscanf(_custom.c_str(), "%hu,%hu,%hu,%lf,%lf,%lf,", &s_x, &s_y, &frames, &amplitude, &waveln, &speed);
+ effct = new WaveFx(_engine, _slotkey, _rect, _unk1, frames, s_x, s_y, amplitude, waveln, speed);
+ }
+ break;
+ case 1: {
+ uint16 aX, aY, aD;
+ if (_engine->getRenderManager()->getRenderTable()->getRenderState() == RenderTable::PANORAMA)
+ sscanf(_art.c_str(), "useart[%hu,%hu,%hu]", &aY, &aX, &aD);
+ else
+ sscanf(_art.c_str(), "useart[%hu,%hu,%hu]", &aX, &aY, &aD);
+ int8 minD;
+ int8 maxD;
+ EffectMap *_map = _engine->getRenderManager()->makeEffectMap(Common::Point(aX, aY), aD, _rect, &minD, &maxD);
+ effct = new LightFx(_engine, _slotkey, _rect, _unk1, _map, atoi(_custom.c_str()), minD, maxD);
+ }
+ break;
+ case 9: {
+ int16 dum1;
+ int32 dum2;
+ char buf[64];
+ sscanf(_custom.c_str(), "%hd,%d,%s", &dum1, &dum2, buf);
+ Graphics::Surface tempMask;
+ _engine->getRenderManager()->readImageToSurface(_art, tempMask);
+ if (_rect.width() != tempMask.w)
+ _rect.setWidth(tempMask.w);
+ if (_rect.height() != tempMask.h)
+ _rect.setHeight(tempMask.h);
+
+ EffectMap *_map = _engine->getRenderManager()->makeEffectMap(tempMask, 0);
+ effct = new FogFx(_engine, _slotkey, _rect, _unk1, _map, Common::String(buf));
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (effct) {
+ _engine->getScriptManager()->addSideFX(new RegionNode(_engine, _slotkey, effct, _delay));
+ _engine->getRenderManager()->addEffect(effct);
+ }
+
+ return true;
+}
//////////////////////////////////////////////////////////////////////////////
// ActionRandom
diff --git a/engines/zvision/scripting/actions.h b/engines/zvision/scripting/actions.h
index de303a7b1b..5e34f6eaf0 100644
--- a/engines/zvision/scripting/actions.h
+++ b/engines/zvision/scripting/actions.h
@@ -317,6 +317,22 @@ public:
bool execute();
};
+class ActionRegion : public ResultAction {
+public:
+ ActionRegion(ZVision *engine, int32 slotkey, const Common::String &line);
+ ~ActionRegion();
+ bool execute();
+
+private:
+ Common::String _art;
+ Common::String _custom;
+ Common::Rect _rect;
+ uint16 _delay;
+ uint16 _type;
+ uint16 _unk1;
+ uint16 _unk2;
+};
+
// TODO: See if this exists in ZGI. It doesn't in ZNem
class ActionUnloadAnimation : public ResultAction {
public:
diff --git a/engines/zvision/scripting/scr_file_handling.cpp b/engines/zvision/scripting/scr_file_handling.cpp
index 04378f856f..8140d09a6a 100644
--- a/engines/zvision/scripting/scr_file_handling.cpp
+++ b/engines/zvision/scripting/scr_file_handling.cpp
@@ -266,7 +266,7 @@ void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::Lis
} else if (act.matchString("random", true)) {
actionList.push_back(new ActionRandom(_engine, slot, args));
} else if (act.matchString("region", true)) {
- // TODO: Implement ActionRegion
+ actionList.push_back(new ActionRegion(_engine, slot, args));
} else if (act.matchString("restore_game", true)) {
// TODO: Implement ActionRestoreGame
} else if (act.matchString("rotate_to", true)) {
diff --git a/engines/zvision/scripting/script_manager.h b/engines/zvision/scripting/script_manager.h
index 4d82f36aea..219cff9f45 100644
--- a/engines/zvision/scripting/script_manager.h
+++ b/engines/zvision/scripting/script_manager.h
@@ -87,9 +87,9 @@ enum StateKey {
StateKey_DebugCheats = 74,
StateKey_JapanFonts = 75,
StateKey_Brightness = 77,
- StateKey_EF9_B = 91,
+ StateKey_EF9_R = 91,
StateKey_EF9_G = 92,
- StateKey_EF9_R = 93,
+ StateKey_EF9_B = 93,
StateKey_EF9_Speed = 94,
StateKey_Inv_Cnt_Slot = 100,
StateKey_Inv_1_Slot = 101,
diff --git a/engines/zvision/scripting/sidefx/region_node.cpp b/engines/zvision/scripting/sidefx/region_node.cpp
new file mode 100644
index 0000000000..de613d8af2
--- /dev/null
+++ b/engines/zvision/scripting/sidefx/region_node.cpp
@@ -0,0 +1,56 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/scripting/sidefx/region_node.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+
+namespace ZVision {
+
+RegionNode::RegionNode(ZVision *engine, uint32 key, Effect *effect, uint32 delay)
+ : SideFX(engine, key, SIDEFX_REGION) {
+ _effect = effect;
+ _delay = delay;
+ _timeLeft = 0;
+}
+
+RegionNode::~RegionNode() {
+ _engine->getRenderManager()->deleteEffect(_key);
+}
+
+bool RegionNode::process(uint32 deltaTimeInMillis) {
+ _timeLeft -= deltaTimeInMillis;
+
+ if (_timeLeft <= 0) {
+ _timeLeft = _delay;
+ if (_effect)
+ _effect->update();
+ }
+
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/sidefx/region_node.h b/engines/zvision/scripting/sidefx/region_node.h
new file mode 100644
index 0000000000..ec716b6e3e
--- /dev/null
+++ b/engines/zvision/scripting/sidefx/region_node.h
@@ -0,0 +1,57 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ZVISION_REGION_NODE_H
+#define ZVISION_REGION_NODE_H
+
+#include "graphics/surface.h"
+
+#include "zvision/scripting/sidefx.h"
+#include "zvision/graphics/effect.h"
+
+namespace ZVision {
+
+class ZVision;
+
+class RegionNode : public SideFX {
+public:
+ RegionNode(ZVision *engine, uint32 key, Effect *effect, uint32 delay);
+ ~RegionNode();
+
+ /**
+ * Decrement the timer by the delta time. If the timer is finished, set the status
+ * in _globalState and let this node be deleted
+ *
+ * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
+ * @return If true, the node can be deleted after process() finishes
+ */
+ bool process(uint32 deltaTimeInMillis);
+
+private:
+ int32 _timeLeft;
+ uint32 _delay;
+ Effect *_effect;
+};
+
+} // End of namespace ZVision
+
+#endif