aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2015-03-20 19:44:32 -0400
committerPaul Gilbert2015-03-20 19:44:32 -0400
commitcf92e540db2d58f243abe595da40a7da4450911f (patch)
tree378de11bcde5fb1bbfc453c7f785b8bfa43e175a /engines
parent43381e98197f8adb5ee73f8dc05c81b972fedeae (diff)
downloadscummvm-rg350-cf92e540db2d58f243abe595da40a7da4450911f.tar.gz
scummvm-rg350-cf92e540db2d58f243abe595da40a7da4450911f.tar.bz2
scummvm-rg350-cf92e540db2d58f243abe595da40a7da4450911f.zip
SHERLOCK: More scene loading code and support methods
Diffstat (limited to 'engines')
-rw-r--r--engines/sherlock/objects.cpp37
-rw-r--r--engines/sherlock/objects.h26
-rw-r--r--engines/sherlock/scene.cpp196
-rw-r--r--engines/sherlock/scene.h48
-rw-r--r--engines/sherlock/screen.cpp2
-rw-r--r--engines/sherlock/screen.h3
-rw-r--r--engines/sherlock/sherlock.cpp1
-rw-r--r--engines/sherlock/sherlock.h2
-rw-r--r--engines/sherlock/sound.cpp4
-rw-r--r--engines/sherlock/sound.h1
10 files changed, 308 insertions, 12 deletions
diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
index 73e6397b50..aa9b391f96 100644
--- a/engines/sherlock/objects.cpp
+++ b/engines/sherlock/objects.cpp
@@ -134,7 +134,7 @@ void Object::synchronize(Common::SeekableReadStream &s) {
_maxFrames = s.readUint16LE();
_flags = s.readByte();
_aOpen.synchronize(s);
- _aType = s.readByte();
+ _aType = (AType)s.readByte();
_lookFrames = s.readByte();
_seqCounter = s.readByte();
_lookPosition.x = s.readUint16LE();
@@ -155,6 +155,41 @@ void Object::synchronize(Common::SeekableReadStream &s) {
_use[idx].synchronize(s);
}
+void Object::toggleHidden() {
+ if (_type != HIDDEN && _type != HIDE_SHAPE && _type != INVALID) {
+ if (_seqTo != 0)
+ _sequences[_frameNumber] = _seqTo + SEQ_TO_CODE + 128;
+ _seqTo = 0;
+
+ if (_images == nullptr || _images->size() == 0)
+ // No shape to erase, so flag as hidden
+ _type = HIDDEN;
+ else
+ // Otherwise, flag it to be hidden after it gets erased
+ _type = HIDE_SHAPE;
+ } else if (_type != INVALID) {
+ if (_seqTo != 0)
+ _sequences[_frameNumber] = _seqTo + SEQ_TO_CODE + 128;
+ _seqTo = 0;
+
+ _seqCounter = _seqcounter2 = 0;
+ _seqStack = 0;
+ _frameNumber = -1;
+
+ if (_images == nullptr || _images->size() == 0) {
+ _type = NO_SHAPE;
+ } else {
+ _type = ACTIVE_BG_SHAPE;
+ int idx = _sequences[0];
+ if (idx >= _maxFrames)
+ // Turn on: set up first frame
+ idx = 0;
+
+ _imageFrame = &(*_images)[idx];
+ }
+ }
+}
+
/*----------------------------------------------------------------*/
void CAnim::synchronize(Common::SeekableReadStream &s) {
diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h
index 31d9520932..f3879b1143 100644
--- a/engines/sherlock/objects.h
+++ b/engines/sherlock/objects.h
@@ -49,9 +49,31 @@ enum SpriteType {
HIDE_SHAPE = 8 // Object needs to be hidden
};
+enum AType {
+ OBJECT = 0,
+ PERSON = 1,
+ SOLID = 2,
+ TALK = 3, // Standard talk zone
+ FLAG_SET = 4,
+ DELTA = 5,
+ WALK_AROUND = 6,
+ TALK_EVERY = 7, // Talk zone that turns on every room visit
+ TALK_MOVE = 8, // Talk zone that only activates when Holmes moves
+ PAL_CHANGE = 9, // Changes the palette down so that it gets darker
+ PAL_CHANGE2 = 10, // Same as PAL_CHANGE, except that it goes up
+ SCRIPT_ZONE = 11, // If this is clicked in, it is activated
+ BLANK_ZONE = 12, // This masks out other objects when entered
+ NOWALK_ZONE = 13 // Player cannot walk here
+};
+
#define MAX_HOLMES_SEQUENCE 16
#define MAX_FRAME 30
+// code put into sequences to defines 1-10 type seqs
+#define SEQ_TO_CODE 67
+#define FLIP_CODE (64 + 128)
+#define SOUND_CODE (34 + 128)
+
struct Sprite {
Common::String _name; // Name
Common::String _description; // Description
@@ -131,7 +153,7 @@ struct Object {
int _maxFrames; // Number of frames
int _flags; // Tells if object can be walked behind
ActionType _aOpen; // Holds data for moving object
- int _aType; // Tells if this is an object, person, talk, etc.
+ AType _aType; // Tells if this is an object, person, talk, etc.
int _lookFrames; // How many frames to play of the look anim before pausing
int _seqCounter; // How many times this sequence has been executed
Common::Point _lookPosition; // Where to walk when examining object
@@ -147,6 +169,8 @@ struct Object {
UseType _use[4];
void synchronize(Common::SeekableReadStream &s);
+
+ void toggleHidden();
};
struct CAnim {
diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp
index ffae6f60c1..86e347d011 100644
--- a/engines/sherlock/scene.cpp
+++ b/engines/sherlock/scene.cpp
@@ -46,18 +46,47 @@ void BgfileheaderInfo::synchronize(Common::SeekableReadStream &s) {
_filename = Common::String(buffer);
}
-int _fSize; // How long images are
-int _maxFrames; // How many unique frames in object
-Common::String _filename; // Filename of object
+/*----------------------------------------------------------------*/
+
+void Exit::synchronize(Common::SeekableReadStream &s) {
+ _position.x = s.readSint16LE();
+ _position.y = s.readSint16LE();
+ _size.x = s.readSint16LE();
+ _size.y = s.readSint16LE();
+ _scene = s.readSint16LE();
+ _allow = s.readSint16LE();
+ _people.x = s.readSint16LE();
+ _people.y = s.readSint16LE();
+ _peopleDir = s.readUint16LE();
+}
+
+/*----------------------------------------------------------------*/
+
+void SceneEntry::synchronize(Common::SeekableReadStream &s) {
+ _startPosition.x = s.readSint16LE();
+ _startPosition.y = s.readSint16LE();
+ _startDir = s.readByte();
+ _allow = s.readByte();
+}
+
+void SceneSound::synchronize(Common::SeekableReadStream &s) {
+ char buffer[9];
+ s.read(buffer, 8);
+ buffer[8] = '\0';
+
+ _name = Common::String(buffer);
+ _priority = s.readByte();
+}
/*----------------------------------------------------------------*/
Scene::Scene(SherlockEngine *vm): _vm(vm) {
for (int idx = 0; idx < SCENES_COUNT; ++idx)
Common::fill(&_stats[idx][0], &_stats[idx][9], false);
+ _currentScene = -1;
_goToRoom = -1;
+ _changes = false;
_oldCharPoint = 0;
- _numExits = 0;
_windowOpen = _infoFlag = false;
_menuMode = _keyboardInput = 0;
_walkedInScene = false;
@@ -66,10 +95,12 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) {
_lzwMode = false;
_invGraphicItems = 0;
+ _controlPanel = new ImageFile("controls.vgs");
_controls = nullptr; // new ImageFile("menu.all");
}
Scene::~Scene() {
+ delete _controlPanel;
delete _controls;
clear();
}
@@ -78,13 +109,10 @@ Scene::~Scene() {
* Takes care of clearing any scene data
*/
void Scene::clear() {
- for (uint idx = 0; idx < _bgShapes.size(); ++idx)
- delete _bgShapes[idx]._images;
}
void Scene::selectScene() {
// Reset fields
- _numExits = 0;
_windowOpen = _infoFlag = false;
_menuMode = _keyboardInput = 0;
_oldKey = _help = _oldHelp = 0;
@@ -93,6 +121,7 @@ void Scene::selectScene() {
// Load the scene
Common::String sceneFile = Common::String::format("res%02d", _goToRoom);
Common::String roomName = Common::String::format("res%02d.rrm", _goToRoom);
+ _currentScene = _goToRoom;
_goToRoom = -1;
loadScene(sceneFile);
@@ -108,6 +137,8 @@ void Scene::selectScene() {
* that it should point to after loading; _misc is then set to 0.
*/
void Scene::loadScene(const Common::String &filename) {
+ Screen &screen = *_vm->_screen;
+ Sound &sound = *_vm->_sound;
bool flag;
_walkedInScene = false;
@@ -240,11 +271,160 @@ void Scene::loadScene(const Common::String &filename) {
// Back at version byte, so skip over it
rrmStream->skip(1);
- // TODO
+ // Load the walk directory
+ for (int idx1 = 0; idx1 < MAX_ZONES; ++idx1) {
+ for (int idx2 = 0; idx2 < MAX_ZONES; ++idx2)
+ _walkDirectory[idx1][idx2] = rrmStream->readSint16LE();
+ }
+
+ // Read in the walk data
+ size = rrmStream->readUint16LE();
+ Common::SeekableReadStream *walkStream = !_lzwMode ? rrmStream :
+ decompressLZ(*rrmStream, size);
+
+ _walkData.resize(size);
+ walkStream->read(&_walkData[0], size);
+
+ if (_lzwMode)
+ delete walkStream;
+
+ // Read in the exits
+ int numExits = rrmStream->readByte();
+ _exits.resize(numExits);
+
+ for (int idx = 0; idx < numExits; ++idx)
+ _exits[idx].synchronize(*rrmStream);
+
+ // Read in the entrance
+ _entrance.synchronize(*rrmStream);
+
+ // Initialize sound list
+ int numSounds = rrmStream->readByte();
+ _sounds.resize(numSounds);
+
+ for (int idx = 0; idx < numSounds; ++idx)
+ _sounds[idx].synchronize(*rrmStream);
+
+ // If sound is turned on, load the sounds into memory
+ if (sound._sfxEnabled) {
+ for (int idx = 0; idx < numSounds; ++idx) {
+ sound.loadSound(_sounds[idx]._name, _sounds[idx]._priority);
+ _sounds[idx]._name = "";
+ }
+ }
+
+ // Read in palette
+ rrmStream->read(screen._cMap, PALETTE_SIZE);
+ for (int idx = 0; idx < PALETTE_SIZE; ++idx)
+ screen._cMap[idx] = VGA_COLOR_TRANS(screen._cMap[idx]);
+
+ Common::copy(screen._cMap, screen._cMap + PALETTE_SIZE, screen._sMap);
+
+ // Read in the background
+ Common::SeekableReadStream *bgStream = !_lzwMode ? rrmStream :
+ decompressLZ(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
+
+ bgStream->read(screen._backBuffer.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
+
+ if (_lzwMode)
+ delete bgStream;
+
+ // Set the palette
+ screen._backBuffer2.blitFrom(screen._backBuffer);
+ screen.setPalette(screen._cMap);
delete rrmStream;
}
+ // Clear user interface area and draw controls
+ screen._backBuffer2.fillRect(0, INFO_LINE, SHERLOCK_SCREEN_WIDTH, INFO_LINE + 10, INFO_BLACK);
+ screen._backBuffer.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y));
+ screen._backBuffer2.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y));
+
+ _changes = false;
+ checkSceneStatus();
+
+ if (!_vm->_justLoaded) {
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ if (_bgShapes[idx]._type == HIDDEN && _bgShapes[idx]._aType == TALK_EVERY)
+ _bgShapes[idx].toggleHidden();
+ }
+
+ // Check for TURNON objects
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ if (_bgShapes[idx]._type == HIDDEN && (_bgShapes[idx]._flags & 0x20))
+ _bgShapes[idx].toggleHidden();
+ }
+
+ // Check for TURNOFF objects
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ if (_bgShapes[idx]._type != HIDDEN && (_bgShapes[idx]._flags & 0x40) &&
+ _bgShapes[idx]._type != INVALID)
+ _bgShapes[idx].toggleHidden();
+ }
+ }
+
+ checkSceneFlags(false);
+ checkInventory();
+
+ // TODO
+}
+
+/**
+ * Set objects to their current persistent state. This includes things such as
+ * opening or moving them
+ */
+void Scene::checkSceneStatus() {
+ if (_stats[_currentScene][8]) {
+ for (int idx = 0; idx < 8; ++idx) {
+ int val = _stats[_currentScene][idx];
+
+ for (int bit = 0; bit < 8; ++bit) {
+ uint objNumber = idx * 8 + bit;
+ if (objNumber < _bgShapes.size()) {
+ Object &obj = _bgShapes[objNumber];
+
+ if (val & 1) {
+ // No shape to erase, so flag as hidden
+ obj._type = HIDDEN;
+ } else if (obj._images == nullptr || obj._images->size() == 0) {
+ // No shape
+ obj._type = NO_SHAPE;
+ } else {
+ obj._type = ACTIVE_BG_SHAPE;
+ }
+ } else {
+ // Finished checks
+ return;
+ }
+
+ val >>= 1;
+ }
+ }
+ }
+}
+
+/**
+ * Check the scene's objects against the game flags. If false is passed,
+ * it means the scene has just been loaded. A value of true means that the scene
+ * is in use (ie. not just loaded)
+ */
+void Scene::checkSceneFlags(bool flag) {
+ int mode = mode ? HIDE_SHAPE : HIDDEN;
+
+ for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
+ Object &o = _bgShapes[idx];
+ // TODO: read_flags calls
+ }
+}
+
+/**
+ * Checks scene objects against the player's inventory items. If there are any
+ * matching names, it means the given item has already been picked up, and should
+ * be hidden in the scene.
+ */
+void Scene::checkInventory() {
+
}
} // End of namespace Sherlock
diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h
index 2280e169b7..ae4fcfdb45 100644
--- a/engines/sherlock/scene.h
+++ b/engines/sherlock/scene.h
@@ -32,6 +32,10 @@
namespace Sherlock {
#define SCENES_COUNT 63
+#define MAX_ZONES 40
+#define INFO_LINE 140
+#define CONTROLS_Y 138
+#define CONTROLS_Y1 151
class SherlockEngine;
@@ -54,6 +58,33 @@ struct BgfileheaderInfo {
void synchronize(Common::SeekableReadStream &s);
};
+struct Exit {
+ Common::Point _position;
+ Common::Point _size;
+
+ int _scene;
+ int _allow;
+ Common::Point _people;
+ int _peopleDir;
+
+ void synchronize(Common::SeekableReadStream &s);
+};
+
+struct SceneEntry {
+ Common::Point _startPosition;
+ int _startDir;
+ int _allow;
+
+ void synchronize(Common::SeekableReadStream &s);
+};
+
+struct SceneSound {
+ Common::String _name;
+ int _priority;
+
+ void synchronize(Common::SeekableReadStream &s);
+};
+
class Scene {
private:
SherlockEngine *_vm;
@@ -61,15 +92,23 @@ private:
void loadScene();
void loadScene(const Common::String &filename);
+
+ void checkSceneStatus();
+
+ void checkSceneFlags(bool mode);
+
+ void checkInventory();
public:
+ int _currentScene;
+ int _goToRoom;
+ bool _changes;
bool _stats[SCENES_COUNT][9];
bool _savedStats[SCENES_COUNT][9];
- int _goToRoom;
Common::Point _bigPos;
Common::Point _overPos;
int _oldCharPoint;
ImageFile *_controls;
- int _numExits;
+ ImageFile *_controlPanel;
bool _windowOpen, _infoFlag;
int _menuMode, _keyboardInput;
int _oldKey, _help, _oldHelp;
@@ -86,6 +125,11 @@ public:
Common::Array<CAnim> _cAnim;
Common::Array<byte> _sequenceBuffer;
Common::Array<InvGraphicType> _inv;
+ int _walkDirectory[MAX_ZONES][MAX_ZONES];
+ Common::Array<byte> _walkData;
+ Common::Array<Exit> _exits;
+ SceneEntry _entrance;
+ Common::Array<SceneSound> _sounds;
public:
Scene(SherlockEngine *vm);
~Scene();
diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp
index 0ec5df9c4c..b322b96d6b 100644
--- a/engines/sherlock/screen.cpp
+++ b/engines/sherlock/screen.cpp
@@ -32,6 +32,8 @@ Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCR
_backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT) {
_transitionSeed = 1;
_fadeStyle = false;
+ Common::fill(&_cMap[0], &_cMap[PALETTE_SIZE], 0);
+ Common::fill(&_sMap[0], &_sMap[PALETTE_SIZE], 0);
setFont(1);
}
diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h
index 05fd80a8b7..2c5e585475 100644
--- a/engines/sherlock/screen.h
+++ b/engines/sherlock/screen.h
@@ -34,6 +34,7 @@ namespace Sherlock {
#define PALETTE_SIZE 768
#define PALETTE_COUNT 256
#define VGA_COLOR_TRANS(x) ((x) * 255 / 63)
+#define INFO_BLACK 1
class SherlockEngine;
@@ -52,6 +53,8 @@ protected:
public:
Surface _backBuffer, _backBuffer2;
bool _fadeStyle;
+ byte _cMap[PALETTE_SIZE];
+ byte _sMap[PALETTE_SIZE];
public:
Screen(SherlockEngine *vm);
diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp
index a963d0bfe5..115d9f0130 100644
--- a/engines/sherlock/sherlock.cpp
+++ b/engines/sherlock/sherlock.cpp
@@ -43,6 +43,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam
_useEpilogue2 = false;
_hsavedPos = Common::Point(-1, -1);
_hsavedFs = -1;
+ _justLoaded = false;
}
SherlockEngine::~SherlockEngine() {
diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h
index 210e24c320..c31416f91e 100644
--- a/engines/sherlock/sherlock.h
+++ b/engines/sherlock/sherlock.h
@@ -59,6 +59,7 @@ enum {
#define SHERLOCK_SCREEN_WIDTH 320
#define SHERLOCK_SCREEN_HEIGHT 200
+#define SHERLOCK_SCENE_HEIGHT 138
struct SherlockGameDescription;
@@ -91,6 +92,7 @@ public:
bool _useEpilogue2;
Common::Point _hsavedPos;
int _hsavedFs;
+ bool _justLoaded;
public:
SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
virtual ~SherlockEngine();
diff --git a/engines/sherlock/sound.cpp b/engines/sherlock/sound.cpp
index efc1965637..61c740ea3f 100644
--- a/engines/sherlock/sound.cpp
+++ b/engines/sherlock/sound.cpp
@@ -32,6 +32,10 @@ Sound::Sound(SherlockEngine *vm): _vm(vm) {
_music = false;
}
+void Sound::loadSound(const Common::String &name, int priority) {
+ // TODO
+}
+
void Sound::playSound(const Common::String &name, WaitType waitType) {
// TODO
}
diff --git a/engines/sherlock/sound.h b/engines/sherlock/sound.h
index 442e908838..9d323833f1 100644
--- a/engines/sherlock/sound.h
+++ b/engines/sherlock/sound.h
@@ -46,6 +46,7 @@ public:
public:
Sound(SherlockEngine *vm);
+ void loadSound(const Common::String &name, int priority);
void playSound(const Common::String &name, WaitType waitType = WAIT_RETURN_IMMEDIATELY);
void cacheSound(const Common::String &name, int index);
void playCachedSound(int index);