aboutsummaryrefslogtreecommitdiff
path: root/engines/m4
diff options
context:
space:
mode:
authorPaul Gilbert2010-07-03 11:50:42 +0000
committerPaul Gilbert2010-07-03 11:50:42 +0000
commit99939109d75816e434f51479bafdc48a987fb008 (patch)
tree6b555c7e6a60dff87348fbf6b8c4e215c708948a /engines/m4
parent42dfdea5df648cbf1a7778ac8848d752d0f144bb (diff)
downloadscummvm-rg350-99939109d75816e434f51479bafdc48a987fb008.tar.gz
scummvm-rg350-99939109d75816e434f51479bafdc48a987fb008.tar.bz2
scummvm-rg350-99939109d75816e434f51479bafdc48a987fb008.zip
Adding the beginnings of a player control class, as well as various changes to the other classes to support it
svn-id: r50620
Diffstat (limited to 'engines/m4')
-rw-r--r--engines/m4/globals.h1
-rw-r--r--engines/m4/m4.h2
-rw-r--r--engines/m4/mads_logic.cpp73
-rw-r--r--engines/m4/mads_logic.h2
-rw-r--r--engines/m4/mads_player.cpp193
-rw-r--r--engines/m4/mads_player.h66
-rw-r--r--engines/m4/mads_scene.cpp123
-rw-r--r--engines/m4/mads_scene.h32
-rw-r--r--engines/m4/mads_views.cpp8
-rw-r--r--engines/m4/mads_views.h2
-rw-r--r--engines/m4/module.mk1
11 files changed, 433 insertions, 70 deletions
diff --git a/engines/m4/globals.h b/engines/m4/globals.h
index 0217a96777..5ab1ccd9a6 100644
--- a/engines/m4/globals.h
+++ b/engines/m4/globals.h
@@ -252,6 +252,7 @@ public:
MadsDialogType dialogType;
int sceneNumber;
int previousScene;
+ int16 _nextSceneId;
uint16 actionNouns[3];
IntStorage _dataMap;
diff --git a/engines/m4/m4.h b/engines/m4/m4.h
index f5ddcc28be..3174c886d5 100644
--- a/engines/m4/m4.h
+++ b/engines/m4/m4.h
@@ -42,6 +42,7 @@
#include "m4/events.h"
#include "m4/font.h"
#include "m4/scene.h"
+#include "m4/mads_player.h"
#include "m4/mads_scene.h"
#include "m4/m4_scene.h"
#include "m4/actor.h"
@@ -213,6 +214,7 @@ private:
public:
MadsConversation _converse;
uint32 _currentTimer;
+ MadsPlayer _player;
public:
MadsEngine(OSystem *syst, const M4GameDescription *gameDesc);
virtual ~MadsEngine();
diff --git a/engines/m4/mads_logic.cpp b/engines/m4/mads_logic.cpp
index 72c5fde40b..2e3198029b 100644
--- a/engines/m4/mads_logic.cpp
+++ b/engines/m4/mads_logic.cpp
@@ -54,7 +54,7 @@ void MadsSceneLogic::getSceneSpriteSet() {
strcpy(prefix, "");
_madsVm->globals()->playerSpriteChanged = true;
- _madsVm->scene()->loadPlayerSprites(prefix);
+ _madsVm->_player.loadSprites(prefix);
// if ((_sceneNumber == 105) ((_sceneNumber == 109) && (word_84800 != 0)))
// _madsVm->globals()->playerSpriteChanged = true;
@@ -150,6 +150,59 @@ void MadsSceneLogic::lowRoomsEntrySound() {
}
}
+void MadsSceneLogic::getPlayerSpritesPrefix() {
+ _madsVm->_sound->playSound(5);
+
+ char oldName[80];
+ strcpy(oldName, _madsVm->_player._spritesPrefix);
+
+ if ((_madsVm->globals()->_nextSceneId <= 103) || (_madsVm->globals()->_nextSceneId == 111))
+ strcpy(_madsVm->_player._spritesPrefix, (_madsVm->globals()->_globals[0] == SEX_FEMALE) ? "ROX" : "RXM");
+ else if (_madsVm->globals()->_nextSceneId <= 110)
+ strcpy(_madsVm->_player._spritesPrefix, "RXSM");
+ else if (_madsVm->globals()->_nextSceneId == 112)
+ strcpy(_madsVm->_player._spritesPrefix, "");
+
+ if (strcmp(oldName, _madsVm->_player._spritesPrefix) != 0)
+ _madsVm->_player._spritesChanged = true;
+
+ if ((_madsVm->globals()->_nextSceneId == 105) ||
+ ((_madsVm->globals()->_nextSceneId == 109) && (_madsVm->globals()->_globals[15] != 0))) {
+ // TODO: unknown flag setting
+ _madsVm->_player._spritesChanged = true;
+ }
+
+ _madsVm->_palette->setEntry(16, 40, 255, 255);
+ _madsVm->_palette->setEntry(17, 40, 180, 180);
+
+}
+
+void MadsSceneLogic::getPlayerSpritesPrefix2() {
+ _madsVm->_sound->playSound(5);
+
+ char oldName[80];
+ strcpy(oldName, _madsVm->_player._spritesPrefix);
+
+ if ((_madsVm->globals()->_nextSceneId == 213) || (_madsVm->globals()->_nextSceneId == 216))
+ strcpy(_madsVm->_player._spritesPrefix, "");
+ else if (_madsVm->globals()->_globals[0] == SEX_MALE)
+ strcpy(_madsVm->_player._spritesPrefix, "RXM");
+ else
+ strcpy(_madsVm->_player._spritesPrefix, "ROX");
+
+ // TODO: unknown flag setting for next scene Id > 212
+
+ if (strcmp(oldName, _madsVm->_player._spritesPrefix) != 0)
+ _madsVm->_player._spritesChanged = true;
+
+/* if ((_madsVm->globals()->_nextSceneId == 203) && (_madsVm->globals()->_nextSceneId == 204) &&
+ (_madsVm->globals()->_globals[0x22] == 0))
+ // TODO: unknown flag set
+*/
+ _madsVm->_palette->setEntry(16, 40, 255, 255);
+ _madsVm->_palette->setEntry(17, 40, 180, 180);
+}
+
/*--------------------------------------------------------------------------*/
@@ -175,7 +228,9 @@ void MadsSceneLogic::setupScene() {
// sub_1e754(animName, 3);
if ((_sceneNumber >= 101) && (_sceneNumber <= 112))
- getSceneSpriteSet();
+ getPlayerSpritesPrefix();
+ else
+ getPlayerSpritesPrefix2();
getAnimName();
}
@@ -212,15 +267,15 @@ void MadsSceneLogic::enterScene() {
if (_madsVm->globals()->previousScene != -1)
_madsVm->globals()->_globals[10] = 0;
if (_madsVm->globals()->previousScene != -2) {
- _madsVm->scene()->getSceneResources().playerPos = Common::Point(100, 152);
+ _madsVm->_player._playerPos = Common::Point(100, 152);
}
if ((_madsVm->globals()->previousScene == 112) ||
((_madsVm->globals()->previousScene != -2) && (_spriteIndexes[29] != 0))) {
// Returning from probe cutscene?
_spriteIndexes[29] = -1;
- _madsVm->scene()->getSceneResources().playerPos = Common::Point(161, 123);
- _madsVm->scene()->getSceneResources().playerDir = 9;
+ _madsVm->_player._playerPos = Common::Point(161, 123);
+ _madsVm->_player._direction = 9;
// TODO: Extra flags setting
_spriteIndexes[25] = startCycledSpriteSequence(_spriteIndexes[10], 0, 3, 0, 0, 0);
@@ -241,8 +296,9 @@ void MadsSceneLogic::enterScene() {
const char *animName = MADSResourceManager::getResourceName('S', 'e', EXTTYPE_AA, NULL, -1);
_madsVm->scene()->loadAnimation(animName, 0x47);
- _madsVm->scene()->getSceneResources().playerPos = Common::Point(68, 140);
- _madsVm->scene()->getSceneResources().playerDir = 4;
+ _madsVm->_player._playerPos = Common::Point(68, 140);
+ _madsVm->_player._direction = 4;
+ _madsVm->_player._visible = false;
dataMap()[0x56FC] = 0;
dataMap()[0x5482] = 0;
@@ -258,6 +314,9 @@ void MadsSceneLogic::doAction() {
}
void MadsSceneLogic::sceneStep() {
+ // TODO: Sound handling
+
+
// Wake up message sequence
Animation *anim = _madsVm->scene()->activeAnimation();
if (anim) {
diff --git a/engines/m4/mads_logic.h b/engines/m4/mads_logic.h
index 299464f62b..3c6cb8edf1 100644
--- a/engines/m4/mads_logic.h
+++ b/engines/m4/mads_logic.h
@@ -42,6 +42,8 @@ private:
uint16 startSpriteSequence3(uint16 srcSpriteIdx, int v0, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks);
void activateHotspot(int idx, bool active);
void lowRoomsEntrySound();
+ void getPlayerSpritesPrefix();
+ void getPlayerSpritesPrefix2();
private:
int _sceneNumber;
int16 _spriteIndexes[50];
diff --git a/engines/m4/mads_player.cpp b/engines/m4/mads_player.cpp
new file mode 100644
index 0000000000..53ee857093
--- /dev/null
+++ b/engines/m4/mads_player.cpp
@@ -0,0 +1,193 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "m4/m4.h"
+#include "m4/mads_player.h"
+#include "m4/mads_scene.h"
+
+namespace M4 {
+
+MadsPlayer::MadsPlayer() {
+ _playerPos = Common::Point(160, 78);
+ _direction = 0;
+ _direction2 = 0;
+ _forceRefresh = true;
+ _visible = true;
+ _priorVisible = false;
+ _visible3 = false;
+ _yScale = 0;
+ _moving = false;
+ _spriteListIdx = 0;
+ _spriteListIdx2 = 0;
+ _spritesChanged = true;
+ _currentScale = 0;
+ strcpy(_spritesPrefix, "");
+ for (int idx = 0; idx < 8; ++idx)
+ _spriteSetIndexes[idx] = 0;
+ _frameNum = 0;
+ _frameOffset = 0;
+}
+
+/**
+ * Loads the sprite set for the player
+ */
+bool MadsPlayer::loadSprites(const char *prefix) {
+ const char suffixList[8] = { '8', '9', '6', '3', '2', '7', '4', '1' };
+ char setName[80];
+ bool result = true;
+
+ if (prefix)
+ strcpy(_spritesPrefix, prefix);
+
+ _spriteSetCount = 0;
+ int prefixLen = strlen(_spritesPrefix);
+
+ if (prefixLen == 0) {
+ // No player sprites at at all
+ for (int idx = 0; idx < 8; ++idx)
+ _spriteSetIndexes[idx] = 0;
+ } else {
+ strcpy(setName, "*");
+ strcat(setName, _spritesPrefix);
+ strcat(setName, "_0.SS");
+
+ char *digitP = strchr(setName, '_') + 1;
+
+ for (int idx = 0; idx < 8; ++idx) {
+ *digitP = suffixList[idx];
+ _spriteSetIndexes[idx] = -1;
+
+ int setIndex = _madsVm->scene()->_spriteSlots.addSprites(setName, true);
+ if (setIndex < 0) {
+ if (idx < 7)
+ break;
+ _spriteSetIndexes[idx] = 0;
+ } else {
+ ++_spriteSetCount;
+ }
+
+ if (idx == 0)
+ _spriteListIdx = setIndex;
+ }
+
+ result = 0;
+ // TODO: Unknown flag
+ _spritesChanged = false;
+ }
+
+ return result;
+}
+
+/**
+ * Called each frame to update the display of the player
+ */
+void MadsPlayer::update() {
+ if (_forceRefresh || (_visible != _priorVisible)) {
+ // If there's an existing player sprite visible, flag it for expiry
+ int slotIndex = getSpriteSlot();
+ if (slotIndex >= 0)
+ _madsVm->scene()->_spriteSlots[slotIndex].spriteType = EXPIRED_SPRITE;
+
+ // Figure out the depth for the sprite
+ int newDepth = 1;
+ int yp = MIN(_playerPos.y, (int16)155);
+
+ for (int idx = 1; idx < 15; ++idx) {
+ if (_madsVm->scene()->getSceneResources().depthTable[newDepth] >= yp)
+ newDepth = idx + 1;
+ }
+ _currentDepth = newDepth;
+
+ // Get the scale
+ int newScale = getScale(_playerPos.y);
+ _currentScale = MIN(newScale, 100);
+
+ if (_visible) {
+ // Player sprite needs to be rendered
+ MadsSpriteSlot slot;
+ slot.spriteType = FOREGROUND_SPRITE;
+ slot.seqIndex = PLAYER_SEQ_INDEX;
+ slot.spriteListIndex = _spriteListIdx + _spriteListIdx2;
+ slot.frameNumber = _frameOffset + _frameNum;
+ slot.xp = _playerPos.x;
+ slot.yp = _playerPos.y + (_yScale * newScale) / 100;
+ slot.depth = newDepth;
+ slot.scale = newScale;
+
+ if (slotIndex >= 0) {
+ // Check if the existing player slot has the same details, and can be re-used
+ MadsSpriteSlot &s2 = _madsVm->scene()->_spriteSlots[slotIndex];
+ bool equal = (s2.seqIndex == slot.seqIndex) && (s2.spriteListIndex == slot.spriteListIndex)
+ && (s2.frameNumber == slot.frameNumber) && (s2.xp == slot.xp) && (s2.yp == slot.yp)
+ && (s2.depth == slot.depth) && (s2.scale == slot.scale);
+
+ if (equal)
+ // Undo the prior expiry of the player sprite
+ slot.spriteType = SPRITE_ZERO;
+ else
+ slotIndex = -1;
+ }
+
+ if (slotIndex < 0) {
+ // New slot needed, so allocate one and copy the slot data
+ slotIndex = _madsVm->scene()->_spriteSlots.getIndex();
+ _madsVm->scene()->_spriteSlots[slotIndex] = slot;
+ }
+
+ // TODO: Meaning of word_844c0 block
+
+ }
+ }
+
+ _visible3 = _priorVisible = _visible;
+ _forceRefresh = false;
+}
+
+void MadsPlayer::idle() {
+
+}
+
+int MadsPlayer::getScale(int yp) {
+ MadsSceneResources &r = _madsVm->scene()->getSceneResources();
+
+ int scale = (r.bandsRange() == 0) ? r._maxScale : (yp - r._yBandsStart) * r.scaleRange() / r.bandsRange()
+ + r._minScale;
+
+ return MIN(scale, 100);
+}
+
+/**
+ * Scans through the scene's sprite slot list to find any sprite displaying the player
+ */
+int MadsPlayer::getSpriteSlot() {
+ MadsSpriteSlots &slots = _madsVm->scene()->_spriteSlots;
+ for (int i = 0; i < slots.startIndex; ++i) {
+ if ((slots[i].seqIndex == PLAYER_SEQ_INDEX) && (slots[i].spriteType >= SPRITE_ZERO))
+ return i;
+ }
+ return -1;
+}
+
+} // End of namespace M4
diff --git a/engines/m4/mads_player.h b/engines/m4/mads_player.h
new file mode 100644
index 0000000000..c84c1d0c60
--- /dev/null
+++ b/engines/m4/mads_player.h
@@ -0,0 +1,66 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef M4_MADS_PLAYER_H
+#define M4_MADS_PLAYER_H
+
+#include "common/scummsys.h"
+
+namespace M4 {
+
+#define PLAYER_SEQ_INDEX -2
+
+class MadsPlayer {
+private:
+ int getScale(int yp);
+ int getSpriteSlot();
+public:
+ char _spritesPrefix[16];
+ int _spriteSetCount;
+ int _spriteSetIndexes[8];
+ Common::Point _playerPos;
+ Common::Point _destPos;
+ int16 _direction, _direction2;
+ bool _visible, _priorVisible;
+ bool _visible3;
+ bool _forceRefresh;
+ int16 _currentScale;
+ int16 _yScale;
+ int16 _currentDepth;
+ int16 _spriteListIdx, _spriteListIdx2;
+ bool _spritesChanged;
+ int16 _frameOffset, _frameNum;
+ bool _moving;
+public:
+ MadsPlayer();
+
+ bool loadSprites(const char *prefix);
+ void update();
+ void idle();
+};
+
+} // End of namespace M4
+
+#endif
diff --git a/engines/m4/mads_scene.cpp b/engines/m4/mads_scene.cpp
index f4581ed629..c34216aa34 100644
--- a/engines/m4/mads_scene.cpp
+++ b/engines/m4/mads_scene.cpp
@@ -67,8 +67,10 @@ MadsScene::~MadsScene() {
/**
* Secondary scene loading code
*/
-void MadsScene::loadScene2(const char *aaName) {
+void MadsScene::loadScene2(const char *aaName, int sceneNumber) {
// TODO: Completely finish
+ _madsVm->globals()->previousScene = _madsVm->globals()->sceneNumber;
+ _madsVm->globals()->sceneNumber = sceneNumber;
_spriteSlots.clear();
_sequenceList.clear();
@@ -115,27 +117,41 @@ void MadsScene::loadScene(int sceneNumber) {
// Handle common scene setting
Scene::loadScene(sceneNumber);
-
- _madsVm->globals()->previousScene = _madsVm->globals()->sceneNumber;
- _madsVm->globals()->sceneNumber = sceneNumber;
+ _madsVm->globals()->_nextSceneId = sceneNumber;
// Existing ScummVM code that needs to be eventually replaced with MADS code
loadSceneTemporary();
+ _madsVm->_player._spritesChanged = true;
+ _madsVm->globals()->clearQuotes();
+ _dynamicHotspots.reset();
+
// Signal the script engine what scene is to be active
_sceneLogic.selectScene(sceneNumber);
- _sceneLogic.setupScene();
// Add the scene if necessary to the list of scenes that have been visited
_vm->globals()->addVisitedScene(sceneNumber);
- if (_vm->getGameType() == GType_RexNebular) {
+ if (_vm->getGameType() == GType_RexNebular)
+ _sceneLogic.setupScene();
+
+ // TODO: Unknown code
+
+ // Secondary scene load routine
+ if (_vm->getGameType() == GType_RexNebular)
// Secondary scene load routine
- loadScene2("*I0.AA");
+ loadScene2("*I0.AA", sceneNumber);
- // Do any scene specific setup
+ _madsVm->_player.loadSprites(NULL);
+
+ // Do any scene specific setup
+ if (_vm->getGameType() == GType_RexNebular)
_sceneLogic.enterScene();
- }
+
+ // Miscellaneous player setup
+ _madsVm->_player._destPos = _madsVm->_player._destPos;
+ _madsVm->_player._direction2 = _madsVm->_player._direction;
+ _madsVm->_player.idle();
// Purge resources
_vm->res()->purge();
@@ -300,6 +316,8 @@ void MadsScene::update() {
}
void MadsScene::updateState() {
+ _madsVm->_player.update();
+
_sceneLogic.sceneStep();
if ((_activeAnimation) && !_abortTimers) {
@@ -311,8 +329,36 @@ void MadsScene::updateState() {
}
MadsView::update();
+
+ // Remove the animation if it's been completed
+ if ((_activeAnimation) && ((MadsAnimation *)_activeAnimation)->freeFlag())
+ freeAnimation();
+}
+
+/**
+ * Does extra work at cleaning up the animation, and then deletes it
+ */
+void MadsScene::freeAnimation() {
+ if (!_activeAnimation)
+ return;
+
+ MadsAnimation *anim = (MadsAnimation *)_activeAnimation;
+ if (anim->freeFlag()) {
+ _madsVm->scene()->_spriteSlots.clear();
+ _madsVm->scene()->_spriteSlots.fullRefresh();
+ _madsVm->scene()->_sequenceList.scan();
+ }
+
+ if (_madsVm->_player._visible) {
+ _madsVm->_player._forceRefresh = true;
+ _madsVm->_player.update();
+ }
+
+ delete _activeAnimation;
+ _activeAnimation = NULL;
}
+
int MadsScene::loadSceneSpriteSet(const char *setName) {
char resName[100];
strcpy(resName, setName);
@@ -324,28 +370,6 @@ int MadsScene::loadSceneSpriteSet(const char *setName) {
return _spriteSlots.addSprites(resName);
}
-void MadsScene::loadPlayerSprites(const char *prefix) {
- const char suffixList[8] = { '8', '9', '6', '3', '2', '7', '4', '1' };
- char setName[80];
-
- strcpy(setName, "*");
- strcat(setName, prefix);
- strcat(setName, "_0.SS");
- char *digitP = strchr(setName, '_') + 1;
-
- for (int idx = 0; idx < 8; ++idx) {
- *digitP = suffixList[idx];
-
- if (_vm->res()->resourceExists(setName)) {
- loadSceneSpriteSet(setName);
- return;
- }
- }
-
- // Phantom/Dragon
- warning("Couldn't find player sprites");
-}
-
enum boxSprites {
topLeft = 0,
topRight = 1,
@@ -665,22 +689,27 @@ void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Su
}
// TODO: The following is wrong for Phantom/Dragon
- artFileNum = stream->readUint16LE();
- depthStyle = stream->readUint16LE();
- width = stream->readUint16LE();
- height = stream->readUint16LE();
+ _artFileNum = stream->readUint16LE();
+ _depthStyle = stream->readUint16LE();
+ _width = stream->readUint16LE();
+ _height = stream->readUint16LE();
stream->skip(24);
int objectCount = stream->readUint16LE();
-
- stream->skip(40);
+ _yBandsEnd = stream->readUint16LE();
+ _yBandsStart = stream->readUint16LE();
+ _maxScale = stream->readSint16LE();
+ _minScale = stream->readSint16LE();
+ for (int i = 0; i < DEPTH_BANDS_SIZE; ++i)
+ _depthBands[i] = stream->readUint16LE();
+ stream->skip(2);
// Load in any scene objects
for (int i = 0; i < objectCount; ++i) {
MadsObject rec;
rec.load(stream);
- objects.push_back(rec);
+ _objects.push_back(rec);
}
for (int i = 0; i < 20 - objectCount; ++i)
stream->skip(48);
@@ -690,7 +719,7 @@ void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Su
for (int i = 0; i < setCount; ++i) {
char buffer2[64];
Common::String s(buffer2, 64);
- setNames.push_back(s);
+ _setNames.push_back(s);
}
delete stream;
@@ -698,16 +727,16 @@ void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Su
// Initialise a copy of the surfaces if they weren't provided
bool dsFlag = false, ssFlag = false;
if (!surface) {
- surface = new M4Surface(width, height);
+ surface = new M4Surface(_width, _height);
ssFlag = true;
- } else if ((width != surface->width()) || (height != surface->height()))
- surface->setSize(width, height);
+ } else if ((_width != surface->width()) || (_height != surface->height()))
+ surface->setSize(_width, _height);
if (!depthSurface) {
- depthSurface = new M4Surface(width, height);
+ depthSurface = new M4Surface(_width, _height);
dsFlag = true;
- } else if ((width != depthSurface->width()) || (height != depthSurface->height()))
- depthSurface->setSize(width, height);
+ } else if ((_width != depthSurface->width()) || (_height != depthSurface->height()))
+ depthSurface->setSize(_width, _height);
// For Rex Nebular, read in the scene's compressed walk surface information
@@ -724,7 +753,7 @@ void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Su
// Run length encoded depth data
while ((runLength = *srcP++) != 0) {
- if (depthStyle == 2) {
+ if (_depthStyle == 2) {
// 2-bit depth pixels
byte byteVal = *srcP++;
for (int byteCtr = 0; byteCtr < runLength; ++byteCtr) {
@@ -746,7 +775,7 @@ void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Su
_vm->_resourceManager->toss(sceneName);
// Load the surface artwork
- surface->loadBackground(artFileNum);
+ surface->loadBackground(_artFileNum);
// Final cleanup
if (ssFlag)
diff --git a/engines/m4/mads_scene.h b/engines/m4/mads_scene.h
index c5fe6f01cd..66b50d809f 100644
--- a/engines/m4/mads_scene.h
+++ b/engines/m4/mads_scene.h
@@ -35,22 +35,26 @@ namespace M4 {
#define INTERFACE_HEIGHT 106
class MadsInterfaceView;
+#define DEPTH_BANDS_SIZE 15
+
class MadsSceneResources: public SceneResources {
public:
- int sceneId;
- int artFileNum;
- int depthStyle;
- int width;
- int height;
- Common::Array<MadsObject> objects;
- Common::Array<Common::String> setNames;
-
- Common::Point playerPos;
- int playerDir;
-
- MadsSceneResources() { playerDir = 0; }
+ int _sceneId;
+ int _artFileNum;
+ int _depthStyle;
+ int _width;
+ int _height;
+ Common::Array<MadsObject> _objects;
+ Common::Array<Common::String> _setNames;
+ int _yBandsStart, _yBandsEnd;
+ int _maxScale, _minScale;
+ int _depthBands[DEPTH_BANDS_SIZE];
+
+ MadsSceneResources() {}
~MadsSceneResources() {}
void load(int sceneId, const char *resName, int v0, M4Surface *depthSurface, M4Surface *surface);
+ int bandsRange() const { return _yBandsEnd - _yBandsStart; }
+ int scaleRange() const { return _maxScale - _minScale; }
};
enum MadsActionMode {ACTMODE_NONE = 0, ACTMODE_VERB = 1, ACTMODE_OBJECT = 3, ACTMODE_TALK = 6};
@@ -99,7 +103,7 @@ private:
SpriteAsset *_playerSprites;
void drawElements();
- void loadScene2(const char *aaName);
+ void loadScene2(const char *aaName, int sceneNumber);
void loadSceneTemporary();
void loadSceneHotspots(int sceneNumber);
void clearAction();
@@ -125,10 +129,10 @@ public:
virtual void updateState();
int loadSceneSpriteSet(const char *setName);
- void loadPlayerSprites(const char *prefix);
void showMADSV2TextBox(char *text, int x, int y, char *faceName);
void loadAnimation(const Common::String &animName, int v0);
Animation *activeAnimation() const { return _activeAnimation; }
+ void freeAnimation();
MadsInterfaceView *getInterface() { return (MadsInterfaceView *)_interfaceSurface; }
MadsSceneResources &getSceneResources() { return _sceneResources; }
diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp
index 21ea3a75cb..9241774d16 100644
--- a/engines/m4/mads_views.cpp
+++ b/engines/m4/mads_views.cpp
@@ -86,7 +86,13 @@ int MadsSpriteSlots::getIndex() {
return startIndex++;
}
-int MadsSpriteSlots::addSprites(const char *resName) {
+int MadsSpriteSlots::addSprites(const char *resName, bool suppressErrors) {
+ // If errors are suppressed, first check if the resource exists
+ if (suppressErrors) {
+ if (!_vm->res()->resourceExists(resName))
+ return -1;
+ }
+
// Get the sprite set
Common::SeekableReadStream *data = _vm->res()->get(resName);
SpriteAsset *spriteSet = new SpriteAsset(_vm, data, data->size(), resName);
diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h
index e3344bc8a4..38c7ed0712 100644
--- a/engines/m4/mads_views.h
+++ b/engines/m4/mads_views.h
@@ -92,7 +92,7 @@ public:
}
int getIndex();
- int addSprites(const char *resName);
+ int addSprites(const char *resName, bool suppressErrors = false);
void deleteSprites(int listIndex);
void clear();
void deleteTimer(int seqIndex);
diff --git a/engines/m4/module.mk b/engines/m4/module.mk
index 1b08ea2188..f60757ba3b 100644
--- a/engines/m4/module.mk
+++ b/engines/m4/module.mk
@@ -22,6 +22,7 @@ MODULE_OBJS = \
mads_anim.o \
mads_logic.o \
mads_menus.o \
+ mads_player.o \
mads_scene.o \
mads_views.o \
midi.o \