aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2015-06-13 21:07:50 -0400
committerPaul Gilbert2015-06-13 21:07:50 -0400
commit5531cf9fd503c3e74b8a32f6b12f2243bac68c06 (patch)
tree2ccdd038e0c7a3376cfcfb7bd11dfe1f8cedac8d
parent8d07a00f39fc80845911211d488eabf899c94f1a (diff)
downloadscummvm-rg350-5531cf9fd503c3e74b8a32f6b12f2243bac68c06.tar.gz
scummvm-rg350-5531cf9fd503c3e74b8a32f6b12f2243bac68c06.tar.bz2
scummvm-rg350-5531cf9fd503c3e74b8a32f6b12f2243bac68c06.zip
SHERLOCK: Refactored walk data block to e a proper structure
-rw-r--r--engines/sherlock/people.cpp16
-rw-r--r--engines/sherlock/scene.cpp66
-rw-r--r--engines/sherlock/scene.h15
3 files changed, 80 insertions, 17 deletions
diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp
index c108d333b9..349be671a4 100644
--- a/engines/sherlock/people.cpp
+++ b/engines/sherlock/people.cpp
@@ -124,11 +124,10 @@ void Person::goAllTheWay() {
if (i == -1)
i = scene._walkDirectory[_destZone][_srcZone];
- int count = scene._walkData[i];
- ++i;
+ const WalkArray &points = scene._walkPoints[i];
// See how many points there are between the src and dest zones
- if (!count || count == -1) {
+ if (!points._pointsCount || points._pointsCount == -1) {
// There are none, so just walk to the new zone
setWalking();
} else {
@@ -137,14 +136,11 @@ void Person::goAllTheWay() {
_walkTo.clear();
if (scene._walkDirectory[_srcZone][_destZone] != -1) {
- i += 3 * (count - 1);
- for (int idx = 0; idx < count; ++idx, i -= 3) {
- _walkTo.push(Common::Point(READ_LE_UINT16(&scene._walkData[i]),
- scene._walkData[i + 2]));
- }
+ for (int idx = (int)points.size() - 1; idx >= 0; --idx)
+ _walkTo.push(points[idx]);
} else {
- for (int idx = 0; idx < count; ++idx, i += 3) {
- _walkTo.push(Common::Point(READ_LE_UINT16(&scene._walkData[i]), scene._walkData[i + 2]));
+ for (int idx = 0; idx < (int)points.size(); ++idx) {
+ _walkTo.push(points[idx]);
}
}
diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp
index c4b87cf444..47e5c89bdb 100644
--- a/engines/sherlock/scene.cpp
+++ b/engines/sherlock/scene.cpp
@@ -193,6 +193,18 @@ void ScaleZone::load(Common::SeekableReadStream &s) {
/*----------------------------------------------------------------*/
+void WalkArray::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
+ _pointsCount = (int8)s.readByte();
+
+ for (int idx = 0; idx < _pointsCount; ++idx) {
+ int x = s.readSint16LE();
+ int y = isRoseTattoo ? s.readSint16LE() : s.readByte();
+ push_back(Common::Point(x, y));
+ }
+}
+
+/*----------------------------------------------------------------*/
+
Scene *Scene::init(SherlockEngine *vm) {
if (vm->getGameID() == GType_SerratedScalpel)
return new Scalpel::ScalpelScene(vm);
@@ -285,7 +297,7 @@ void Scene::freeScene() {
_sequenceBuffer.clear();
_descText.clear();
- _walkData.clear();
+ _walkPoints.clear();
_cAnim.clear();
_bgShapes.clear();
_zones.clear();
@@ -538,9 +550,12 @@ bool Scene::loadScene(const Common::String &filename) {
if (rrmStream->readByte() != (IS_SERRATED_SCALPEL ? 254 : 251))
error("Invalid scene path data");
- // Load the walk directory
+ // Load the walk directory and walk data
assert(_zones.size() < MAX_ZONES);
+
+
for (uint idx1 = 0; idx1 < _zones.size(); ++idx1) {
+ Common::fill(&_walkDirectory[idx1][0], &_walkDirectory[idx1][MAX_ZONES], 0);
for (uint idx2 = 0; idx2 < _zones.size(); ++idx2)
_walkDirectory[idx1][idx2] = rrmStream->readSint16LE();
}
@@ -550,12 +565,31 @@ bool Scene::loadScene(const Common::String &filename) {
Common::SeekableReadStream *walkStream = !_lzwMode ? rrmStream :
res.decompress(*rrmStream, size);
- _walkData.resize(size);
- walkStream->read(&_walkData[0], size);
+ int startPos = walkStream->pos();
+ while ((walkStream->pos() - startPos) < size) {
+ _walkPoints.push_back(WalkArray());
+ _walkPoints[_walkPoints.size() - 1]._fileOffset = walkStream->pos() - startPos;
+ _walkPoints[_walkPoints.size() - 1].load(*walkStream, IS_ROSE_TATTOO);
+ }
if (_lzwMode)
delete walkStream;
+ // Translate the file offsets of the walk directory to indexes in the loaded walk data
+ for (uint idx1 = 0; idx1 < _zones.size(); ++idx1) {
+ for (uint idx2 = 0; idx2 < _zones.size(); ++idx2) {
+ int fileOffset = _walkDirectory[idx1][idx2];
+ if (fileOffset == -1)
+ continue;
+
+ uint dataIndex = 0;
+ while (dataIndex < _walkPoints.size() && _walkPoints[dataIndex]._fileOffset != fileOffset)
+ ++dataIndex;
+ assert(dataIndex < _walkPoints.size());
+ _walkDirectory[idx1][idx2] = dataIndex;
+ }
+ }
+
if (IS_ROSE_TATTOO) {
// Read in the entrance
_entrance.load(*rrmStream);
@@ -781,8 +815,28 @@ bool Scene::loadScene(const Common::String &filename) {
// === WALK DATA === Read in the walk data
roomStream->seek(header3DO_walkData_offset);
- _walkData.resize(header3DO_walkData_size);
- roomStream->read(&_walkData[0], header3DO_walkData_size);
+
+ int startPos = roomStream->pos();
+ while ((roomStream->pos() - startPos) < header3DO_walkData_size) {
+ _walkPoints.push_back(WalkArray());
+ _walkPoints[_walkPoints.size() - 1]._fileOffset = roomStream->pos() - startPos;
+ _walkPoints[_walkPoints.size() - 1].load(*roomStream, false);
+ }
+
+ // Translate the file offsets of the walk directory to indexes in the loaded walk data
+ for (uint idx1 = 0; idx1 < _zones.size(); ++idx1) {
+ for (uint idx2 = 0; idx2 < _zones.size(); ++idx2) {
+ int fileOffset = _walkDirectory[idx1][idx2];
+ if (fileOffset == -1)
+ continue;
+
+ uint dataIndex = 0;
+ while (dataIndex < _walkPoints.size() && _walkPoints[dataIndex]._fileOffset != fileOffset)
+ ++dataIndex;
+ assert(dataIndex < _walkPoints.size());
+ _walkDirectory[idx1][idx2] = dataIndex;
+ }
+ }
// === EXITS === Read in the exits
roomStream->seek(header3DO_exits_offset);
diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h
index 2cf8b803b4..799433fd53 100644
--- a/engines/sherlock/scene.h
+++ b/engines/sherlock/scene.h
@@ -131,6 +131,19 @@ public:
void load(Common::SeekableReadStream &s);
};
+class WalkArray : public Common::Array < Common::Point > {
+public:
+ int _pointsCount;
+ int _fileOffset;
+
+ WalkArray() : _pointsCount(0), _fileOffset(-1) {}
+
+ /**
+ * Load data for the walk array entry
+ */
+ void load(Common::SeekableReadStream &s, bool isRoseTattoo);
+};
+
class Scene {
private:
bool _loadingSavedGame;
@@ -213,7 +226,7 @@ public:
Common::Array<byte> _sequenceBuffer;
Common::Array<SceneImage> _images;
int _walkDirectory[MAX_ZONES][MAX_ZONES];
- Common::Array<byte> _walkData;
+ Common::Array<WalkArray> _walkPoints;
Common::Array<Exit> _exits;
int _exitZone;
SceneEntry _entrance;