diff options
author | Eugene Sandulenko | 2016-05-10 11:23:13 +0200 |
---|---|---|
committer | Eugene Sandulenko | 2016-05-10 11:23:13 +0200 |
commit | 200882277aed257a1a71d300a59ca0b9fdbc7699 (patch) | |
tree | efa543c4d5074746eb6a4d38aca8bee8ddf3eb87 /engines | |
parent | 28deb13d4e78ee97cbbb22e861c48b8a17f49439 (diff) | |
download | scummvm-rg350-200882277aed257a1a71d300a59ca0b9fdbc7699.tar.gz scummvm-rg350-200882277aed257a1a71d300a59ca0b9fdbc7699.tar.bz2 scummvm-rg350-200882277aed257a1a71d300a59ca0b9fdbc7699.zip |
SCUMM HE: Initial code for Moonbase FOW
Diffstat (limited to 'engines')
-rw-r--r-- | engines/scumm/he/intern_he.h | 1 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/moonbase.cpp | 10 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/moonbase.h | 51 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/moonbase_fow.cpp | 435 | ||||
-rw-r--r-- | engines/scumm/he/wiz_he.cpp | 3 | ||||
-rw-r--r-- | engines/scumm/module.mk | 3 | ||||
-rw-r--r-- | engines/scumm/scumm.cpp | 2 |
7 files changed, 490 insertions, 15 deletions
diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h index a8d7e846a2..51d9a9045f 100644 --- a/engines/scumm/he/intern_he.h +++ b/engines/scumm/he/intern_he.h @@ -188,6 +188,7 @@ protected: #ifdef ENABLE_HE class ScummEngine_v71he : public ScummEngine_v70he { friend class Wiz; + friend class Moonbase; protected: bool _skipProcessActors; diff --git a/engines/scumm/he/moonbase/moonbase.cpp b/engines/scumm/he/moonbase/moonbase.cpp index 1f9d843bb9..a07a874b48 100644 --- a/engines/scumm/he/moonbase/moonbase.cpp +++ b/engines/scumm/he/moonbase/moonbase.cpp @@ -24,19 +24,13 @@ namespace Scumm { -Moonbase::Moonbase() { - _fowSentinelImage = -1; - _fowSentinelState = -1; - _fowSentinelConditionBits = 0; +Moonbase::Moonbase(ScummEngine_v71he *vm) : _vm(vm) { + initFOW(); } Moonbase::~Moonbase() { } -void Moonbase::renderFOW() { - warning("STUB: renderFOW()"); -} - void Moonbase::blitT14WizImage(uint8 *dst, int dstw, int dsth, int dstPitch, const Common::Rect *clipBox, uint8 *wizd, int x, int y, int rawROP, int paramROP) { diff --git a/engines/scumm/he/moonbase/moonbase.h b/engines/scumm/he/moonbase/moonbase.h index 7ff2f17070..e50337ddeb 100644 --- a/engines/scumm/he/moonbase/moonbase.h +++ b/engines/scumm/he/moonbase/moonbase.h @@ -29,18 +29,63 @@ namespace Scumm { class Moonbase { public: - Moonbase(); + Moonbase(ScummEngine_v71he *vm); ~Moonbase(); - void renderFOW(); - void blitT14WizImage(uint8 *dst, int dstw, int dsth, int dstPitch, const Common::Rect *clipBox, uint8 *wizd, int srcx, int srcy, int rawROP, int paramROP); + // FOW Stuff + void initFOW(); + void releaseFOWResources(); + + bool setFOWImage(int id); + + void setFOWInfo(int fowInfoArray, int downDim, int acrossDim, int viewX, int viewY, int clipX1, + int clipY1, int clipX2, int clipY2, int technique, int nFrame); + + + void renderFOW(uint8 *destSurface, int dstPitch, int dstType, int dstw, int dsth, int flags); + +private: + bool captureFOWImageFromLocation(void *src); + int readFOWVisibilityArray(int array, int y, int x); + void renderFOWState(uint8 *destSurface, int dstPitch, int dstType, int dstw, int dsth, int x, int y, int srcw, int srch, int state, int flags); + public: int _fowSentinelImage; int _fowSentinelState; uint16 _fowSentinelConditionBits; + +private: + ScummEngine_v71he *_vm; + + int _fowFrameBaseNumber; + int _fowAnimationFrames; + int _fowCurrentFOWFrame; + + int _fowTileW; + int _fowTileH; + + byte *_fowImage; + int _fowClipX1; + int _fowClipY1; + int _fowClipX2; + int _fowClipY2; + + int _fowDrawX; + int _fowDrawY; + + int _fowVtx1; + int _fowVty1; + int _fowMvx; + int _fowMvy; + int _fowVw; + int _fowVh; + + bool _fowBlackMode; + + int _fowRenderTable[32768]; }; #endif diff --git a/engines/scumm/he/moonbase/moonbase_fow.cpp b/engines/scumm/he/moonbase/moonbase_fow.cpp new file mode 100644 index 0000000000..7693d4dd24 --- /dev/null +++ b/engines/scumm/he/moonbase/moonbase_fow.cpp @@ -0,0 +1,435 @@ +/* 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/config-manager.h" +#include "scumm/he/intern_he.h" + +namespace Scumm { + +#define FOW_ANIM_FRAME_COUNT 38 + +void Moonbase::initFOW() { + _fowSentinelImage = -1; + _fowSentinelState = -1; + _fowSentinelConditionBits = 0; + + _fowFrameBaseNumber = 0; + _fowAnimationFrames = 1; + _fowCurrentFOWFrame = 0; + + _fowTileW = 0; + _fowTileH = 0; + + _fowImage = nullptr; + _fowClipX1 = 0; + _fowClipY1 = 0; + _fowClipX2 = 0; + _fowClipY2 = 0; + + _fowDrawX = 0; + _fowDrawY = 0; + + _fowVtx1 = 0; + _fowVty1 = 0; + _fowMvx = 0; + _fowMvy = 0; + _fowVw = 0; + _fowVh = 0; + + _fowBlackMode = true; + + memset(_fowRenderTable, 0, 32768); +} + +void Moonbase::releaseFOWResources() { + if (_fowImage) { + free(_fowImage); + _fowImage = 0; + } +} + +bool Moonbase::captureFOWImageFromLocation(void *src) { + if (!src) + return false; + + int imageDataSize = 0; //getMemoryBlockSize(src); // TODO + + if (imageDataSize <= 0) + return false; + + _fowImage = (byte *)malloc(imageDataSize); + + if (!_fowImage) + return false; + + memcpy(_fowImage, src, imageDataSize); + + return true; +} + +bool Moonbase::setFOWImage(int image) { + releaseFOWResources(); + + if (!_fowImage) { + Common::String fowImageFilename(ConfMan.get("MOONX_FOWImageFilename").c_str()); + +#if 0 // TODO + if (!fowImageFilename.empty()) { + void *wiz = loadWizFromFilename(fowImageFilename); + + if (wiz) { + captureFOWImageFromLocation(wiz); + free(wiz); + } + } +#endif + + if (!_fowImage && image < 0) { + int resType; + + // PIECES BUBBLES CIRCLES SIMPLE* WEDGEY BUBBLE2 + // WEDGE2 SPIKEY ANGLES SMOOTHED WUZZY SYS7-BEVELED + if (image >= -1 && image <= 12) + resType = 210 - image; // 211-222 range + else + resType = 214; // default, SIMPLE +#if 0 // TODO + HRSRC hResource = FindResource(g_hInst, resType, 10); + if (hResource) { + byte res = LoadResource(g_hInst, hResource); + + if (res) { + uint16 nDataSize = SizeofResource(g_hInst, hResource); + + if (nDataSize) + captureFOWImageFromLocation(res); + } + } +#endif + } + + if (!_fowImage && image > 0) { + void *glob = _vm->getResourceAddress(rtImage, image); + + if (glob) + captureFOWImageFromLocation(glob); + } + + if (!_fowImage) + return false; + } + + int nStates = _vm->_wiz->getWizImageStates(0); //_fowImage); // TODO + + if (nStates > FOW_ANIM_FRAME_COUNT) { + releaseFOWResources(); + return false; + } + + _fowAnimationFrames = (nStates + FOW_ANIM_FRAME_COUNT - 1) / FOW_ANIM_FRAME_COUNT; + + Common::Point fowTileSize(0, 0); //getWizStateSize(_fowImage, (nStates - 1)); // TODO + + _fowTileW = fowTileSize.x; + _fowTileH = fowTileSize.y; + + int hitTestValue = 0; + uint pixelValue = 0; + + //LayeredWizHitTest(&hitTestValue, &pixelValue, _fowImage, (nStates - 1), 0, 0, 0, 0); // TODO + _fowBlackMode = (pixelValue == 0) ? 1 : 0; + + if (ConfMan.hasKey("EnableFOWRects")) + _fowBlackMode = (ConfMan.getInt("EnableFOWRects") == 1); + + return true; +} + +enum FOWElement { + FOW_EMPTY = 0, + FOW_SOLID = 1, + + FF_L = 0x01, + FF_R = 0x02, + FF_T = 0x04, + FF_B = 0x08, + FF_T_L = 0x10, + FF_T_R = 0x20, + FF_B_L = 0x40, + FF_B_R = 0x80, + FF_Q_A = (FF_L | FF_T | FF_T_L), + FF_Q_B = (FF_R | FF_T | FF_T_R), + FF_Q_C = (FF_L | FF_B | FF_B_L), + FF_Q_D = (FF_R | FF_B | FF_B_R) +}; + +int Moonbase::readFOWVisibilityArray(int array, int y, int x) { + //_vm->VAR(_vm->VAR_U32_ARRAY_UNK) = array; // TODO + + if (_vm->readArray(116, y, x) > 0) + return FOW_EMPTY; + + return FOW_SOLID; +} + +void Moonbase::setFOWInfo(int fowInfoArray, int downDim, int acrossDim, int viewX, int viewY, int clipX1, + int clipY1, int clipX2, int clipY2, int technique, int nFrame) { + if (!_fowImage) + return; + + _fowDrawX = clipX1; + _fowDrawY = clipY1; + + _fowClipX1 = clipX1; + _fowClipY1 = clipY1; + _fowClipX2 = clipX2; + _fowClipY2 = clipY2; + + // Figure out the number of tiles are involved + int view_W = (clipX2 - clipX1) + 1; + int view_H = (clipY2 - clipY1) + 1; + + int tw = _fowTileW; + int th = _fowTileH; + + int dw = acrossDim; + int dh = downDim; + + int dlw = dw * tw; + int dlh = dh * th; + + _fowMvx = (0 <= viewX) ? (viewX % dlw) : (dlw - (-viewX % dlw)); + _fowMvy = (0 <= viewY) ? (viewY % dlh) : (dlh - (-viewY % dlh)); + + _fowVtx1 = _fowMvx / tw; + _fowVty1 = _fowMvy / th; + + _fowVw = (((_fowMvx + view_W + tw - 1) / tw) - _fowVtx1) + 1; + _fowVh = (((_fowMvy + view_H + th - 1) / th) - _fowVty1) + 1; + + // Build the connectivity table + int t = (_fowVty1 - 1); if (t >= dh) { t = 0; } else if (t < 0) { t = (dh - 1); } + int m = (_fowVty1 + 0); if (m >= dh) { m = 0; } else if (m < 0) { m = (dh - 1); } + int b = (_fowVty1 + 1); if (b >= dh) { b = 0; } else if (b < 0) { b = (dh - 1); } + + int il = (_fowVtx1 - 1); if (il >= dh) { il = 0; } else if (il < 0) { il = (dw - 1); } + int ic = (_fowVtx1 + 0); if (ic >= dh) { ic = 0; } else if (ic < 0) { ic = (dw - 1); } + int ir = (_fowVtx1 + 1); if (ir >= dh) { ir = 0; } else if (ir < 0) { ir = (dw - 1); } + + int dataOffset = (_fowVw * 3); + int dataOffset2 = (dataOffset * 2); + int *pOutterRenderTableA = _fowRenderTable; + int *pOutterRenderTableB = pOutterRenderTableA + dataOffset; + + for (int ay = 0; ay < _fowVh; ay++) { + int l = il; + int c = ic; + int r = ir; + + int *pRenderTableA = pOutterRenderTableA; + int *pRenderTableB = pOutterRenderTableB; + + pOutterRenderTableA += dataOffset2; + pOutterRenderTableB += dataOffset2; + + for (int ax = 0; ax < _fowVw; ax++) { + int visibility = readFOWVisibilityArray(fowInfoArray, m, c); + + if (visibility == FOW_EMPTY) { + int bits = 0; + + if (readFOWVisibilityArray(fowInfoArray, t, l) != 0) bits |= FF_T_L; + if (readFOWVisibilityArray(fowInfoArray, t, c) != 0) bits |= FF_T; + if (readFOWVisibilityArray(fowInfoArray, t, r) != 0) bits |= FF_T_R; + if (readFOWVisibilityArray(fowInfoArray, m, l) != 0) bits |= FF_L; + if (readFOWVisibilityArray(fowInfoArray, m, r) != 0) bits |= FF_R; + if (readFOWVisibilityArray(fowInfoArray, b, l) != 0) bits |= FF_B_L; + if (readFOWVisibilityArray(fowInfoArray, b, c) != 0) bits |= FF_B; + if (readFOWVisibilityArray(fowInfoArray, b, r) != 0) bits |= FF_B_R; + + if (bits) { + *pRenderTableA++ = 1; + *pRenderTableB++ = 1; + + // Quadrant (A) + if (bits & FF_Q_A) { + *pRenderTableA++ = ( + ((FF_L & bits) ? 1 : 0) | + ((FF_T & bits) ? 2 : 0) | + ((FF_T_L & bits) ? 4 : 0) + ) + 0; + } else { + *pRenderTableA++ = 0; + } + + // Quadrant (B) + if (bits & FF_Q_B) { + *pRenderTableA++ = ( + ((FF_R & bits) ? 1 : 0) | + ((FF_T & bits) ? 2 : 0) | + ((FF_T_R & bits) ? 4 : 0) + ) + 8; + } else { + *pRenderTableA++ = 0; + } + + // Quadrant (C) + if (bits & FF_Q_C) { + *pRenderTableB++ = ( + ((FF_L & bits) ? 1 : 0) | + ((FF_B & bits) ? 2 : 0) | + ((FF_B_L & bits) ? 4 : 0) + ) + 16; + } else { + *pRenderTableB++ = 0; + } + + // Quadrant (D) + if (bits & FF_Q_D) { + *pRenderTableB++ = ( + ((FF_R & bits) ? 1 : 0) | + ((FF_B & bits) ? 2 : 0) | + ((FF_B_R & bits) ? 4 : 0) + ) + 24; + } else { + *pRenderTableB++ = 0; + } + } else { + *pRenderTableA++ = 0; + *pRenderTableB++ = 0; + } + } else { + if (_fowBlackMode) { + *pRenderTableA++ = 2; + *pRenderTableB++ = 2; + } else { + *pRenderTableA++ = 1; + *pRenderTableA++ = 33; + *pRenderTableA++ = 34; + + *pRenderTableB++ = 1; + *pRenderTableB++ = 35; + *pRenderTableB++ = 36; + } + } + + if (++l >= dw) { l = 0; } + if (++c >= dw) { c = 0; } + if (++r >= dw) { r = 0; } + } + + if (++t >= dh) { t = 0; } + if (++m >= dh) { m = 0; } + if (++b >= dh) { b = 0; } + } + + _fowCurrentFOWFrame = (nFrame >= 0) ? (nFrame % _fowAnimationFrames) : ((-nFrame) % _fowAnimationFrames); + _fowFrameBaseNumber = (_fowCurrentFOWFrame * FOW_ANIM_FRAME_COUNT); +} + +void Moonbase::renderFOWState(uint8 *destSurface, int dstPitch, int dstType, int dstw, int dsth, int x, int y, int srcw, int srch, int state, int flags) { + int spotx, spoty; + + //getWizImageSpot(_fowImage, state, &spotx, &spoty); // TODO + Common::Rect r(_fowClipX1, _fowClipY1, _fowClipX2, _fowClipY2); + + _vm->_wiz->drawWizImageEx(destSurface, _fowImage, 0, dstPitch, dstType, dstw, dsth, x - spotx, y - spoty, srcw, srch, state, &r, flags, 0, 0, 16, 0, 0); +} + +static void blackRect_16bpp(uint8 *destSurface, int x1, int y1, int x2, int y2) { + // TODO +} + +void Moonbase::renderFOW(uint8 *destSurface, int dstPitch, int dstType, int dstw, int dsth, int flags) { + if (!_fowImage) + return; + + const int *pOutterRenderTable = _fowRenderTable; + int ixPos = ((_fowVtx1 * _fowTileW) - _fowMvx) + _fowDrawX; + int yPos = ((_fowVty1 * _fowTileH) - _fowMvy) + _fowDrawY; + int dataOffset = _fowVw * 3; + int halfTileHeight = _fowTileH / 2; + int cx2 = MIN(_fowClipX2, (dstw - 1)); + int cy2 = MIN(_fowClipY2, (dsth - 1)); + + for (int ry = 0; ry < _fowVh; ry++) { + int real_yPos = yPos; + + for (int i = 0; i < 2; i++) { + const int *pRenderTable = pOutterRenderTable; + pOutterRenderTable += dataOffset; + + int xPos = ixPos; + + for (int rx = 0; rx < _fowVw; rx++) { + int nState = *pRenderTable++; + + if (nState != 0) { + if (nState == 2) { + int countLeft = (_fowVw - rx); + int count = 0; + + for (; count < countLeft; count++) { + if (*(pRenderTable + count) != 2) + break; + + pRenderTable++; + rx++; + } + count++; + + int x1 = xPos; + int y1 = real_yPos; + + xPos += _fowTileW * count; + int x2 = (xPos - 1); + int y2 = ((y1 + halfTileHeight) - 1); + + x1 = MAX(0, x1); + y1 = MAX(0, y1); + x2 = MIN(x2, cx2); + y2 = MIN(y2, cy2); + + if ((x2 >= x1) && (y2 >= y1) && (x1 <= _fowClipX2) && (y1 <= _fowClipY2)) + blackRect_16bpp(destSurface, x1, y1, x2, y2); + } else { + int subState; + + if ((subState = *pRenderTable++) != 0) + renderFOWState(destSurface, dstPitch, dstType, dstw, dsth, xPos, yPos, _fowTileW, _fowTileH, (subState + _fowFrameBaseNumber), flags); + + if ((subState = *pRenderTable++) != 0) + renderFOWState(destSurface, dstPitch, dstType, dstw, dsth, xPos, yPos, _fowTileW, _fowTileH, (subState + _fowFrameBaseNumber), flags); + + xPos += _fowTileW; + } + } else { + xPos += _fowTileW; + } + } + real_yPos += halfTileHeight; + } + yPos += _fowTileH; + } +} + +} // End of namespace Scumm diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp index 19e9dbb5b6..94d5938724 100644 --- a/engines/scumm/he/wiz_he.cpp +++ b/engines/scumm/he/wiz_he.cpp @@ -2310,10 +2310,9 @@ void Wiz::displayWizComplexImage(const WizParameters *params) { if (params->img.resNum == _vm->_moonbase->_fowSentinelImage && state == _vm->_moonbase->_fowSentinelState && params->conditionBits == _vm->_moonbase->_fowSentinelConditionBits) - _vm->_moonbase->renderFOW(); + _vm->_moonbase->renderFOW(0, 0, 0, 0, 0, flags); } - drawWizImage(params->img.resNum, state, 0, 0, po_x, po_y, params->img.zorder, shadow, zbuffer, r, flags, dstResNum, _vm->getHEPaletteSlot(palette), params->conditionBits); } } diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk index 5462ad3090..c56ef7e5f4 100644 --- a/engines/scumm/module.mk +++ b/engines/scumm/module.mk @@ -139,7 +139,8 @@ MODULE_OBJS += \ he/logic/moonbase_logic.o \ he/logic/puttrace.o \ he/logic/soccer.o \ - he/moonbase/moonbase.o + he/moonbase/moonbase.o \ + he/moonbase/moonbase_fow.o endif # This module can be built as a plugin diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 746e74d33d..ff25dc9201 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -837,7 +837,7 @@ ScummEngine_v71he::ScummEngine_v71he(OSystem *syst, const DetectorResult &dr) _moonbase = 0; if (_game.id == GID_MOONBASE) - _moonbase = new Moonbase(); + _moonbase = new Moonbase(this); } ScummEngine_v71he::~ScummEngine_v71he() { |