ZVISION: Action:region and visual effects implemented.

This commit is contained in:
Marisa-Chan 2014-10-10 16:40:46 +07:00
parent 2a6c2fdf45
commit cf63da941c
16 changed files with 1115 additions and 5 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 \

View File

@ -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

View File

@ -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:

View File

@ -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)) {

View File

@ -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,

View File

@ -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

View File

@ -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