aboutsummaryrefslogtreecommitdiff
path: root/engines/zvision/graphics/render_manager.cpp
diff options
context:
space:
mode:
authorMarisa-Chan2014-10-10 16:40:46 +0700
committerMarisa-Chan2014-10-10 16:40:46 +0700
commitcf63da941cf7b7162551f6d660f5dbbda3150239 (patch)
tree930f14ddbbefb64cf8244321e437726cdaa92953 /engines/zvision/graphics/render_manager.cpp
parent2a6c2fdf4532e6f5ba3a2a6f8a0e78db4dcdc635 (diff)
downloadscummvm-rg350-cf63da941cf7b7162551f6d660f5dbbda3150239.tar.gz
scummvm-rg350-cf63da941cf7b7162551f6d660f5dbbda3150239.tar.bz2
scummvm-rg350-cf63da941cf7b7162551f6d660f5dbbda3150239.zip
ZVISION: Action:region and visual effects implemented.
Diffstat (limited to 'engines/zvision/graphics/render_manager.cpp')
-rw-r--r--engines/zvision/graphics/render_manager.cpp218
1 files changed, 216 insertions, 2 deletions
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