Skip to content

Commit

Permalink
SHERLOCK: Refactored walk data block to e a proper structure
Browse files Browse the repository at this point in the history
  • Loading branch information
dreammaster committed Jun 14, 2015
1 parent 8d07a00 commit 5531cf9
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 17 deletions.
16 changes: 6 additions & 10 deletions engines/sherlock/people.cpp
Expand Up @@ -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 {
Expand All @@ -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]);
}
}

Expand Down
66 changes: 60 additions & 6 deletions engines/sherlock/scene.cpp
Expand Up @@ -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);
Expand Down Expand Up @@ -285,7 +297,7 @@ void Scene::freeScene() {

_sequenceBuffer.clear();
_descText.clear();
_walkData.clear();
_walkPoints.clear();
_cAnim.clear();
_bgShapes.clear();
_zones.clear();
Expand Down Expand Up @@ -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();
}
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
15 changes: 14 additions & 1 deletion engines/sherlock/scene.h
Expand Up @@ -131,6 +131,19 @@ class ScaleZone: public Common::Rect {
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;
Expand Down Expand Up @@ -213,7 +226,7 @@ class Scene {
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;
Expand Down

0 comments on commit 5531cf9

Please sign in to comment.