aboutsummaryrefslogtreecommitdiff
path: root/engines/sherlock/objects.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sherlock/objects.cpp')
-rw-r--r--engines/sherlock/objects.cpp121
1 files changed, 85 insertions, 36 deletions
diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
index 6ef08c28cc..a05351b170 100644
--- a/engines/sherlock/objects.cpp
+++ b/engines/sherlock/objects.cpp
@@ -60,6 +60,8 @@ BaseObject::BaseObject() {
_sequences = nullptr;
_images = nullptr;
_imageFrame = nullptr;
+ _sequenceNumber = 0;
+ _startSeq = 0;
_walkCount = 0;
_allow = 0;
_frameNumber = 0;
@@ -88,7 +90,7 @@ BaseObject::BaseObject() {
bool BaseObject::hasAborts() const {
int seqNum = _talkSeq;
- // See if the object is in it's regular sequence
+ // See if the object is in its regular sequence
bool startChecking = !seqNum || _type == CHARACTER;
uint idx = 0;
@@ -104,14 +106,14 @@ bool BaseObject::hasAborts() const {
// If we've started checking and we've encountered another Talk or Listen Sequence Code,
// then we're done checking this sequence because this is where it would repeat
if (startChecking && (v == TALK_SEQ_CODE || v == TALK_LISTEN_CODE))
- return false;
+ break;
// See if we've found the beginning of a Talk Sequence
if ((v == TALK_SEQ_CODE && seqNum < 128) || (v == TALK_LISTEN_CODE && seqNum >= 128)) {
// If checking was already on and we came across one of these codes, then there couldn't
// have been an Allow Talk Interrupt code in the sequence we were checking, so we're done.
if (startChecking)
- return false;
+ break;
seqNum--;
// See if we're at the correct Talk Sequence Number
@@ -132,7 +134,7 @@ bool BaseObject::hasAborts() const {
}
} while (idx < _seqSize);
- return true;
+ return false;
}
void BaseObject::checkObject() {
@@ -178,6 +180,7 @@ void BaseObject::checkObject() {
if (IS_ROSE_TATTOO && v == ALLOW_TALK_CODE) {
if (_gotoSeq) {
setObjTalkSequence(_gotoSeq);
+ _gotoSeq = 0;
} else {
++_frameNumber;
}
@@ -347,19 +350,23 @@ bool BaseObject::checkEndOfSequence() {
if (_type == REMOVE || _type == INVALID)
return false;
- if (_sequences[_frameNumber] == 0 || _frameNumber >= checkFrame) {
+ if (_frameNumber < 0 || _frameNumber >= checkFrame || _sequences[_frameNumber] == 0) {
result = true;
- if (_frameNumber >= (checkFrame - 1)) {
+ if (_frameNumber < 0 || _frameNumber >= (checkFrame - 1)) {
_frameNumber = START_FRAME;
} else {
// Determine next sequence to use
int seq = _sequences[_frameNumber + 1];
+ // If the object has been turned off, we're going nowhere
+ if (IS_ROSE_TATTOO && (_type == HIDE_SHAPE || _type == HIDDEN || _type == REMOVE))
+ return false;
+
if (seq == 99) {
--_frameNumber;
- screen._backBuffer1.transBlitFrom(*_imageFrame, _position);
- screen._backBuffer2.transBlitFrom(*_imageFrame, _position);
+ screen._backBuffer1.SHtransBlitFrom(*_imageFrame, _position);
+ screen._backBuffer2.SHtransBlitFrom(*_imageFrame, _position);
_type = INVALID;
} else if (IS_ROSE_TATTOO && _talkSeq && seq == 0) {
setObjTalkSequence(_talkSeq);
@@ -397,6 +404,10 @@ void BaseObject::setObjSequence(int seq, bool wait) {
Scene &scene = *_vm->_scene;
int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
+ if (IS_ROSE_TATTOO && (seq == -1 || seq == 255))
+ // This means goto beginning
+ seq = 0;
+
if (seq >= 128) {
// Loop the sequence until the count exceeded
seq -= 128;
@@ -419,6 +430,10 @@ void BaseObject::setObjSequence(int seq, bool wait) {
if (_frameNumber >= checkFrame)
_frameNumber = 0;
+ // For Rose Tattoo, save the starting frame for new sequences
+ if (IS_ROSE_TATTOO)
+ _startSeq = _frameNumber;
+
_seqCounter = 0;
if (_sequences[_frameNumber] == 0)
seq = _sequences[_frameNumber + 1];
@@ -426,12 +441,18 @@ void BaseObject::setObjSequence(int seq, bool wait) {
return;
} else {
// Find beginning of sequence
- do {
- --_frameNumber;
- } while (_frameNumber > 0 && _sequences[_frameNumber] != 0);
+ if (IS_ROSE_TATTOO) {
+ // Use the saved start of the sequence to reset the frame
+ _frameNumber = _startSeq;
+ } else {
+ // For Scalpel, scan backwards from the end of the sequence to find its start
+ do {
+ --_frameNumber;
+ } while (_frameNumber > 0 && _sequences[_frameNumber] != 0);
- if (_frameNumber != 0)
- _frameNumber += 2;
+ if (_frameNumber != 0)
+ _frameNumber += 2;
+ }
return;
}
@@ -444,16 +465,35 @@ void BaseObject::setObjSequence(int seq, bool wait) {
int seqCc = 0;
while (seqCc < seq && idx < checkFrame) {
- ++idx;
- if (_sequences[idx] == 0) {
- ++seqCc;
- idx += 2;
+ if (IS_SERRATED_SCALPEL) {
+ ++idx;
+
+ if (_sequences[idx] == 0) {
+ ++seqCc;
+ idx += 2;
+ }
+ } else {
+ byte s = _sequences[idx];
+
+ if (s == 0) {
+ ++seqCc;
+ ++idx;
+ } else if (s == MOVE_CODE || s == TELEPORT_CODE) {
+ idx += 4;
+ } else if (s == CALL_TALK_CODE) {
+ idx += 8;
+ } else if (s == HIDE_CODE) {
+ idx += 2;
+ }
+
+ ++idx;
}
}
if (idx >= checkFrame)
idx = 0;
_frameNumber = idx;
+ _startSeq = idx;
if (wait) {
seqCc = idx;
@@ -499,7 +539,7 @@ int BaseObject::checkNameForCodes(const Common::String &name, FixedTextActionId
// G: Have object go somewhere
// A: Add onto existing co-ordinates
Common::String sx(name.c_str() + 2, name.c_str() + 5);
- Common::String sy(name.c_str() + 6, name.c_str() + 9);
+ Common::String sy(name.c_str() + 5, name.c_str() + 8);
if (ch == 'G')
_position = Common::Point(atoi(sx.c_str()), atoi(sy.c_str()));
@@ -580,8 +620,9 @@ void Sprite::clear() {
_images = nullptr;
_imageFrame = nullptr;
_walkCount = 0;
+ _oldWalkSequence = 0;
_allow = 0;
- _frameNumber = _sequenceNumber = 0;
+ _frameNumber = 0;
_position.x = _position.y = 0;
_delta.x = _delta.y = 0;
_oldPosition.x = _oldPosition.y = 0;
@@ -594,7 +635,10 @@ void Sprite::clear() {
_misc = 0;
_altImages = nullptr;
_altSeq = 0;
- Common::fill(&_stopFrames[0], &_stopFrames[8], (ImageFrame *)nullptr);
+ _centerWalk = 0;
+
+ for (int i = 0; i < 8; i++)
+ _stopFrames[i] = nullptr;
}
void Sprite::setImageFrame() {
@@ -935,7 +979,6 @@ void UseType::synchronize(Serializer &s) {
/*----------------------------------------------------------------*/
Object::Object(): BaseObject() {
- _sequenceNumber = 0;
_sequenceOffset = 0;
_pickup = 0;
_defaultCommand = 0;
@@ -1020,6 +1063,11 @@ void Object::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
for (int idx = 0; idx < 6; ++idx)
_use[idx].load(s, true);
+ // WORKAROUND: Fix German version using hatpin/pin in pillow in Pratt's loft
+ if (_use[1]._target == "Nadel" && _use[1]._verb == "Untersuche"
+ && _use[2]._target == "Nadel" && _use[2]._verb == "Untersuche")
+ _use[1]._target = "Alte Nadel";
+
_quickDraw = s.readByte();
_scaleVal = s.readUint16LE();
_requiredFlag[1] = s.readSint16LE();
@@ -1189,26 +1237,16 @@ void Object::setObjTalkSequence(int seq) {
// See if we're supposed to restore the object's sequence from the talk sequence stack
if (seq == -1) {
- TalkSequence &ts = talk._talkSequenceStack[_restoreSlot];
if (_seqTo != 0)
_sequences[_frameNumber] = _seqTo;
- _frameNumber = ts._frameNumber;
- _sequenceNumber = ts._sequenceNumber;
- _seqStack = ts._seqStack;
- _seqTo = ts._seqTo;
- _seqCounter = ts._seqCounter;
- _seqCounter2 = ts._seqCounter2;
- _talkSeq = 0;
-
- // Flag this slot as free again
- ts._obj = nullptr;
+ talk.pullSequence(_restoreSlot);
return;
}
assert(_type != CHARACTER);
- talk.pushTalkSequence(this);
+ talk.pushSequenceEntry(this);
int talkSeqNum = seq;
// Find where the talk sequence data begins in the object
@@ -1307,7 +1345,7 @@ void Object::adjustObject() {
frame = 0;
int imgNum = _sequences[frame];
- if (imgNum > _maxFrames)
+ if (imgNum > _maxFrames || imgNum == 0)
imgNum = 1;
_imageFrame = &(*_images)[imgNum - 1];
@@ -1393,8 +1431,19 @@ int Object::pickUpObject(FixedTextActionId fixedTextActionId) {
ui.clearInfo();
Common::String itemName = _description;
- itemName.setChar(tolower(itemName[0]), 0);
- screen.print(Common::Point(0, INFO_LINE + 1), COL_INFO_FOREGROUND, "Picked up %s", itemName.c_str());
+
+ // It's an item, make it lowercase
+ switch (_vm->getLanguage()) {
+ case Common::DE_DEU:
+ // don't do this for German version
+ break;
+ default:
+ // do it for English + Spanish version
+ itemName.setChar(tolower(itemName[0]), 0);
+ break;
+ }
+
+ screen.print(Common::Point(0, INFO_LINE + 1), COL_INFO_FOREGROUND, fixedText.getObjectPickedUpText(), itemName.c_str());
ui._menuCounter = 25;
}
}