aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm
diff options
context:
space:
mode:
Diffstat (limited to 'engines/scumm')
-rw-r--r--engines/scumm/he/cup_player_he.cpp3
-rw-r--r--engines/scumm/he/intern_he.h17
-rw-r--r--engines/scumm/he/moonbase/ai_defenseunit.cpp32
-rw-r--r--engines/scumm/he/moonbase/ai_main.cpp13
-rw-r--r--engines/scumm/he/moonbase/ai_targetacquisition.cpp22
-rw-r--r--engines/scumm/he/moonbase/ai_targetacquisition.h2
-rw-r--r--engines/scumm/he/moonbase/ai_traveller.cpp14
-rw-r--r--engines/scumm/he/moonbase/ai_tree.cpp7
-rw-r--r--engines/scumm/he/moonbase/ai_types.h2
-rw-r--r--engines/scumm/he/moonbase/distortion.cpp218
-rw-r--r--engines/scumm/he/moonbase/moonbase.h4
-rw-r--r--engines/scumm/he/moonbase/moonbase_fow.cpp32
-rw-r--r--engines/scumm/he/script_v100he.cpp85
-rw-r--r--engines/scumm/he/script_v70he.cpp40
-rw-r--r--engines/scumm/he/sound_he.cpp28
-rw-r--r--engines/scumm/he/sound_he.h6
-rw-r--r--engines/scumm/he/wiz_he.cpp20
-rw-r--r--engines/scumm/module.mk1
-rw-r--r--engines/scumm/scumm.cpp2
-rw-r--r--engines/scumm/sound.cpp12
-rw-r--r--engines/scumm/sound.h7
21 files changed, 429 insertions, 138 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) {
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index 04611ba1b1..85ff1aa4cd 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -147,6 +147,7 @@ MODULE_OBJS += \
he/moonbase/ai_tree.o \
he/moonbase/ai_types.o \
he/moonbase/ai_weapon.o \
+ he/moonbase/distortion.o \
he/moonbase/moonbase.o \
he/moonbase/moonbase_fow.o
endif
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index d5727f2a7c..3b7dea194b 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -805,6 +805,8 @@ ScummEngine_v70he::ScummEngine_v70he(OSystem *syst, const DetectorResult &dr)
_heSndChannel = 0;
_heSndFlags = 0;
_heSndSoundFreq = 0;
+ _heSndPan = 0;
+ _heSndVol = 0;
_numStoredFlObjects = 0;
_storedFlObjects = (ObjectData *)calloc(100, sizeof(ObjectData));
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index 33b7c3108d..a62092f493 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -110,7 +110,7 @@ Sound::~Sound() {
delete _talkChannelHandle;
}
-void Sound::addSoundToQueue(int sound, int heOffset, int heChannel, int heFlags) {
+void Sound::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;
_lastSound = sound;
@@ -119,15 +119,18 @@ void Sound::addSoundToQueue(int sound, int heOffset, int heChannel, int heFlags)
if (sound <= _vm->_numSounds)
_vm->ensureResourceLoaded(rtSound, sound);
- addSoundToQueue2(sound, heOffset, heChannel, heFlags);
+ addSoundToQueue2(sound, heOffset, heChannel, heFlags, heFreq, hePan, heVol);
}
-void Sound::addSoundToQueue2(int sound, int heOffset, int heChannel, int heFlags) {
+void Sound::addSoundToQueue2(int sound, int heOffset, int heChannel, int heFlags, int heFreq, int hePan, int heVol) {
assert(_soundQue2Pos < ARRAYSIZE(_soundQue2));
_soundQue2[_soundQue2Pos].sound = sound;
_soundQue2[_soundQue2Pos].offset = heOffset;
_soundQue2[_soundQue2Pos].channel = heChannel;
_soundQue2[_soundQue2Pos].flags = heFlags;
+ _soundQue2[_soundQue2Pos].freq = heFreq;
+ _soundQue2[_soundQue2Pos].pan = hePan;
+ _soundQue2[_soundQue2Pos].vol = heVol;
_soundQue2Pos++;
}
@@ -806,6 +809,9 @@ void Sound::stopSound(int sound) {
_soundQue2[i].offset = 0;
_soundQue2[i].channel = 0;
_soundQue2[i].flags = 0;
+ _soundQue2[i].freq = 0;
+ _soundQue2[i].pan = 0;
+ _soundQue2[i].vol = 0;
}
}
}
diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h
index 7fdb16371c..bc1e88f76b 100644
--- a/engines/scumm/sound.h
+++ b/engines/scumm/sound.h
@@ -67,6 +67,9 @@ protected:
int32 offset;
int16 channel;
int16 flags;
+ int16 freq;
+ int16 pan;
+ int16 vol;
} _soundQue2[10];
Common::String _sfxFilename;
@@ -101,8 +104,8 @@ public:
public:
Sound(ScummEngine *parent, Audio::Mixer *mixer);
virtual ~Sound();
- 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);
void processSound();
void playSound(int soundID);