Skip to content

Commit

Permalink
SHERLOCK: Implemented Tattoo loadWalk changes
Browse files Browse the repository at this point in the history
  • Loading branch information
dreammaster committed May 23, 2015
1 parent ad543a0 commit a66570f
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 46 deletions.
12 changes: 8 additions & 4 deletions engines/sherlock/map.cpp
Expand Up @@ -65,8 +65,12 @@ Map::Map(SherlockEngine *vm): _vm(vm), _topLine(g_system->getWidth(), 12) {
_oldCharPoint = 0;
_frameChangeFlag = false;

for (int idx = 0; idx < MAX_HOLMES_SEQUENCE; ++idx)
Common::fill(&_sequences[idx][0], &_sequences[idx][MAX_FRAME], 0);
// Initialise the initial walk sequence set
_walkSequences.resize(MAX_HOLMES_SEQUENCE);
for (int idx = 0; idx < MAX_HOLMES_SEQUENCE; ++idx) {
_walkSequences[idx]._sequences.resize(MAX_FRAME);
Common::fill(&_walkSequences[idx]._sequences[0], &_walkSequences[idx]._sequences[0] + MAX_FRAME, 0);
}

if (!_vm->isDemo())
loadData();
Expand All @@ -80,7 +84,7 @@ void Map::loadPoints(int count, const int *xList, const int *yList, const int *t

void Map::loadSequences(int count, const byte *seq) {
for (int idx = 0; idx < count; ++idx, seq += MAX_FRAME)
Common::copy(seq, seq + MAX_FRAME, &_sequences[idx][0]);
Common::copy(seq, seq + MAX_FRAME, &_walkSequences[idx]._sequences[0]);
}

void Map::loadData() {
Expand Down Expand Up @@ -289,7 +293,7 @@ void Map::setupSprites() {
p._type = CHARACTER;
p._position = Common::Point(12400, 5000);
p._sequenceNumber = 0;
p._sequences = &_sequences;
p._walkSequences = _walkSequences;
p._images = _shapes;
p._imageFrame = nullptr;
p._frameNumber = 0;
Expand Down
2 changes: 1 addition & 1 deletion engines/sherlock/map.h
Expand Up @@ -76,7 +76,7 @@ class Map {
ImageFile *_mapCursors;
ImageFile *_shapes;
ImageFile *_iconShapes;
byte _sequences[MAX_HOLMES_SEQUENCE][MAX_FRAME];
Common::Array<WalkSequence> _walkSequences;
Point32 _lDrawnPos;
int _point;
bool _placesShown;
Expand Down
19 changes: 14 additions & 5 deletions engines/sherlock/objects.cpp
Expand Up @@ -46,7 +46,7 @@ void Sprite::clear() {
_description = "";
_examine.clear();
_pickUp = "";
_sequences = nullptr;
_walkSequences.clear();
_images = nullptr;
_imageFrame = nullptr;
_walkCount = 0;
Expand All @@ -63,12 +63,21 @@ void Sprite::clear() {
_status = 0;
_misc = 0;
_numFrames = 0;
_altImages = nullptr;
_altSequences = false;
Common::fill(&_stopFrames[0], &_stopFrames[8], (ImageFrame *)nullptr);
}

void Sprite::setImageFrame() {
int imageNumber = (*_sequences)[_sequenceNumber][_frameNumber] +
(*_sequences)[_sequenceNumber][0] - 2;
_imageFrame = &(*_images)[imageNumber];
int frameNum = MAX(_frameNumber, 0);
int imageNumber = _walkSequences[_sequenceNumber][frameNum];

if (IS_SERRATED_SCALPEL)
imageNumber = imageNumber + +_walkSequences[_sequenceNumber][0] - 2;
else if (imageNumber > _numFrames)
imageNumber = 1;

_imageFrame = &(_altSequences ? *_altImages : *_images)[imageNumber];
}

void Sprite::adjustSprite() {
Expand Down Expand Up @@ -120,7 +129,7 @@ void Sprite::adjustSprite() {
if (!map._active || (map._frameChangeFlag = !map._frameChangeFlag))
++_frameNumber;

if ((*_sequences)[_sequenceNumber][_frameNumber] == 0) {
if (_walkSequences[_sequenceNumber][_frameNumber] == 0) {
switch (_sequenceNumber) {
case STOP_UP:
case STOP_DOWN:
Expand Down
28 changes: 25 additions & 3 deletions engines/sherlock/objects.h
Expand Up @@ -46,7 +46,10 @@ enum SpriteType {
REMOVE = 5, // Object should be removed next frame
NO_SHAPE = 6, // Background object with no shape
HIDDEN = 7, // Hidden backgruond object
HIDE_SHAPE = 8 // Object needs to be hidden
HIDE_SHAPE = 8, // Object needs to be hidden

// Rose Tattoo
HIDDEN_CHARACTER = 128
};

enum AType {
Expand Down Expand Up @@ -98,16 +101,31 @@ class Point32 {
void operator-=(const Point32 &delta) { x -= delta.x; y -= delta.y; }
};


struct WalkSequence {
Common::String _vgsName;
bool _horizFlip;
Common::Array<byte> _sequences;

WalkSequence() : _vgsName(nullptr), _horizFlip(false) {}
const byte &operator[](int idx) { return _sequences[idx]; }

/**
* Load data for the sequence from a stream
*/
void load(Common::SeekableReadStream &s);
};

class Sprite {
private:
static SherlockEngine *_vm;
public:
Common::String _name;
Common::String _description;
Common::StringArray _examine; // Examine in-depth description
Common::String _examine; // Examine in-depth description
Common::String _pickUp; // Message for if you can't pick up object

const uint8 (*_sequences)[MAX_HOLMES_SEQUENCE][MAX_FRAME]; // Holds animation sequences
Common::Array<WalkSequence> _walkSequences; // Holds animation sequences
ImageFile *_images; // Sprite images
ImageFrame *_imageFrame; // Pointer to shape in the images
int _walkCount; // Character walk counter
Expand All @@ -124,8 +142,12 @@ class Sprite {
int _status; // Status: open/closed, moved/not moved
int8 _misc; // Miscellaneous use
int _numFrames; // How many frames the object has
ImageFile *_altImages;
bool _altSequences;
ImageFrame *_stopFrames[8]; // Stop/rest frame for each direction
public:
Sprite() { clear(); }

static void setVm(SherlockEngine *vm) { _vm = vm; }

/**
Expand Down
160 changes: 140 additions & 20 deletions engines/sherlock/people.cpp
Expand Up @@ -50,10 +50,37 @@ static const uint8 CHARACTER_SEQUENCES[MAX_HOLMES_SEQUENCE][MAX_FRAME] = {
{ 52, 1, 2, 3, 4, 0 } // Goto Stand Down Left
};

// Rose Tattoo walk image libraries
// Walk resources within WALK.LIB
#define NUM_IN_WALK_LIB 10
const char *const WALK_LIB_NAMES[10] = {
"SVGAWALK.VGS",
"COATWALK.VGS",
"WATSON.VGS",
"NOHAT.VGS",
"TUPRIGHT.VGS",
"TRIGHT.VGS",
"TDOWNRG.VGS",
"TWUPRIGH.VGS",
"TWRIGHT.VGS",
"TWDOWNRG.VGS"
};

/*----------------------------------------------------------------*/

void WalkSequence::load(Common::SeekableReadStream &s) {
char buffer[9];
s.read(buffer, 9);
_vgsName = Common::String(buffer);
_horizFlip = s.readByte() != 0;

_sequences.resize(s.readUint16LE());
s.read(&_sequences[0], _sequences.size());
}

/*----------------------------------------------------------------*/

People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) {
_walkLoaded = false;
_holmesOn = true;
_oldWalkSequence = -1;
_allowWalkAbort = false;
Expand All @@ -68,13 +95,18 @@ People::People(SherlockEngine *vm) : _vm(vm), _player(_data[0]) {
_holmesQuotient = 0;
_hSavedPos = Common::Point(-1, -1);
_hSavedFacing = -1;
_forceWalkReload = false;
_useWalkLib = false;

_portrait._sequences = new byte[32];
}

People::~People() {
if (_walkLoaded)
delete _data[PLAYER]._images;
for (int idx = 0; idx < MAX_PLAYERS; ++idx) {
if (_data[idx]._walkLoaded)
delete _data[PLAYER]._images;
}

delete _talkPics;
delete[] _portrait._sequences;
}
Expand All @@ -88,7 +120,6 @@ void People::reset() {
p._type = CHARACTER;
p._position = Common::Point(10000, 11000);
p._sequenceNumber = STOP_DOWNRIGHT;
p._sequences = &CHARACTER_SEQUENCES;
p._imageFrame = nullptr;
p._frameNumber = 1;
p._delta = Common::Point(0, 0);
Expand All @@ -102,32 +133,106 @@ void People::reset() {
p._goto = Common::Point(0, 0);
p._status = 0;

// Load the default walk sequences
p._walkSequences.resize(MAX_HOLMES_SEQUENCE);
for (int idx = 0; idx < MAX_HOLMES_SEQUENCE; ++idx) {
p._walkSequences[idx]._sequences.clear();

const byte *pSrc = &CHARACTER_SEQUENCES[idx][0];
do {
p._walkSequences[idx]._sequences.push_back(*pSrc);
} while (*pSrc++);
}

// Reset any walk path in progress when Sherlock leaves scenes
_walkTo.clear();
}

bool People::loadWalk() {
if (_walkLoaded) {
return false;
Resources &res = *_vm->_res;
bool result = false;

if (IS_SERRATED_SCALPEL) {
if (_data[PLAYER]._walkLoaded) {
return false;
} else {
_data[PLAYER]._images = new ImageFile("walk.vgs");
_data[PLAYER].setImageFrame();
_data[PLAYER]._walkLoaded = true;

result = true;
}
} else {
_data[PLAYER]._images = new ImageFile("walk.vgs");
_data[PLAYER].setImageFrame();
_walkLoaded = true;
for (int idx = 0; idx < MAX_PLAYERS; ++idx) {
if (!_data[idx]._walkLoaded && (_data[idx]._type == CHARACTER || _data[idx]._type == HIDDEN_CHARACTER)) {
if (_data[idx]._type == HIDDEN_CHARACTER)
_data[idx]._type = INVALID;

// See if this is one of the more used Walk Graphics stored in WALK.LIB
for (int libNum = 0; libNum < NUM_IN_WALK_LIB; ++libNum) {
if (!_data[0]._walkVGSName.compareToIgnoreCase(WALK_LIB_NAMES[libNum])) {
_useWalkLib = true;
break;
}
}

// Load the images for the character
_data[idx]._images = new ImageFile(_data[idx]._walkVGSName, false);
_data[idx]._numFrames = _data[idx]._images->size();

// Load walk sequence data
Common::String fname = Common::String(_data[idx]._walkVGSName.c_str(), strchr(_data[idx]._walkVGSName.c_str(), '.'));
fname += ".SEQ";

// Load the walk sequence data
Common::SeekableReadStream *stream = res.load(fname, _useWalkLib ? "walk.lib" : "vgs.lib");

_data[idx]._walkSequences.resize(stream->readByte());

for (uint seqNum = 0; seqNum < _data[idx]._walkSequences.size(); ++seqNum)
_data[idx]._walkSequences[seqNum].load(*stream);

// Close the sequences resource
delete stream;
_useWalkLib = false;

_data[idx]._frameNumber = 0;
_data[idx].setImageFrame();

// Set the stop Frames pointers
for (int dirNum = 0; dirNum < 8; ++dirNum) {
int count = 0;
while (_data[idx]._walkSequences[dirNum + 8][count] != 0)
++count;
count += 2;
count = _data[idx]._walkSequences[dirNum + 8][count] - 1;
_data[idx]._stopFrames[dirNum] = &(*_data[idx]._images)[count];
}

return true;
result = true;
_data[idx]._walkLoaded = true;
} else if (_data[idx]._type != CHARACTER) {
_data[idx]._walkLoaded = false;
}
}
}

_forceWalkReload = false;
return result;
}

bool People::freeWalk() {
if (_walkLoaded) {
delete _player._images;
_player._images = nullptr;
bool result = false;

_walkLoaded = false;
return true;
} else {
return false;
for (int idx = 0; idx < MAX_PLAYERS; ++idx) {
if (_data[idx]._walkLoaded) {
delete _data[idx]._images;
_data[idx]._images = nullptr;
result = true;
}
}

return result;
}

void People::setWalking() {
Expand Down Expand Up @@ -553,9 +658,24 @@ void People::setTalking(int speaker) {

void People::synchronize(Common::Serializer &s) {
s.syncAsByte(_holmesOn);
s.syncAsSint16LE(_player._position.x);
s.syncAsSint16LE(_player._position.y);
s.syncAsSint16LE(_player._sequenceNumber);

if (IS_SERRATED_SCALPEL) {
s.syncAsSint16LE(_player._position.x);
s.syncAsSint16LE(_player._position.y);
s.syncAsSint16LE(_player._sequenceNumber);
} else {
for (int idx = 0; idx < MAX_PLAYERS; ++idx) {
Person &p = _data[idx];
s.syncAsSint16LE(p._position.x);
s.syncAsSint16LE(p._position.y);
s.syncAsSint16LE(p._sequenceNumber);
s.syncAsSint16LE(p._type);
s.syncString(p._walkVGSName);
s.syncString(p._description);
s.syncString(p._examine);
}
}

s.syncAsSint16LE(_holmesQuotient);

if (s.isLoading()) {
Expand Down

0 comments on commit a66570f

Please sign in to comment.