diff options
Diffstat (limited to 'engines/scumm/he')
-rw-r--r-- | engines/scumm/he/cup_player_he.cpp | 3 | ||||
-rw-r--r-- | engines/scumm/he/intern_he.h | 17 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_defenseunit.cpp | 32 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_main.cpp | 13 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_targetacquisition.cpp | 22 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_targetacquisition.h | 2 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_traveller.cpp | 14 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_tree.cpp | 7 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_types.h | 2 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/distortion.cpp | 218 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/moonbase.h | 4 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/moonbase_fow.cpp | 32 | ||||
-rw-r--r-- | engines/scumm/he/script_v100he.cpp | 85 | ||||
-rw-r--r-- | engines/scumm/he/script_v70he.cpp | 40 | ||||
-rw-r--r-- | engines/scumm/he/sound_he.cpp | 28 | ||||
-rw-r--r-- | engines/scumm/he/sound_he.h | 6 | ||||
-rw-r--r-- | engines/scumm/he/wiz_he.cpp | 20 |
17 files changed, 412 insertions, 133 deletions
diff --git a/engines/scumm/he/cup_player_he.cpp b/engines/scumm/he/cup_player_he.cpp index c409863804..3a7ad49c2f 100644 --- a/engines/scumm/he/cup_player_he.cpp +++ b/engines/scumm/he/cup_player_he.cpp @@ -408,6 +408,9 @@ void CUP_Player::handleSRLE(Common::SeekableReadStream &dataStream, uint32 dataS static void decodeLZSS(uint8 *dst, const uint8 *src1, const uint8 *src2, const uint8 *src3) { uint8 wnd[4096]; int index = 1; + + memset(wnd, 0, sizeof(wnd)); + while (1) { int code = *src1++; for (int b = 0; b < 8; ++b) { diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h index 7f7babc604..c6abac3ecc 100644 --- a/engines/scumm/he/intern_he.h +++ b/engines/scumm/he/intern_he.h @@ -121,13 +121,24 @@ class ScummEngine_v70he : public ScummEngine_v60he { friend class ResExtractor; protected: + enum HESndFlags { + HE_SND_LOOP = 1, + HE_SND_APPEND = 2, + HE_SND_SOFT_SOUND = 4, + HE_SND_QUICK_START = 8, + HE_SND_OFFSET = 16, + HE_SND_VOL = 32, + HE_SND_FREQUENCY = 64, + HE_SND_PAN = 128 + }; + ResExtractor *_resExtractor; byte *_heV7DiskOffsets; byte *_heV7RoomOffsets; uint32 *_heV7RoomIntOffsets; - int32 _heSndSoundId, _heSndOffset, _heSndChannel, _heSndFlags, _heSndSoundFreq; + int32 _heSndSoundId, _heSndOffset, _heSndChannel, _heSndFlags, _heSndSoundFreq, _heSndPan, _heSndVol; int _numStoredFlObjects; ObjectData *_storedFlObjects; @@ -168,7 +179,7 @@ protected: virtual void setDefaultCursor(); /* HE version 70 script opcodes */ - void o70_startSound(); + void o70_soundOps(); void o70_pickupObject(); void o70_getActorRoom(); void o70_resourceRoutines(); @@ -622,7 +633,7 @@ protected: void o100_redimArray(); void o100_roomOps(); void o100_setSystemMessage(); - void o100_startSound(); + void o100_soundOps(); void o100_setSpriteInfo(); void o100_startScript(); void o100_systemOps(); diff --git a/engines/scumm/he/moonbase/ai_defenseunit.cpp b/engines/scumm/he/moonbase/ai_defenseunit.cpp index 37ce303bc5..ab61297603 100644 --- a/engines/scumm/he/moonbase/ai_defenseunit.cpp +++ b/engines/scumm/he/moonbase/ai_defenseunit.cpp @@ -80,14 +80,14 @@ Common::Point *AntiAirUnit::createTargetPos(int index, int distance, int weaponT targetPos->y = getPosY(); } else { ratio = MAX(0, (getRadius() / distance)); - targetPos->x = getPosX() - ratio * (getPosX() - sourceX); - targetPos->y = getPosY() - ratio * (getPosY() - sourceY); + targetPos->x = (int16)(getPosX() - ratio * (getPosX() - sourceX)); + targetPos->y = (int16)(getPosY() - ratio * (getPosY() - sourceY)); } break; case ITEM_EMP: - if (getRadius() + 215 > distance) { //emp radius + if (getRadius() + 215 > distance) { // Emp radius double x1 = static_cast<double>(sourceX); double y1 = static_cast<double>(sourceY); double x2 = static_cast<double>(getPosX()); @@ -96,17 +96,17 @@ Common::Point *AntiAirUnit::createTargetPos(int index, int distance, int weaponT double r2 = static_cast<double>(getRadius() + 3); double d = static_cast<double>(distance); - //formulae for calculating one point of intersection of two circles + // Formulae for calculating one point of intersection of two circles float root = sqrt((((r1 + r2) * (r1 + r2)) - (d * d)) * ((d * d) - ((r2 - r1) * (r2 - r1)))); - int x = ((x1 + x2) / 2) + ((x2 - x1) * (r1 * r1 - r2 * r2)) / (2 * d * d) + ((y2 - y1) / (2 * d * d)) * root; - int y = ((y1 + y2) / 2) + ((y2 - y1) * (r1 * r1 - r2 * r2)) / (2 * d * d) - ((x2 - x1) / (2 * d * d)) * root; + int x = (int)(((x1 + x2) / 2) + ((x2 - x1) * (r1 * r1 - r2 * r2)) / (2 * d * d) + ((y2 - y1) / (2 * d * d)) * root); + int y = (int)(((y1 + y2) / 2) + ((y2 - y1) * (r1 * r1 - r2 * r2)) / (2 * d * d) - ((x2 - x1) / (2 * d * d)) * root); targetPos->x = x; targetPos->y = y; } else { ratio = 1 - (getRadius() / static_cast<float>(distance - 20)); - targetPos->x = sourceX + ratio * (getPosX() - sourceX); - targetPos->y = sourceY + ratio * (getPosY() - sourceY); + targetPos->x = (int16)(sourceX + ratio * (getPosX() - sourceX)); + targetPos->y = (int16)(sourceY + ratio * (getPosY() - sourceY)); } break; @@ -188,7 +188,7 @@ Common::Point *ShieldUnit::createTargetPos(int index, int distance, int weaponTy break; case ITEM_EMP: - if (getRadius() + 215 > distance) { //emp radius + if (getRadius() + 215 > distance) { // Emp radius double x1 = static_cast<double>(sourceX); double y1 = static_cast<double>(sourceY); double x2 = static_cast<double>(getPosX()); @@ -197,17 +197,17 @@ Common::Point *ShieldUnit::createTargetPos(int index, int distance, int weaponTy double r2 = static_cast<double>(getRadius() + 10); double d = static_cast<double>(distance); - //formulae for calculating one point of intersection of two circles + // Formulae for calculating one point of intersection of two circles float root = sqrt((((r1 + r2) * (r1 + r2)) - (d * d)) * ((d * d) - ((r2 - r1) * (r2 - r1)))); - int x = ((x1 + x2) / 2) + ((x2 - x1) * (r1 * r1 - r2 * r2)) / (2 * d * d) + ((y2 - y1) / (2 * d * d)) * root; - int y = ((y1 + y2) / 2) + ((y2 - y1) * (r1 * r1 - r2 * r2)) / (2 * d * d) - ((x2 - x1) / (2 * d * d)) * root; + int x = (int)(((x1 + x2) / 2) + ((x2 - x1) * (r1 * r1 - r2 * r2)) / (2 * d * d) + ((y2 - y1) / (2 * d * d)) * root); + int y = (int)(((y1 + y2) / 2) + ((y2 - y1) * (r1 * r1 - r2 * r2)) / (2 * d * d) - ((x2 - x1) / (2 * d * d)) * root); targetPos->x = x; targetPos->y = y; } else { ratio = 1 - (getRadius() / static_cast<float>(distance - 20)); - targetPos->x = sourceX + ratio * (getPosX() - sourceX); - targetPos->y = sourceY + ratio * (getPosY() - sourceY); + targetPos->x = (int16)(sourceX + ratio * (getPosX() - sourceX)); + targetPos->y = (int16)(sourceY + ratio * (getPosY() - sourceY)); } if (distance < getRadius()) { @@ -282,8 +282,8 @@ Common::Point *MineUnit::createTargetPos(int index, int distance, int weaponType case ITEM_EMP: ratio = 1 - (getRadius() / static_cast<float>(distance - 20)); - targetPos->x = sourceX + ratio * (getPosX() - sourceX); - targetPos->y = sourceY + ratio * (getPosY() - sourceY); + targetPos->x = (int16)(sourceX + ratio * (getPosX() - sourceX)); + targetPos->y = (int16)(sourceY + ratio * (getPosY() - sourceY)); break; default: diff --git a/engines/scumm/he/moonbase/ai_main.cpp b/engines/scumm/he/moonbase/ai_main.cpp index 7ca4fbd933..98a577bdba 100644 --- a/engines/scumm/he/moonbase/ai_main.cpp +++ b/engines/scumm/he/moonbase/ai_main.cpp @@ -606,7 +606,7 @@ int AI::masterControlProgram(const int paramCount, const int32 *params) { targetX = getHubX(closestHub); targetY = getHubY(closestHub); - delete launchAction; + delete[] launchAction; launchAction = NULL; _aiState = STATE_DEFEND_TARGET; delete myTree; @@ -647,7 +647,7 @@ int AI::masterControlProgram(const int paramCount, const int32 *params) { } } else { index++; - delete launchAction; + delete[] launchAction; launchAction = NULL; } } else { @@ -667,7 +667,7 @@ int AI::masterControlProgram(const int paramCount, const int32 *params) { _aiState = STATE_INIT_ACQUIRE_TARGET; } else { index++; - delete launchAction; + delete[] launchAction; launchAction = NULL; } } @@ -695,7 +695,7 @@ int AI::masterControlProgram(const int paramCount, const int32 *params) { } } else { index++; - delete launchAction; + delete[] launchAction; launchAction = NULL; } } @@ -817,8 +817,7 @@ int AI::masterControlProgram(const int paramCount, const int32 *params) { { // ANGLE setting - int angleAdjustment = 0; - angleAdjustment = _vm->_rnd.getRandomNumber(_aiType[getCurrentPlayer()]->getAngleVariation() * AI_VAR_BASE_ANGLE) * 3.6; + int angleAdjustment = (int)(_vm->_rnd.getRandomNumber(_aiType[getCurrentPlayer()]->getAngleVariation() * AI_VAR_BASE_ANGLE) * 3.6); //pos or neg choice angleAdjustment *= ((_vm->_rnd.getRandomNumber(1) * 2) - 1); angleAdjustment *= randomAttenuation; @@ -2111,7 +2110,7 @@ int *AI::energizeTarget(int &targetX, int &targetY, int index) { break; } - testDist = ((((n - attempt) / n) * .5) + .5) * (getDistance(getHubX(nextUnit), getHubY(nextUnit), targetX, targetY) / .8); + testDist = (((((double)n - (double)attempt) / n) * .5) + .5) * (getDistance(getHubX(nextUnit), getHubY(nextUnit), targetX, targetY) / .8); xPos = getHubX(nextUnit) + testDist * cos(degToRad(testAngle)); yPos = getHubY(nextUnit) + testDist * sin(degToRad(testAngle)); } diff --git a/engines/scumm/he/moonbase/ai_targetacquisition.cpp b/engines/scumm/he/moonbase/ai_targetacquisition.cpp index 938a02dba3..313ea7a411 100644 --- a/engines/scumm/he/moonbase/ai_targetacquisition.cpp +++ b/engines/scumm/he/moonbase/ai_targetacquisition.cpp @@ -226,7 +226,7 @@ IContainedObject *Sortie::createChildObj(int index, int &completionFlag) { if (!_ai->_vm->_rnd.getRandomNumber(4)) currentWeapon->setTypeID(ITEM_MINE); - (*i)->setDamage(thisDamage); + (*i)->setDamage((int)thisDamage); // Apply emp effect if (currentWeapon->getTypeID() == ITEM_EMP) { @@ -278,7 +278,8 @@ float Sortie::calcH() { } int Sortie::checkSuccess() { - if (!_enemyDefenses.size()) return SUCCESS; + if (!_enemyDefenses.size()) + return SUCCESS; int targetX = getTargetPosX(); int targetY = getTargetPosY(); @@ -319,6 +320,15 @@ void Sortie::printEnemyDefenses() { } } +Defender::Defender(AI *ai) : _ai(ai) { + _sourceX = _sourceY = 0; + _targetX = _targetY = 0; + _sourceUnit = 0; + _power = 0; + _angle = 0; + _unit = 0; +} + int Defender::calculateDefenseUnitPosition(int targetX, int targetY, int index) { int currentPlayer = _ai->getCurrentPlayer(); @@ -431,8 +441,8 @@ int Defender::calculateDefenseUnitPosition(int targetX, int targetY, int index) int randAngle = directAngleToHub + _ai->_vm->_rnd.getRandomNumber(179) - 90; int randDist = _ai->_vm->_rnd.getRandomNumber(109) + 40; - int x = targetX + randDist * cos(_ai->degToRad(randAngle)); - int y = targetY + randDist * sin(_ai->degToRad(randAngle)); + int x = (int)(targetX + randDist * cos(_ai->degToRad(randAngle))); + int y = (int)(targetY + randDist * sin(_ai->degToRad(randAngle))); int powAngle = _ai->getPowerAngleFromPoint(hubX, hubY, x, y, 20); @@ -496,8 +506,8 @@ int Defender::calculateDefenseUnitPosition(int targetX, int targetY, int index) int xDist = xCoord - x; int yDist = yCoord - y; - x = xCoord + (terrainSquareSize * 1.414 * (xDist / (abs(xDist) + 1))); - y = yCoord + (terrainSquareSize * 1.414 * (yDist / (abs(yDist) + 1))); + x = (int)(xCoord + (terrainSquareSize * 1.414 * (xDist / (abs(xDist) + 1)))); + y = (int)(yCoord + (terrainSquareSize * 1.414 * (yDist / (abs(yDist) + 1)))); setTargetX(x); setTargetY(y); diff --git a/engines/scumm/he/moonbase/ai_targetacquisition.h b/engines/scumm/he/moonbase/ai_targetacquisition.h index 9afe0f50ab..5e6cfed8bc 100644 --- a/engines/scumm/he/moonbase/ai_targetacquisition.h +++ b/engines/scumm/he/moonbase/ai_targetacquisition.h @@ -112,7 +112,7 @@ private: AI *_ai; public: - Defender(AI *ai) : _ai(ai) {} + Defender(AI *ai); void setSourceX(int sourceX) { _sourceX = sourceX; } void setSourceY(int sourceY) { _sourceY = sourceY; } void setTargetX(int targetX) { _targetX = targetX; } diff --git a/engines/scumm/he/moonbase/ai_traveller.cpp b/engines/scumm/he/moonbase/ai_traveller.cpp index 8294ea32b5..d6eea67b41 100644 --- a/engines/scumm/he/moonbase/ai_traveller.cpp +++ b/engines/scumm/he/moonbase/ai_traveller.cpp @@ -46,6 +46,8 @@ Traveller::Traveller(AI *ai) : _ai(ai) { _waterSourceY = 0; _waterDestX = 0; _waterDestY = 0; + + _posX = _posY = 0; } Traveller::Traveller(int originX, int originY, AI *ai) : _ai(ai) { @@ -143,10 +145,10 @@ IContainedObject *Traveller::createChildObj(int index, int &completionFlag) { if (directDist > _maxDist + 120) maxPower = _ai->getMaxPower(); else - maxPower = (static_cast<float>(directDist) / static_cast<float>(_maxDist + 120)) * _ai->getMaxPower(); + maxPower = (int)((static_cast<float>(directDist) / static_cast<float>(_maxDist + 120)) * _ai->getMaxPower()); maxPower -= 70; - power = maxPower * (1 - ((index % NUM_POWER_STEPS) * SIZE_POWER_STEP)); + power = (int)(maxPower * (1 - ((index % NUM_POWER_STEPS) * SIZE_POWER_STEP))); } retTraveller->setAngleTo(angle); @@ -188,8 +190,8 @@ IContainedObject *Traveller::createChildObj(int index, int &completionFlag) { float pwr = _ai->getMinPower() * .3; float cosine = cos((static_cast<float>(angle) / 360) * (2 * M_PI)); float sine = sin((static_cast<float>(angle) / 360) * (2 * M_PI)); - int xParam = xCoord + (pwr * cosine); - int yParam = yCoord + (pwr * sine); + int xParam = (int)(xCoord + (pwr * cosine)); + int yParam = (int)(yCoord + (pwr * sine)); if (xParam < 0) xParam += _ai->getMaxX(); @@ -233,8 +235,8 @@ IContainedObject *Traveller::createChildObj(int index, int &completionFlag) { int xDist = xCoord - _posX; int yDist = yCoord - _posY; - retTraveller->setPosX(xCoord + (terrainSquareSize * 1.414 * (xDist / (abs(xDist) + 1)))); - retTraveller->setPosY(yCoord + (terrainSquareSize * 1.414 * (yDist / (abs(yDist) + 1)))); + retTraveller->setPosX((int)(xCoord + (terrainSquareSize * 1.414 * (xDist / (abs(xDist) + 1))))); + retTraveller->setPosY((int)(yCoord + (terrainSquareSize * 1.414 * (yDist / (abs(yDist) + 1))))); int closestHub = _ai->getClosestUnit(retTraveller->getPosX(), retTraveller->getPosY(), _ai->getMaxX(), _ai->getCurrentPlayer(), 1, BUILDING_MAIN_BASE, 1, 110); diff --git a/engines/scumm/he/moonbase/ai_tree.cpp b/engines/scumm/he/moonbase/ai_tree.cpp index e3098a7b24..d18536812b 100644 --- a/engines/scumm/he/moonbase/ai_tree.cpp +++ b/engines/scumm/he/moonbase/ai_tree.cpp @@ -29,7 +29,12 @@ namespace Scumm { static int compareTreeNodes(const void *a, const void *b) { - return ((const TreeNode *)a)->value - ((const TreeNode *)b)->value; + if (((const TreeNode *)a)->value < ((const TreeNode *)b)->value) + return -1; + else if (((const TreeNode *)a)->value > ((const TreeNode *)b)->value) + return 1; + else + return 0; } Tree::Tree(AI *ai) : _ai(ai) { diff --git a/engines/scumm/he/moonbase/ai_types.h b/engines/scumm/he/moonbase/ai_types.h index e2de87d653..bb16a737e9 100644 --- a/engines/scumm/he/moonbase/ai_types.h +++ b/engines/scumm/he/moonbase/ai_types.h @@ -72,7 +72,7 @@ public: AIEntity(int id); ~AIEntity() { if (_nameString) { - delete _nameString; + delete[] _nameString; _nameString = 0; } } diff --git a/engines/scumm/he/moonbase/distortion.cpp b/engines/scumm/he/moonbase/distortion.cpp new file mode 100644 index 0000000000..6b637d0565 --- /dev/null +++ b/engines/scumm/he/moonbase/distortion.cpp @@ -0,0 +1,218 @@ +/* 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 "scumm/he/intern_he.h" +#include "engines/scumm/he/moonbase/moonbase.h" + +namespace Scumm { + +enum { + kBptHeaderSize = 8, + + kReflectionClipped = 0, + kNotClipped = 1, + kSpecializedNotClipped = 2 +}; + +static void blitDistortionCore( + Graphics::Surface *dstBitmap, + const int x, const int y, + const Graphics::Surface *distortionBitmap, + const Common::Rect *optionalclipRectPtr, + int transferOp, + const Graphics::Surface *srcBitmap, + Common::Rect *srcClipRect +) { + Common::Rect clipRect(dstBitmap->w, dstBitmap->h); + + if (optionalclipRectPtr) + if (!clipRect.intersects(*optionalclipRectPtr)) + return; + + clipRect.clip(*optionalclipRectPtr); + + Common::Rect distortionRect(distortionBitmap->w, distortionBitmap->h); + Common::Rect dstRect(x, y, x + distortionRect.width(), y + distortionRect.height()); + + if (!dstRect.intersects(clipRect)) + return; + + dstRect.clip(clipRect); + + distortionRect.moveTo(dstRect.left - x, dstRect.top - y); + + const byte *distortionPtr = (const byte *)distortionBitmap->getBasePtr(distortionRect.left, distortionRect.top); + byte *dstPtr = (byte *)dstBitmap->getBasePtr(dstRect.left, dstRect.top); + int cw = dstRect.width(); + int ch = dstRect.height(); + int idx = dstRect.left; + int dy = dstRect.top; + + int baseX, baseY; + const byte *srcData = (const byte *)srcBitmap->getBasePtr(0, 0); + int srcPitch = srcBitmap->pitch; + + switch (transferOp) { + case kReflectionClipped: + case kNotClipped: + baseX = -(0x1f / 2); // Half range + baseY = -(0x1f / 2); + break; + + case kSpecializedNotClipped: + default: + baseX = 0; + baseY = 0; + } + + while (--ch >= 0) { + uint16 *d = (uint16 *)dstPtr; + const uint16 *is = (const uint16 *)distortionPtr; + int dx = idx; + + for (int i = cw; --i >= 0;) { + uint16 p = READ_LE_UINT16(is); + int sx = baseX + dx + ((p >> 5) & 0x1f); // G color + int sy = baseY + dy + (p & 0x1f); // B color; + + if (transferOp == kReflectionClipped) { + if (sx < srcClipRect->left) + sx -= (srcClipRect->left - sx); + + if (sx > srcClipRect->right) + sx -= (sx - srcClipRect->right); + + sx = MAX<int>(srcClipRect->left, MIN<int>(sx, srcClipRect->right)); + + if (sy < srcClipRect->top) + sy -= (srcClipRect->top - sy); + + if (sy > srcClipRect->bottom) + sy -= (sy - srcClipRect->bottom); + + sy = MAX<int>(srcClipRect->top, MIN<int>(sy, srcClipRect->bottom)); + } + + *d = *((const uint16 *)(srcData + sy * srcPitch + sx * 2)); + + ++d; + ++is; + ++dx; + } + + dstPtr += dstBitmap->pitch; + distortionPtr += distortionBitmap->pitch; + + ++dy; + } +} + +void Moonbase::blitDistortion(byte *bufferData, const int bufferWidth, const int bufferHeight, const int bufferPitch, + const Common::Rect *optionalClippingRect, byte *dataStream, const int x, const int y, byte *altSourceBuffer) { + byte *sourcePixels = (altSourceBuffer) ? altSourceBuffer : bufferData; + Common::Rect dstLimitsRect(bufferWidth, bufferHeight); + Common::Rect clippedDstRect = dstLimitsRect; + + if (optionalClippingRect) { + if (!dstLimitsRect.intersects(*optionalClippingRect)) + return; + dstLimitsRect.clip(*optionalClippingRect); + } else { + clippedDstRect = dstLimitsRect; + } + + int w = READ_LE_UINT16(dataStream + kBptHeaderSize + 0); + int h = READ_LE_UINT16(dataStream + kBptHeaderSize + 2); + Common::Rect srcLimitsRect(w, h); + Common::Rect clippedSrcRect = srcLimitsRect; + Common::Rect dstOperation(x, y, x + clippedSrcRect.width(), y + clippedSrcRect.height()); + + if (!clippedDstRect.intersects(dstOperation)) + return; + + clippedDstRect.clip(dstOperation); + + int subBlockCount = READ_LE_UINT16(dataStream + kBptHeaderSize + 4); + byte *subBlockStream = dataStream + kBptHeaderSize + READ_LE_UINT32(dataStream + 4); + int cx1 = clippedDstRect.left; + int cy1 = clippedDstRect.top; + int cx2 = clippedDstRect.right - 1; + int cy2 = clippedDstRect.bottom - 1; + + for (int i = 0; i < subBlockCount; i++) { + byte *blockData = subBlockStream; + uint32 blockSize = READ_LE_UINT32(blockData); blockData += 4; + subBlockStream += blockSize; + int xOffset = READ_LE_UINT16(blockData); blockData += 2; + int yOffset = READ_LE_UINT16(blockData); blockData += 2; + int width = READ_LE_UINT16(blockData); blockData += 2; + int height = READ_LE_UINT16(blockData); blockData += 2; + int l_reach = READ_LE_UINT16(blockData); blockData += 2; + int r_reach = READ_LE_UINT16(blockData); blockData += 2; + int t_reach = READ_LE_UINT16(blockData); blockData += 2; + int b_reach = READ_LE_UINT16(blockData); blockData += 2; + int distortionPitch = ((width * 2 + 7) / 8); // 2 for 555 + + if (width == 0 && height == 0) + continue; + + Graphics::Surface dstBitmap; + dstBitmap.init(bufferWidth, bufferHeight, bufferPitch, bufferData, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)); + + Graphics::Surface srcBitmap; + srcBitmap.init(bufferWidth, bufferHeight, bufferPitch, sourcePixels, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)); + + Graphics::Surface distortionBitmap; + distortionBitmap.init(width, height, distortionPitch, blockData, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)); + + Common::Rect srcClipRect(cx1, cy1, cx2, cy2); + Common::Rect dstClipRect(cx1, cy1, cx2, cy2); + + int src_x = (x + xOffset); + int src_y = (y + yOffset); + + Common::Rect srcReach((src_x - l_reach), (src_y - t_reach), (src_x + r_reach), (src_y + b_reach)); + Common::Rect srcLimits(srcBitmap.w, srcBitmap.h); + + if (!srcLimits.intersects(srcClipRect)) + return; + + srcLimits.clip(srcClipRect); + + if (!srcReach.intersects(srcLimits)) + return; + + srcReach.clip(srcLimits); + + if (srcLimits.contains(srcReach)) { + if (srcBitmap.pitch == 1280) { + blitDistortionCore(&dstBitmap, src_x, src_y, &distortionBitmap, &dstClipRect, kSpecializedNotClipped, &srcBitmap, 0); + } else { + blitDistortionCore(&dstBitmap, src_x, src_y, &distortionBitmap, &dstClipRect, kNotClipped, &srcBitmap, 0); + } + } else { + blitDistortionCore(&dstBitmap, src_x, src_y, &distortionBitmap, &dstClipRect, kReflectionClipped, &srcBitmap, &srcLimits); + } + } +} + +} diff --git a/engines/scumm/he/moonbase/moonbase.h b/engines/scumm/he/moonbase/moonbase.h index 243d53a11d..71c03cb007 100644 --- a/engines/scumm/he/moonbase/moonbase.h +++ b/engines/scumm/he/moonbase/moonbase.h @@ -42,6 +42,8 @@ public: void blitT14WizImage(uint8 *dst, int dstw, int dsth, int dstPitch, const Common::Rect *clipBox, uint8 *wizd, int srcx, int srcy, int rawROP, int paramROP); + void blitDistortion(byte *bufferData, const int bufferWidth, const int bufferHeight, const int bufferPitch, + const Common::Rect *optionalClippingRect, byte *dataStream, const int x, const int y, byte *altSourceBuffer); // FOW Stuff bool isFOW(int resNum, int state, uint32 conditionBits) { @@ -98,7 +100,7 @@ private: bool _fowBlackMode; - int _fowRenderTable[32768]; + int32 _fowRenderTable[32768]; Common::PEResources _exe; Common::String _fileName; diff --git a/engines/scumm/he/moonbase/moonbase_fow.cpp b/engines/scumm/he/moonbase/moonbase_fow.cpp index 48c2219926..0837d9eea3 100644 --- a/engines/scumm/he/moonbase/moonbase_fow.cpp +++ b/engines/scumm/he/moonbase/moonbase_fow.cpp @@ -59,7 +59,7 @@ void Moonbase::initFOW() { _fowBlackMode = true; - memset(_fowRenderTable, 0, 32768); + memset(_fowRenderTable, 0, sizeof(_fowRenderTable)); } void Moonbase::releaseFOWResources() { @@ -114,8 +114,14 @@ bool Moonbase::setFOWImage(int image) { delete stream; } - if (!_fowImage && image > 0) - _fowImage = _vm->getResourceAddress(rtImage, image); + if (!_fowImage && image > 0) { + int sz = _vm->getResourceSize(rtImage, image); + _fowImage = (uint8 *)malloc(sz); + + // We have to copy it, otherwise the resource manager + // will kill it earlier or later. Matches original. + memcpy(_fowImage, _vm->getResourceAddress(rtImage, image), sz); + } if (!_fowImage) return false; @@ -158,7 +164,7 @@ enum FOWElement { }; int Moonbase::readFOWVisibilityArray(int array, int y, int x) { - if (readFromArray(array, y, x) > 0) + if (readFromArray(array, x, y) > 0) return FOW_EMPTY; return FOW_SOLID; @@ -169,6 +175,8 @@ void Moonbase::setFOWInfo(int fowInfoArray, int downDim, int acrossDim, int view if (!_fowImage) return; + memset(_fowRenderTable, 0, sizeof(_fowRenderTable)); + _fowDrawX = clipX1; _fowDrawY = clipY1; @@ -210,16 +218,16 @@ void Moonbase::setFOWInfo(int fowInfoArray, int downDim, int acrossDim, int view int dataOffset = (_fowVw * 3); int dataOffset2 = (dataOffset * 2); - int *pOutterRenderTableA = _fowRenderTable; - int *pOutterRenderTableB = pOutterRenderTableA + dataOffset; + int32 *pOutterRenderTableA = _fowRenderTable; + int32 *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; + int32 *pRenderTableA = pOutterRenderTableA; + int32 *pRenderTableB = pOutterRenderTableB; pOutterRenderTableA += dataOffset2; pOutterRenderTableB += dataOffset2; @@ -228,7 +236,7 @@ void Moonbase::setFOWInfo(int fowInfoArray, int downDim, int acrossDim, int view int visibility = readFOWVisibilityArray(fowInfoArray, m, c); if (visibility == FOW_EMPTY) { - int bits = 0; + uint32 bits = 0; if (readFOWVisibilityArray(fowInfoArray, t, l) != 0) bits |= FF_T_L; if (readFOWVisibilityArray(fowInfoArray, t, c) != 0) bits |= FF_T; @@ -333,7 +341,7 @@ static void blackRect_16bpp(uint8 *destSurface, int dstPitch, int dstw, int dsth int h = y2 - y1; int w = ((x2 - x1) + 1) * 2; - while ( --h >= 0 ) { + while (--h >= 0) { memset(dst, 0, w); dst += dstPitch; } @@ -343,7 +351,7 @@ void Moonbase::renderFOW(uint8 *destSurface, int dstPitch, int dstType, int dstw if (!_fowImage) return; - const int *pOutterRenderTable = _fowRenderTable; + const int32 *pOutterRenderTable = _fowRenderTable; int ixPos = ((_fowVtx1 * _fowTileW) - _fowMvx) + _fowDrawX; int yPos = ((_fowVty1 * _fowTileH) - _fowMvy) + _fowDrawY; int dataOffset = _fowVw * 3; @@ -355,7 +363,7 @@ void Moonbase::renderFOW(uint8 *destSurface, int dstPitch, int dstType, int dstw int real_yPos = yPos; for (int i = 0; i < 2; i++) { - const int *pRenderTable = pOutterRenderTable; + const int32 *pRenderTable = pOutterRenderTable; pOutterRenderTable += dataOffset; int xPos = ixPos; diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp index 2e7b4c4bf5..714f431188 100644 --- a/engines/scumm/he/script_v100he.cpp +++ b/engines/scumm/he/script_v100he.cpp @@ -184,7 +184,7 @@ void ScummEngine_v100he::setupOpcodes() { OPCODE(0x74, o6_delay); OPCODE(0x75, o6_delayMinutes); OPCODE(0x76, o6_delaySeconds); - OPCODE(0x77, o100_startSound); + OPCODE(0x77, o100_soundOps); /* 78 */ OPCODE(0x78, o80_sourceDebug); OPCODE(0x79, o100_setSpriteInfo); @@ -643,6 +643,11 @@ void ScummEngine_v100he::o100_arrayOps() { dim2end = pop(); dim2start = pop(); + debug(0, "Complex: %d = %d[%d to %d][%d to %d] %c %d[%d to %d][%d to %d]", array, + array1, a1_dim1start, a1_dim2end, a1_dim1start, a1_dim2end, + " +-&|^"[type], + array2, a2_dim1start, a2_dim2end, a2_dim1start, a2_dim2end); + int a12_num = a1_dim2end - a1_dim2start + 1; int a11_num = a1_dim1end - a1_dim1start + 1; int a22_num = a2_dim2end - a2_dim2start + 1; @@ -689,8 +694,6 @@ void ScummEngine_v100he::o100_arrayOps() { writeArray(array, dim2start, dim1, res); } } - - warning("STUB: o100_arrayOps: case 132 type %d", type); break; } case 133: // SO_RANGE_ARRAY_ASSIGNMENT @@ -1739,69 +1742,69 @@ void ScummEngine_v100he::o100_setSystemMessage() { } } -void ScummEngine_v100he::o100_startSound() { +void ScummEngine_v100he::o100_soundOps() { byte filename[260]; int var, value; byte subOp = fetchScriptByte(); switch (subOp) { - case 6: - _heSndFlags |= 16; + case 6: // SO_AT + _heSndFlags |= HE_SND_OFFSET; _heSndOffset = pop(); break; - case 47: + case 47: // SO_LOAD copyScriptString(filename, sizeof(filename)); _heSndSoundId = pop(); if (_heSndSoundId) debug(0, "Load sound %d from file %s\n", _heSndSoundId, filename); break; - case 55: - _heSndFlags |= 8; + case 55: // SO_NOW + _heSndFlags |= HE_SND_QUICK_START; break; - case 83: + case 83: // SO_VARIABLE value = pop(); var = pop(); _heSndSoundId = pop(); ((SoundHE *)_sound)->setSoundVar(_heSndSoundId, var, value); break; - case 92: - _sound->addSoundToQueue(_heSndSoundId, _heSndOffset, _heSndChannel, _heSndFlags); + case 92: // SO_END + _sound->addSoundToQueue(_heSndSoundId, _heSndOffset, _heSndChannel, _heSndFlags, _heSndSoundFreq, _heSndPan, _heSndVol); break; - case 128: - _heSndFlags |= 2; + case 128: // SO_SOUND_ADD + _heSndFlags |= HE_SND_APPEND; break; - case 129: + case 129: // SO_SOUND_CHANNEL _heSndChannel = pop(); break; - case 130: - _heSndFlags |= 64; - pop(); + case 130: // SO_SOUND_FREQUENCY + _heSndFlags |= HE_SND_FREQUENCY; + _heSndSoundFreq = pop(); break; - case 131: - _heSndFlags |= 1; + case 131: // SO_SOUND_LOOPING + _heSndFlags |= HE_SND_LOOP; break; - case 132: // Music - case 134: // Sound + case 132: // SO_SOUND_MODIFY + case 134: // SO_SOUND_START _heSndSoundId = pop(); _heSndOffset = 0; _heSndSoundFreq = 11025; _heSndChannel = VAR(VAR_SOUND_CHANNEL); _heSndFlags = 0; break; - case 133: - _heSndFlags |= 128; - pop(); + case 133: // SO_SOUND_PAN + _heSndFlags |= HE_SND_PAN; + _heSndPan = pop(); break; - case 135: - _heSndFlags |= 4; + case 135: // SO_SOUND_SOFT + _heSndFlags |= HE_SND_SOFT_SOUND; break; - case 136: - _heSndFlags |= 32; - pop(); + case 136: // SO_SOUND_VOLUME + _heSndFlags |= HE_SND_VOL; + _heSndVol = pop(); break; default: - error("o100_startSound invalid case %d", subOp); + error("o100_soundOps invalid case %d", subOp); } } @@ -2572,62 +2575,62 @@ void ScummEngine_v100he::o100_getWizData() { byte subOp = fetchScriptByte(); switch (subOp) { - case 20: + case 20: // SO_COLOR y = pop(); x = pop(); state = pop(); resId = pop(); push(_wiz->getWizPixelColor(resId, state, x, y)); break; - case 26: + case 26: // SO_COUNT resId = pop(); push(_wiz->getWizImageStates(resId)); break; - case 33: + case 33: // SO_FIND y = pop(); x = pop(); state = pop(); resId = pop(); push(_wiz->isWizPixelNonTransparent(resId, state, x, y, 0)); break; - case 39: + case 39: // SO_HEIGHT state = pop(); resId = pop(); _wiz->getWizImageDim(resId, state, w, h); push(h); break; - case 54: + case 54: // SO_NEW_GENERAL_PROPERTY type = pop(); state = pop(); resId = pop(); push(_wiz->getWizImageData(resId, state, type)); break; - case 84: + case 84: // SO_WIDTH state = pop(); resId = pop(); _wiz->getWizImageDim(resId, state, w, h); push(w); break; - case 85: + case 85: // SO_XPOS state = pop(); resId = pop(); _wiz->getWizImageSpot(resId, state, x, y); push(x); break; - case 86: + case 86: // SO_YPOS state = pop(); resId = pop(); _wiz->getWizImageSpot(resId, state, x, y); push(y); break; - case 131: + case 131: // SO_FONT_START pop(); copyScriptString(filename, sizeof(filename)); pop(); push(0); debug(0, "o100_getWizData() case 111 unhandled"); break; - case 132: + case 132: // SO_HISTOGRAM h = pop(); w = pop(); y = pop(); diff --git a/engines/scumm/he/script_v70he.cpp b/engines/scumm/he/script_v70he.cpp index b91943c685..0bdeb3211e 100644 --- a/engines/scumm/he/script_v70he.cpp +++ b/engines/scumm/he/script_v70he.cpp @@ -39,7 +39,7 @@ namespace Scumm { void ScummEngine_v70he::setupOpcodes() { ScummEngine_v60he::setupOpcodes(); - OPCODE(0x74, o70_startSound); + OPCODE(0x74, o70_soundOps); OPCODE(0x84, o70_pickupObject); OPCODE(0x8c, o70_getActorRoom); OPCODE(0x9b, o70_resourceRoutines); @@ -52,60 +52,60 @@ void ScummEngine_v70he::setupOpcodes() { OPCODE(0xfa, o70_setSystemMessage); } -void ScummEngine_v70he::o70_startSound() { +void ScummEngine_v70he::o70_soundOps() { int var, value; byte subOp = fetchScriptByte(); switch (subOp) { - case 9: - _heSndFlags |= 4; + case 9: // SO_SOUND_SOFT? + _heSndFlags |= HE_SND_SOFT_SOUND; break; - case 23: + case 23: // SO_VARIABLE value = pop(); var = pop(); _heSndSoundId = pop(); ((SoundHE *)_sound)->setSoundVar(_heSndSoundId, var, value); break; - case 25: + case 25: // SO_SOUND_VOLUME value = pop(); _heSndSoundId = pop(); - _sound->addSoundToQueue(_heSndSoundId, 0, 0, 8); + _sound->addSoundToQueue(_heSndSoundId, 0, 0, HE_SND_VOL, 0, 0, value); break; - case 56: - _heSndFlags |= 16; + case 56: // SO_NOW + _heSndFlags |= HE_SND_QUICK_START; break; - case 164: - _heSndFlags |= 2; + case 164: // SO_SOUND_ADD + _heSndFlags |= HE_SND_APPEND; break; case 222: // WORKAROUND: For errors in room script 240 (room 4) of maze break; - case 224: + case 224: // SO_SOUND_FREQUENCY _heSndSoundFreq = pop(); break; - case 230: + case 230: // SO_SOUND_CHANNEL _heSndChannel = pop(); break; - case 231: + case 231: // SO_AT _heSndOffset = pop(); break; - case 232: + case 232: // SO_SOUND_START _heSndSoundId = pop(); _heSndOffset = 0; _heSndSoundFreq = 11025; _heSndChannel = VAR(VAR_SOUND_CHANNEL); break; - case 245: - _heSndFlags |= 1; + case 245: // SO_SOUND_LOOPING + _heSndFlags |= HE_SND_LOOP; break; - case 255: - _sound->addSoundToQueue(_heSndSoundId, _heSndOffset, _heSndChannel, _heSndFlags); + case 255: // SO_END + _sound->addSoundToQueue(_heSndSoundId, _heSndOffset, _heSndChannel, _heSndFlags, _heSndSoundFreq); _heSndFlags = 0; break; default: - error("o70_startSound invalid case %d", subOp); + error("o70_soundOps invalid case %d", subOp); } } diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp index 8670116c68..9da3641064 100644 --- a/engines/scumm/he/sound_he.cpp +++ b/engines/scumm/he/sound_he.cpp @@ -59,31 +59,29 @@ SoundHE::~SoundHE() { delete[] _heSoundChannels; } -void SoundHE::addSoundToQueue(int sound, int heOffset, int heChannel, int heFlags) { +void SoundHE::addSoundToQueue(int sound, int heOffset, int heChannel, int heFlags, int heFreq, int hePan, int heVol) { if (_vm->VAR_LAST_SOUND != 0xFF) _vm->VAR(_vm->VAR_LAST_SOUND) = sound; - if ((_vm->_game.heversion <= 99 && (heFlags & 16)) || (_vm->_game.heversion >= 100 && (heFlags & 8))) { - playHESound(sound, heOffset, heChannel, heFlags); - return; + if (heFlags & 8) { + playHESound(sound, heOffset, heChannel, heFlags, heFreq, hePan, heVol); } else { - - Sound::addSoundToQueue(sound, heOffset, heChannel, heFlags); + Sound::addSoundToQueue(sound, heOffset, heChannel, heFlags, heFreq, hePan, heVol); } } -void SoundHE::addSoundToQueue2(int sound, int heOffset, int heChannel, int heFlags) { +void SoundHE::addSoundToQueue2(int sound, int heOffset, int heChannel, int heFlags, int heFreq, int hePan, int heVol) { int i = _soundQue2Pos; while (i--) { if (_soundQue2[i].sound == sound && !(heFlags & 2)) return; } - Sound::addSoundToQueue2(sound, heOffset, heChannel, heFlags); + Sound::addSoundToQueue2(sound, heOffset, heChannel, heFlags, heFreq, hePan, heVol); } void SoundHE::processSoundQueues() { - int snd, heOffset, heChannel, heFlags; + int snd, heOffset, heChannel, heFlags, heFreq, hePan, heVol; if (_vm->_game.heversion >= 72) { for (int i = 0; i <_soundQue2Pos; i++) { @@ -91,8 +89,11 @@ void SoundHE::processSoundQueues() { heOffset = _soundQue2[i].offset; heChannel = _soundQue2[i].channel; heFlags = _soundQue2[i].flags; + heFreq = _soundQue2[_soundQue2Pos].freq; + hePan = _soundQue2[_soundQue2Pos].pan; + heVol = _soundQue2[_soundQue2Pos].vol; if (snd) - playHESound(snd, heOffset, heChannel, heFlags); + playHESound(snd, heOffset, heChannel, heFlags, heFreq, hePan, heVol); } _soundQue2Pos = 0; } else { @@ -102,8 +103,11 @@ void SoundHE::processSoundQueues() { heOffset = _soundQue2[_soundQue2Pos].offset; heChannel = _soundQue2[_soundQue2Pos].channel; heFlags = _soundQue2[_soundQue2Pos].flags; + heFreq = _soundQue2[_soundQue2Pos].freq; + hePan = _soundQue2[_soundQue2Pos].pan; + heVol = _soundQue2[_soundQue2Pos].vol; if (snd) - playHESound(snd, heOffset, heChannel, heFlags); + playHESound(snd, heOffset, heChannel, heFlags, heFreq, hePan, heVol); } } @@ -527,7 +531,7 @@ byte *findSoundTag(uint32 tag, byte *ptr) { return NULL; } -void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) { +void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags, int heFreq, int hePan, int heVol) { Audio::RewindableAudioStream *stream = 0; byte *ptr, *spoolPtr; int size = -1; diff --git a/engines/scumm/he/sound_he.h b/engines/scumm/he/sound_he.h index e0324d0753..d5a2817a0f 100644 --- a/engines/scumm/he/sound_he.h +++ b/engines/scumm/he/sound_he.h @@ -61,8 +61,8 @@ public: SoundHE(ScummEngine *parent, Audio::Mixer *mixer); ~SoundHE(); - virtual void addSoundToQueue(int sound, int heOffset = 0, int heChannel = 0, int heFlags = 0); - virtual void addSoundToQueue2(int sound, int heOffset = 0, int heChannel = 0, int heFlags = 0); + virtual void addSoundToQueue(int sound, int heOffset = 0, int heChannel = 0, int heFlags = 0, int heFreq = 0, int hePan = 0, int heVol = 0); + virtual void addSoundToQueue2(int sound, int heOffset = 0, int heChannel = 0, int heFlags = 0, int heFreq = 0, int hePan = 0, int heVol = 0); virtual int isSoundRunning(int sound) const; virtual void stopSound(int sound); @@ -75,7 +75,7 @@ public: int getSoundPos(int sound); int getSoundVar(int sound, int var); void setSoundVar(int sound, int var, int val); - void playHESound(int soundID, int heOffset, int heChannel, int heFlags); + void playHESound(int soundID, int heOffset, int heChannel, int heFlags, int heFreq, int hePan, int heVol); void processSoundCode(); void processSoundOpcodes(int sound, byte *codePtr, int *soundVars); void setOverrideFreq(int freq); diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp index 428960f673..9339318d19 100644 --- a/engines/scumm/he/wiz_he.cpp +++ b/engines/scumm/he/wiz_he.cpp @@ -1748,7 +1748,7 @@ void Wiz::copyCompositeWizImage(uint8 *dst, uint8 *wizPtr, uint8 *compositeInfoB drawFlags = flags; } - uint srcw1, srch1; + uint srcw1 = 0, srch1 = 0; if (drawFlags & (kWIFFlipX | kWIFFlipY)) { uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), wizPtr, subState, 0); assert(wizh); @@ -1816,11 +1816,10 @@ void Wiz::copy555WizImage(uint8 *dst, uint8 *wizd, int dstPitch, int dstType, if (compID == 0x12340102) { ((ScummEngine_v100he *)_vm)->_moonbase->blitT14WizImage(dst, dstw, dsth, dstPitch, clipBox, wizd, srcx, srcy, rawROP, paramROP); } else if (compID == 0x12340802) { - warning("Distorion codec"); + ((ScummEngine_v100he *)_vm)->_moonbase->blitDistortion(dst, dstw, dsth, dstPitch, clipBox, wizd, srcx, srcy, 0); } else if (compID == 0x12340902) { error("Unsupported Distortion"); } - } #endif @@ -2790,6 +2789,14 @@ int Wiz::isWizPixelNonTransparent(uint8 *data, int state, int x, int y, int flag int c = READ_LE_UINT32(wizh + 0x0); int w = READ_LE_UINT32(wizh + 0x4); int h = READ_LE_UINT32(wizh + 0x8); + + if (_vm->_game.id == GID_MOONBASE) { + uint16 color = 0xffff; + drawWizImageEx((byte *)&color, data, 0, 2, kDstMemory, 1, 1, -x, -y, w, h, state, 0, 0, 0, 0, 2, 0, 0); + + return color != 0xffff; + } + uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), data, state, 0); assert(wizd); if (x >= 0 && x < w && y >= 0 && y < h) { @@ -2841,6 +2848,13 @@ uint16 Wiz::getWizPixelColor(int resNum, int state, int x, int y) { int c = READ_LE_UINT32(wizh + 0x0); int w = READ_LE_UINT32(wizh + 0x4); int h = READ_LE_UINT32(wizh + 0x8); + + if (_vm->_game.id == GID_MOONBASE) { + drawWizImageEx((byte *)&color, data, 0, 2, kDstMemory, 1, 1, -x, -y, w, h, state, 0, 0, 0, 0, 2, 0, 0); + + return color; + } + uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), data, state, 0); assert(wizd); switch (c) { |