[Scummvm-cvs-logs] scummvm master -> 5364b46d6ac2a0907d864ec1aa60cd4835f4d1dc
dreammaster
dreammaster at scummvm.org
Sun Jun 14 15:00:00 CEST 2015
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
5364b46d6a SHERLOCK: RT: Move checkObject from Object to BaseObject
Commit: 5364b46d6ac2a0907d864ec1aa60cd4835f4d1dc
https://github.com/scummvm/scummvm/commit/5364b46d6ac2a0907d864ec1aa60cd4835f4d1dc
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2015-06-14T08:56:00-04:00
Commit Message:
SHERLOCK: RT: Move checkObject from Object to BaseObject
checkObject needs to be called in checkSprite now, which is in
the Sprite class. So the method and a few others it depeends
on have been moved into BaseObject
Changed paths:
engines/sherlock/objects.cpp
engines/sherlock/objects.h
engines/sherlock/scalpel/scalpel_scene.cpp
diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp
index 29c5d73..df91995 100644
--- a/engines/sherlock/objects.cpp
+++ b/engines/sherlock/objects.cpp
@@ -70,10 +70,15 @@ static const AdjustWalk ADJUST_WALKS[NUM_ADJUSTED_WALKS] = {
{ "ITDOWNRG", 8, 0, 0 }
};
-SherlockEngine *Sprite::_vm;
+SherlockEngine *BaseObject::_vm;
/*----------------------------------------------------------------*/
+void BaseObject::setVm(SherlockEngine *vm) {
+ _vm = vm;
+ _countCAnimFrames = false;
+}
+
BaseObject::BaseObject() {
_type = INVALID;
_sequences = nullptr;
@@ -156,1023 +161,1114 @@ bool BaseObject::hasAborts() const {
return true;
}
-/*----------------------------------------------------------------*/
-
-void Sprite::clear() {
- _name = "";
- _description = "";
- _examine.clear();
- _pickUp = "";
- _walkSequences.clear();
- _sequences = nullptr;
- _images = nullptr;
- _imageFrame = nullptr;
- _walkCount = 0;
- _allow = 0;
- _frameNumber = _sequenceNumber = 0;
- _position.x = _position.y = 0;
- _delta.x = _delta.y = 0;
- _oldPosition.x = _oldPosition.y = 0;
- _oldSize.x = _oldSize.y = 0;
- _goto.x = _goto.y = 0;
- _type = INVALID;
- _pickUp.clear();
- _noShapeSize.x = _noShapeSize.y = 0;
- _status = 0;
- _misc = 0;
- _altImages = nullptr;
- _altSeq = 0;
- Common::fill(&_stopFrames[0], &_stopFrames[8], (ImageFrame *)nullptr);
-}
-
-void Sprite::setImageFrame() {
- int frameNum = MAX(_frameNumber, 0);
- int imageNumber = _walkSequences[_sequenceNumber][frameNum];
-
- if (IS_SERRATED_SCALPEL)
- imageNumber = imageNumber + _walkSequences[_sequenceNumber][0] - 2;
- else if (imageNumber > _maxFrames)
- imageNumber = 1;
+void BaseObject::checkObject() {
+ Scene &scene = *_vm->_scene;
+ Sound &sound = *_vm->_sound;
+ Talk &talk = *_vm->_talk;
+ int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
+ bool codeFound;
- // Get the images to use
- ImageFile *images = _altSeq ? _altImages : _images;
- assert(images);
+ if (_seqTo) {
+ byte *ptr = &_sequences[_frameNumber];
+ if (*ptr == _seqTo) {
+ // The sequence is completed
+ *ptr = _seqTo + SEQ_TO_CODE + 128; // Reset to normal
+ _seqTo = 0;
+ } else {
+ // Continue doing sequence
+ if (*ptr > _seqTo)
+ *ptr -= 1;
+ else
+ *ptr += 1;
- if (_vm->getPlatform() == Common::kPlatform3DO) {
- // only do this to the image-array with 110 entries
- // map uses another image-array and this code
- if (images->size() == 110) {
- // 3DO has 110 animation frames inside walk.anim
- // PC has 55
- // this adjusts the framenumber accordingly
- // sort of HACK
- imageNumber *= 2;
+ return;
}
- } else if (IS_ROSE_TATTOO) {
- --imageNumber;
}
- // Set the frame pointer
- _imageFrame = &(*images)[imageNumber];
-}
-
-void Sprite::checkSprite() {
- Events &events = *_vm->_events;
- People &people = *_vm->_people;
- Scene &scene = *_vm->_scene;
- Screen &screen = *_vm->_screen;
- Talk &talk = *_vm->_talk;
- Point32 pt;
- Common::Rect objBounds;
- Common::Point spritePt(_position.x / FIXED_INT_MULTIPLIER, _position.y / FIXED_INT_MULTIPLIER);
-
- if (_type != CHARACTER || (IS_SERRATED_SCALPEL && talk._talkCounter))
- return;
-
- pt = _walkCount ? _position + _delta : _position;
- pt.x /= FIXED_INT_MULTIPLIER;
- pt.y /= FIXED_INT_MULTIPLIER;
+ ++_frameNumber;
- if (IS_ROSE_TATTOO) {
- // TODO: Needs to be called
- //checkObject(1001);
+ do {
+ // Check for end of sequence
+ codeFound = checkEndOfSequence();
- // For Rose Tattoo, we only do the further processing for Sherlock
- if (this != &people[HOLMES])
- return;
- }
+ if (_sequences[_frameNumber] >= 128 && _frameNumber < checkFrame) {
+ codeFound = true;
+ int v = _sequences[_frameNumber];
- for (uint idx = 0; idx < scene._bgShapes.size() && !talk._talkToAbort; ++idx) {
- Object &obj = scene._bgShapes[idx];
- if (obj._aType <= PERSON || obj._type == INVALID || obj._type == HIDDEN)
- continue;
+ // Check for a Talk or Listen Sequence
+ if (IS_ROSE_TATTOO && v == ALLOW_TALK_CODE) {
+ if (_gotoSeq) {
+ setObjTalkSequence(_gotoSeq);
+ } else {
+ ++_frameNumber;
+ }
+ } else if (IS_ROSE_TATTOO && (v == TALK_SEQ_CODE || v == TALK_LISTEN_CODE)) {
+ if (_talkSeq)
+ setObjTalkSequence(_talkSeq);
+ else
+ setObjSequence(0, false);
+ } else if (v >= GOTO_CODE) {
+ // Goto code found
+ v -= GOTO_CODE;
+ _seqCounter2 = _seqCounter;
+ _seqStack = _frameNumber + 1;
+ setObjSequence(v, false);
+ } else if (v >= SOUND_CODE && (v < (SOUND_CODE + 30))) {
+ codeFound = true;
+ ++_frameNumber;
+ v -= SOUND_CODE + (IS_SERRATED_SCALPEL ? 1 : 0);
- if (obj._type == NO_SHAPE) {
- objBounds = Common::Rect(obj._position.x, obj._position.y,
- obj._position.x + obj._noShapeSize.x + 1, obj._position.y + obj._noShapeSize.y + 1);
- } else {
- int xp = obj._position.x + obj._imageFrame->_offset.x;
- int yp = obj._position.y + obj._imageFrame->_offset.y;
- objBounds = Common::Rect(xp, yp,
- xp + obj._imageFrame->_frame.w + 1, yp + obj._imageFrame->_frame.h + 1);
- }
+ if (sound._soundOn && !_countCAnimFrames) {
+ if (!scene._sounds[v]._name.empty() && sound._digitized)
+ sound.playLoadedSound(v, WAIT_RETURN_IMMEDIATELY);
+ }
+ } else if (v >= FLIP_CODE && v < (FLIP_CODE + 3)) {
+ // Flip code
+ codeFound = true;
+ ++_frameNumber;
+ v -= FLIP_CODE;
- if (objBounds.contains(pt)) {
- if (objBounds.contains(spritePt)) {
- // Current point is already inside the the bounds, so impact occurred
- // on a previous call. So simply do nothing until we're clear of the box
- switch (obj._aType) {
- case TALK_MOVE:
- if (_walkCount) {
- // Holmes is moving
- obj._type = HIDDEN;
- obj.setFlagsAndToggles();
- talk.talkTo(obj._use[0]._target);
- }
+ // Alter the flipped status
+ switch (v) {
+ case 0:
+ // Clear the flag
+ _flags &= ~OBJ_FLIPPED;
+ break;
+ case 1:
+ // Set the flag
+ _flags |= OBJ_FLIPPED;
+ break;
+ case 2:
+ // Toggle the flag
+ _flags ^= OBJ_FLIPPED;
break;
+ default:
+ break;
+ }
+ } else if (IS_ROSE_TATTOO && v == TELEPORT_CODE) {
+ _position.x = READ_LE_UINT16(&_sequences[_frameNumber + 1]);
+ _position.y = READ_LE_UINT16(&_sequences[_frameNumber + 3]);
- case PAL_CHANGE:
- case PAL_CHANGE2:
- if (_walkCount) {
- int palStart = atoi(obj._use[0]._names[0].c_str()) * 3;
- int palLength = atoi(obj._use[0]._names[1].c_str()) * 3;
- int templ = atoi(obj._use[0]._names[2].c_str()) * 3;
- if (templ == 0)
- templ = 100;
+ _frameNumber += 5;
+ } else if (IS_ROSE_TATTOO && v == CALL_TALK_CODE) {
+ Common::String filename;
+ for (int idx = 0; idx < 8; ++idx) {
+ if (_sequences[_frameNumber + 1 + idx] != 1)
+ filename += (char)_sequences[_frameNumber + 1 + idx];
+ else
+ break;
+ }
- // Ensure only valid palette change data found
- if (palLength > 0) {
- // Figure out how far into the shape Holmes is so that we
- // can figure out what percentage of the original palette
- // to set the current palette to
- int palPercent = (pt.x - objBounds.left) * 100 / objBounds.width();
- palPercent = palPercent * templ / 100;
- if (obj._aType == PAL_CHANGE)
- // Invert percentage
- palPercent = 100 - palPercent;
+ _frameNumber += 8;
+ talk.talkTo(filename);
- for (int i = palStart; i < (palStart + palLength); ++i)
- screen._sMap[i] = screen._cMap[i] * palPercent / 100;
+ } else if (IS_ROSE_TATTOO && v == HIDE_CODE) {
+ switch (_sequences[_frameNumber + 2]) {
+ case 1:
+ // Hide Object
+ if (scene._bgShapes[_sequences[_frameNumber + 1] - 1]._type != HIDDEN)
+ scene._bgShapes[_sequences[_frameNumber + 1] - 1].toggleHidden();
+ break;
- events.pollEvents();
- screen.setPalette(screen._sMap);
- }
- }
+ case 2:
+ // Activate Object
+ if (scene._bgShapes[_sequences[_frameNumber + 1] - 1]._type == HIDDEN)
+ scene._bgShapes[_sequences[_frameNumber + 1] - 1].toggleHidden();
break;
- case TALK:
- case TALK_EVERY:
- obj._type = HIDDEN;
- obj.setFlagsAndToggles();
- talk.talkTo(obj._use[0]._target);
+ case 3:
+ // Toggle Object
+ scene._bgShapes[_sequences[_frameNumber + 1] - 1].toggleHidden();
break;
default:
break;
}
+ _frameNumber += 3;
+
} else {
- // New impact just occurred
- switch (obj._aType) {
- case BLANK_ZONE:
- // A blank zone masks out all other remaining zones underneath it.
- // If this zone is hit, exit the outer loop so we do not check anymore
- return;
-
- case SOLID:
- case TALK:
- // Stop walking
- if (obj._aType == TALK) {
- obj.setFlagsAndToggles();
- talk.talkTo(obj._use[0]._target);
- } else {
- gotoStand();
- }
- break;
+ v -= 128;
- case TALK_EVERY:
- if (obj._aType == TALK_EVERY) {
- obj._type = HIDDEN;
- obj.setFlagsAndToggles();
- talk.talkTo(obj._use[0]._target);
- } else {
- gotoStand();
- }
- break;
+ // 68-99 is a squence code
+ if (v > SEQ_TO_CODE) {
+ byte *p = &_sequences[_frameNumber];
+ v -= SEQ_TO_CODE; // # from 1-32
+ _seqTo = v;
+ *p = *(p - 1);
- case FLAG_SET:
- obj.setFlagsAndToggles();
- obj._type = HIDDEN;
- break;
+ if (*p > 128)
+ // If the high bit is set, convert to a real frame
+ *p -= (byte)(SEQ_TO_CODE - 128);
- case WALK_AROUND:
- if (objBounds.contains(people[HOLMES]._walkTo.front())) {
- // Reached zone
- gotoStand();
- } else {
- // Destination not within box, walk to best corner
- Common::Point walkPos;
+ if (*p > _seqTo)
+ *p -= 1;
+ else
+ *p += 1;
- if (spritePt.x >= objBounds.left && spritePt.x < objBounds.right) {
- // Impact occurred due to vertical movement. Determine whether to
- // travel to the left or right side
- if (_delta.x > 0)
- // Go to right side
- walkPos.x = objBounds.right + CLEAR_DIST_X;
- else if (_delta.x < 0) {
- // Go to left side
- walkPos.x = objBounds.left - CLEAR_DIST_X;
- } else {
- // Going straight up or down. So choose best side
- if (spritePt.x >= (objBounds.left + objBounds.width() / 2))
- walkPos.x = objBounds.right + CLEAR_DIST_X;
- else
- walkPos.x = objBounds.left - CLEAR_DIST_X;
- }
+ // Will be incremented below to return back to original value
+ --_frameNumber;
+ v = 0;
- walkPos.y = (_delta.y >= 0) ? objBounds.top - CLEAR_DIST_Y :
- objBounds.bottom + CLEAR_DIST_Y;
- } else {
- // Impact occurred due to horizontal movement
- if (_delta.y > 0)
- // Go to bottom of box
- walkPos.y = objBounds.bottom + CLEAR_DIST_Y;
- else if (_delta.y < 0)
- // Go to top of box
- walkPos.y = objBounds.top - CLEAR_DIST_Y;
- else {
- // Going straight horizontal, so choose best side
- if (spritePt.y >= (objBounds.top + objBounds.height() / 2))
- walkPos.y = objBounds.bottom + CLEAR_DIST_Y;
- else
- walkPos.y = objBounds.top - CLEAR_DIST_Y;
- }
+ } else if (IS_ROSE_TATTOO && v == 10) {
+ // Set delta for objects
+ _delta = Common::Point(READ_LE_UINT16(&_sequences[_frameNumber + 1]),
+ READ_LE_UINT16(&_sequences[_frameNumber + 3]));
+ _noShapeSize = Common::Point(0, 0);
+ _frameNumber += 4;
- walkPos.x = (_delta.x >= 0) ? objBounds.left - CLEAR_DIST_X :
- objBounds.right + CLEAR_DIST_X;
- }
+ } else if (v == 10) {
+ // Set delta for objects
+ Common::Point pt(_sequences[_frameNumber + 1], _sequences[_frameNumber + 2]);
+ if (pt.x > 128)
+ pt.x = (pt.x - 128) * -1;
+ else
+ pt.x--;
- walkPos.x += people[HOLMES]._imageFrame->_frame.w / 2;
- people._walkDest = walkPos;
- people[HOLMES]._walkTo.push(walkPos);
- people[HOLMES].setWalking();
- }
- break;
+ if (pt.y > 128)
+ pt.y = (pt.y - 128) * -1;
+ else
+ pt.y--;
- case DELTA:
- _position.x += 200;
- break;
+ _delta = pt;
+ _frameNumber += 2;
- default:
- break;
+ } else if (v < USE_COUNT) {
+ for (int idx = 0; idx < NAMES_COUNT; ++idx) {
+ checkNameForCodes(_use[v]._names[idx], nullptr);
+ }
+
+ if (_use[v]._useFlag)
+ _vm->setFlags(_use[v]._useFlag);
}
+
+ ++_frameNumber;
}
}
- }
+ } while (codeFound);
}
-const Common::Rect Sprite::getOldBounds() const {
- return Common::Rect(_oldPosition.x, _oldPosition.y, _oldPosition.x + _oldSize.x, _oldPosition.y + _oldSize.y);
-}
+bool BaseObject::checkEndOfSequence() {
+ Screen &screen = *_vm->_screen;
+ int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
+ bool result = false;
-void Sprite::setObjTalkSequence(int seq) {
- assert(seq != -1 && _type == CHARACTER);
+ if (_type == REMOVE || _type == INVALID)
+ return false;
- if (_seqTo) {
- // reset to previous value
- _walkSequences[_sequenceNumber]._sequences[_frameNumber] = _seqTo;
- _seqTo = 0;
+ if (_sequences[_frameNumber] == 0 || _frameNumber >= checkFrame) {
+ result = true;
+
+ if (_frameNumber >= (checkFrame - 1)) {
+ _frameNumber = START_FRAME;
+ } else {
+ // Determine next sequence to use
+ int seq = _sequences[_frameNumber + 1];
+
+ if (seq == 99) {
+ --_frameNumber;
+ screen._backBuffer1.transBlitFrom(*_imageFrame, _position);
+ screen._backBuffer2.transBlitFrom(*_imageFrame, _position);
+ _type = INVALID;
+ } else if (IS_ROSE_TATTOO && _talkSeq && seq == 0) {
+ setObjTalkSequence(_talkSeq);
+ } else {
+ setObjSequence(seq, false);
+ }
+ }
+
+ if (_allow && _frameNumber == 0) {
+ // canimation just ended
+ if (_type != NO_SHAPE && _type != REMOVE) {
+ _type = REMOVE;
+
+ if (!_countCAnimFrames) {
+ // Save details before shape is removed
+ _delta.x = _imageFrame->_frame.w;
+ _delta.y = _imageFrame->_frame.h;
+ _position += _imageFrame->_offset;
+
+ // Free the images
+ delete _images;
+ _images = nullptr;
+ _imageFrame = nullptr;
+ }
+ } else {
+ _type = INVALID;
+ }
+ }
}
- _sequenceNumber = _gotoSeq;
- _frameNumber = 0;
- checkWalkGraphics();
+ return result;
}
-void Sprite::checkWalkGraphics() {
- People &people = *_vm->_people;
+void BaseObject::setObjSequence(int seq, bool wait) {
+ Scene &scene = *_vm->_scene;
+ int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
- if (_images == nullptr) {
- freeAltGraphics();
- return;
- }
+ if (seq >= 128) {
+ // Loop the sequence until the count exceeded
+ seq -= 128;
- Common::String filename = Common::String::format("%s.vgs", _walkSequences[_sequenceNumber]._vgsName.c_str());
+ ++_seqCounter;
+ if (_seqCounter >= seq) {
+ // Go to next sequence
+ if (_seqStack) {
+ _frameNumber = _seqStack;
+ _seqStack = 0;
+ _seqCounter = _seqCounter2;
+ _seqCounter2 = 0;
+ if (_frameNumber >= checkFrame)
+ _frameNumber = START_FRAME;
- // Set the adjust depending on if we have to fine tune the x position of this particular graphic
- _adjust.x = _adjust.y = 0;
+ return;
+ }
- for (int idx = 0; idx < NUM_ADJUSTED_WALKS; ++idx) {
- if (!scumm_strnicmp(_walkSequences[_sequenceNumber]._vgsName.c_str(), ADJUST_WALKS[idx]._vgsName,
- strlen(ADJUST_WALKS[idx]._vgsName))) {
- if (_walkSequences[_sequenceNumber]._horizFlip)
- _adjust.x = ADJUST_WALKS[idx]._flipXAdjust;
+ _frameNumber += 2;
+ if (_frameNumber >= checkFrame)
+ _frameNumber = 0;
+
+ _seqCounter = 0;
+ if (_sequences[_frameNumber] == 0)
+ seq = _sequences[_frameNumber + 1];
else
- _adjust.x = ADJUST_WALKS[idx]._xAdjust;
+ return;
+ } else {
+ // Find beginning of sequence
+ do {
+ --_frameNumber;
+ } while (_frameNumber > 0 && _sequences[_frameNumber] != 0);
- _adjust.y = ADJUST_WALKS[idx]._yAdjust;
- break;
+ if (_frameNumber != 0)
+ _frameNumber += 2;
+
+ return;
}
+ } else {
+ // Reset sequence counter
+ _seqCounter = 0;
}
- // See if we're already using Alternate Graphics
- if (_altSeq) {
- // See if the VGS file called for is different than the alternate graphics already loaded
- if (!_walkSequences[_sequenceNumber]._vgsName.compareToIgnoreCase(_walkSequences[_altSeq - 1]._vgsName)) {
- // Different AltGraphics, Free the old ones
- freeAltGraphics();
+ int idx = 0;
+ int seqCc = 0;
+
+ while (seqCc < seq && idx < checkFrame) {
+ ++idx;
+ if (_sequences[idx] == 0) {
+ ++seqCc;
+ idx += 2;
}
}
- // If there is no Alternate Sequence set, see if we need to load a new one
- if (!_altSeq) {
- int npcNum = -1;
- // Find which NPC this is so we can check the name of the graphics loaded
- for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
- if (this == &people[idx]) {
- npcNum = idx;
- break;
- }
- }
+ if (idx >= checkFrame)
+ idx = 0;
+ _frameNumber = idx;
- if (npcNum != -1) {
- // See if the VGS file called for is different than the main graphics which are already loaded
- if (!filename.compareToIgnoreCase(people[npcNum]._walkVGSName)) {
- // See if this is one of the more used Walk Graphics stored in WALK.LIB
- for (int idx = 0; idx < NUM_IN_WALK_LIB; ++idx) {
- if (!scumm_stricmp(filename.c_str(), WALK_LIB_NAMES[idx])) {
- people._useWalkLib = true;
- break;
- }
- }
-
- _altImages = new ImageFile(filename);
- people._useWalkLib = false;
-
- _altSeq = _sequenceNumber + 1;
- }
- }
- }
+ if (wait) {
+ seqCc = idx;
+ while (_sequences[idx] != 0)
+ ++idx;
- // If this is a different seqeunce from the current sequence, reset the appropriate variables
- if (_sequences != &_walkSequences[_sequenceNumber]._sequences[0]) {
- _seqTo = _seqCounter = _seqCounter2 = _seqStack = _startSeq = 0;
- _sequences = &_walkSequences[_sequenceNumber]._sequences[0];
- _seqSize = _walkSequences[_sequenceNumber]._sequences.size();
+ idx = idx - seqCc + 2;
+ for (; idx > 0; --idx)
+ scene.doBgAnim();
}
-
- setImageFrame();
}
-void Sprite::freeAltGraphics() {
- if (_altImages != nullptr) {
- delete _altImages;
- _altImages = nullptr;
- }
-
- _altSeq = 0;
-}
+int BaseObject::checkNameForCodes(const Common::String &name, const char *const messages[]) {
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ UserInterface &ui = *_vm->_ui;
+ bool printed = false;
-/*----------------------------------------------------------------*/
+ scene.toggleObject(name);
-void WalkSequence::load(Common::SeekableReadStream &s) {
- char buffer[9];
- s.read(buffer, 9);
- _vgsName = Common::String(buffer);
- _horizFlip = s.readByte() != 0;
+ if (name.hasPrefix("*")) {
+ // A code was found
+ printed = true;
+ char ch = (name == "*") ? 0 : toupper(name[1]);
- _sequences.resize(s.readUint16LE());
- s.skip(4); // Skip over pointer field of structure
+ switch (ch) {
+ case 'C':
+ talk.talkTo(name.c_str() + 2);
+ break;
- s.read(&_sequences[0], _sequences.size());
-}
+ case 'T':
+ case 'B':
+ case 'F':
+ case 'W':
+ // Nothing: action was already done before canimation
+ break;
-/*----------------------------------------------------------------*/
+ case 'G':
+ case 'A': {
+ // 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);
-WalkSequences &WalkSequences::operator=(const WalkSequences &src) {
- resize(src.size());
- for (uint idx = 0; idx < size(); ++idx) {
- const WalkSequence &wSrc = src[idx];
- WalkSequence &wDest = (*this)[idx];
- wDest._horizFlip = wSrc._horizFlip;
+ if (ch == 'G')
+ _position = Common::Point(atoi(sx.c_str()), atoi(sy.c_str()));
+ else
+ _position += Common::Point(atoi(sx.c_str()), atoi(sy.c_str()));
+ break;
+ }
- wDest._sequences.resize(wSrc._sequences.size());
- Common::copy(&wSrc._sequences[0], &wSrc._sequences[0] + wSrc._sequences.size(), &wDest._sequences[0]);
- }
+ default:
+ if (ch >= '0' && ch <= '9') {
+ scene._goToScene = atoi(name.c_str() + 1);
- return *this;
-}
+ if (IS_SERRATED_SCALPEL && scene._goToScene < 97) {
+ Scalpel::ScalpelMap &map = *(Scalpel::ScalpelMap *)_vm->_map;
+ if (map[scene._goToScene].x) {
+ map._overPos.x = (map[scene._goToScene].x - 6) * FIXED_INT_MULTIPLIER;
+ map._overPos.y = (map[scene._goToScene].y + 9) * FIXED_INT_MULTIPLIER;
+ }
+ }
-/*----------------------------------------------------------------*/
+ const char *p;
+ if ((p = strchr(name.c_str(), ',')) != nullptr) {
+ ++p;
-ActionType::ActionType() {
- _cAnimNum = _cAnimSpeed = 0;
-}
+ Common::String s(p, p + 3);
+ people._hSavedPos.x = atoi(s.c_str());
-void ActionType::load(Common::SeekableReadStream &s) {
- char buffer[12];
+ s = Common::String(p + 3, p + 6);
+ people._hSavedPos.y = atoi(s.c_str());
- _cAnimNum = s.readByte();
- _cAnimSpeed = s.readByte();
- if (_cAnimSpeed & 0x80)
- _cAnimSpeed = -(_cAnimSpeed & 0x7f);
+ s = Common::String(p + 6, p + 9);
+ people._hSavedFacing = atoi(s.c_str());
+ if (people._hSavedFacing == 0)
+ people._hSavedFacing = 10;
+ } else if ((p = strchr(name.c_str(), '/')) != nullptr) {
+ people._hSavedPos = Common::Point(1, 0);
+ people._hSavedFacing = 100 + atoi(p + 1);
+ }
+ } else {
+ scene._goToScene = 100;
+ }
- for (int idx = 0; idx < NAMES_COUNT; ++idx) {
- s.read(buffer, 12);
- _names[idx] = Common::String(buffer);
+ people[HOLMES]._position = Point32(0, 0);
+ break;
+ }
+ } else if (name.hasPrefix("!")) {
+ // Message attached to canimation
+ int messageNum = atoi(name.c_str() + 1);
+ ui._infoFlag = true;
+ ui.clearInfo();
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", messages[messageNum]);
+ ui._menuCounter = 25;
+ } else if (name.hasPrefix("@")) {
+ // Message attached to canimation
+ ui._infoFlag = true;
+ ui.clearInfo();
+ screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", name.c_str() + 1);
+ printed = true;
+ ui._menuCounter = 25;
}
+
+ return printed;
}
/*----------------------------------------------------------------*/
-UseType::UseType(): ActionType() {
- _useFlag = 0;
+void Sprite::clear() {
+ _name = "";
+ _description = "";
+ _examine.clear();
+ _pickUp = "";
+ _walkSequences.clear();
+ _sequences = nullptr;
+ _images = nullptr;
+ _imageFrame = nullptr;
+ _walkCount = 0;
+ _allow = 0;
+ _frameNumber = _sequenceNumber = 0;
+ _position.x = _position.y = 0;
+ _delta.x = _delta.y = 0;
+ _oldPosition.x = _oldPosition.y = 0;
+ _oldSize.x = _oldSize.y = 0;
+ _goto.x = _goto.y = 0;
+ _type = INVALID;
+ _pickUp.clear();
+ _noShapeSize.x = _noShapeSize.y = 0;
+ _status = 0;
+ _misc = 0;
+ _altImages = nullptr;
+ _altSeq = 0;
+ Common::fill(&_stopFrames[0], &_stopFrames[8], (ImageFrame *)nullptr);
}
-void UseType::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
- char buffer[12];
+void Sprite::setImageFrame() {
+ int frameNum = MAX(_frameNumber, 0);
+ int imageNumber = _walkSequences[_sequenceNumber][frameNum];
+
+ if (IS_SERRATED_SCALPEL)
+ imageNumber = imageNumber + _walkSequences[_sequenceNumber][0] - 2;
+ else if (imageNumber > _maxFrames)
+ imageNumber = 1;
- if (isRoseTattoo) {
- s.read(buffer, 12);
- _verb = Common::String(buffer);
- }
+ // Get the images to use
+ ImageFile *images = _altSeq ? _altImages : _images;
+ assert(images);
- ActionType::load(s);
+ if (_vm->getPlatform() == Common::kPlatform3DO) {
+ // only do this to the image-array with 110 entries
+ // map uses another image-array and this code
+ if (images->size() == 110) {
+ // 3DO has 110 animation frames inside walk.anim
+ // PC has 55
+ // this adjusts the framenumber accordingly
+ // sort of HACK
+ imageNumber *= 2;
+ }
+ } else if (IS_ROSE_TATTOO) {
+ --imageNumber;
+ }
- _useFlag = s.readSint16LE();
+ // Set the frame pointer
+ _imageFrame = &(*images)[imageNumber];
+}
- if (!isRoseTattoo)
- s.skip(6);
+void Sprite::checkSprite() {
+ Events &events = *_vm->_events;
+ People &people = *_vm->_people;
+ Scene &scene = *_vm->_scene;
+ Screen &screen = *_vm->_screen;
+ Talk &talk = *_vm->_talk;
+ Point32 pt;
+ Common::Rect objBounds;
+ Common::Point spritePt(_position.x / FIXED_INT_MULTIPLIER, _position.y / FIXED_INT_MULTIPLIER);
- s.read(buffer, 12);
- _target = Common::String(buffer);
-}
+ if (_type != CHARACTER || (IS_SERRATED_SCALPEL && talk._talkCounter))
+ return;
-void UseType::load3DO(Common::SeekableReadStream &s) {
- char buffer[12];
+ pt = _walkCount ? _position + _delta : _position;
+ pt.x /= FIXED_INT_MULTIPLIER;
+ pt.y /= FIXED_INT_MULTIPLIER;
- _cAnimNum = s.readByte();
- _cAnimSpeed = s.readByte();
- if (_cAnimSpeed & 0x80)
- _cAnimSpeed = -(_cAnimSpeed & 0x7f);
+ if (IS_ROSE_TATTOO) {
+ // TODO: Needs to be called
+ //checkObject(1001);
- for (int idx = 0; idx < NAMES_COUNT; ++idx) {
- s.read(buffer, 12);
- _names[idx] = Common::String(buffer);
+ // For Rose Tattoo, we only do the further processing for Sherlock
+ if (this != &people[HOLMES])
+ return;
}
- _useFlag = s.readSint16BE();
-
- s.skip(6);
+ for (uint idx = 0; idx < scene._bgShapes.size() && !talk._talkToAbort; ++idx) {
+ Object &obj = scene._bgShapes[idx];
+ if (obj._aType <= PERSON || obj._type == INVALID || obj._type == HIDDEN)
+ continue;
- s.read(buffer, 12);
- _target = Common::String(buffer);
-}
+ if (obj._type == NO_SHAPE) {
+ objBounds = Common::Rect(obj._position.x, obj._position.y,
+ obj._position.x + obj._noShapeSize.x + 1, obj._position.y + obj._noShapeSize.y + 1);
+ } else {
+ int xp = obj._position.x + obj._imageFrame->_offset.x;
+ int yp = obj._position.y + obj._imageFrame->_offset.y;
+ objBounds = Common::Rect(xp, yp,
+ xp + obj._imageFrame->_frame.w + 1, yp + obj._imageFrame->_frame.h + 1);
+ }
-/*----------------------------------------------------------------*/
+ if (objBounds.contains(pt)) {
+ if (objBounds.contains(spritePt)) {
+ // Current point is already inside the the bounds, so impact occurred
+ // on a previous call. So simply do nothing until we're clear of the box
+ switch (obj._aType) {
+ case TALK_MOVE:
+ if (_walkCount) {
+ // Holmes is moving
+ obj._type = HIDDEN;
+ obj.setFlagsAndToggles();
+ talk.talkTo(obj._use[0]._target);
+ }
+ break;
-SherlockEngine *Object::_vm;
-bool Object::_countCAnimFrames;
+ case PAL_CHANGE:
+ case PAL_CHANGE2:
+ if (_walkCount) {
+ int palStart = atoi(obj._use[0]._names[0].c_str()) * 3;
+ int palLength = atoi(obj._use[0]._names[1].c_str()) * 3;
+ int templ = atoi(obj._use[0]._names[2].c_str()) * 3;
+ if (templ == 0)
+ templ = 100;
-void Object::setVm(SherlockEngine *vm) {
- _vm = vm;
- _countCAnimFrames = false;
-}
+ // Ensure only valid palette change data found
+ if (palLength > 0) {
+ // Figure out how far into the shape Holmes is so that we
+ // can figure out what percentage of the original palette
+ // to set the current palette to
+ int palPercent = (pt.x - objBounds.left) * 100 / objBounds.width();
+ palPercent = palPercent * templ / 100;
+ if (obj._aType == PAL_CHANGE)
+ // Invert percentage
+ palPercent = 100 - palPercent;
-Object::Object(): BaseObject() {
- _sequenceNumber = 0;
- _sequenceOffset = 0;
- _pickup = 0;
- _defaultCommand = 0;
- _pickupFlag = 0;
-}
+ for (int i = palStart; i < (palStart + palLength); ++i)
+ screen._sMap[i] = screen._cMap[i] * palPercent / 100;
-void Object::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
- char buffer[41];
- s.read(buffer, 12);
- _name = Common::String(buffer);
- s.read(buffer, 41);
- _description = Common::String(buffer);
+ events.pollEvents();
+ screen.setPalette(screen._sMap);
+ }
+ }
+ break;
- _examine.clear();
- _sequences = nullptr;
- _images = nullptr;
- _imageFrame = nullptr;
+ case TALK:
+ case TALK_EVERY:
+ obj._type = HIDDEN;
+ obj.setFlagsAndToggles();
+ talk.talkTo(obj._use[0]._target);
+ break;
- s.skip(4);
- _sequenceOffset = s.readUint16LE();
- s.seek(10, SEEK_CUR);
+ default:
+ break;
+ }
+ } else {
+ // New impact just occurred
+ switch (obj._aType) {
+ case BLANK_ZONE:
+ // A blank zone masks out all other remaining zones underneath it.
+ // If this zone is hit, exit the outer loop so we do not check anymore
+ return;
- _walkCount = s.readByte();
- _allow = s.readByte();
- _frameNumber = s.readSint16LE();
- _sequenceNumber = s.readSint16LE();
- _position.x = s.readSint16LE();
- _position.y = s.readSint16LE();
- _delta.x = s.readSint16LE();
- _delta.y = s.readSint16LE();
- _type = (SpriteType)s.readUint16LE();
- _oldPosition.x = s.readSint16LE();
- _oldPosition.y = s.readSint16LE();
- _oldSize.x = s.readUint16LE();
- _oldSize.y = s.readUint16LE();
-
- _goto.x = s.readSint16LE();
- _goto.y = s.readSint16LE();
- if (!isRoseTattoo) {
- _goto.x = _goto.x * FIXED_INT_MULTIPLIER / 100;
- _goto.y = _goto.y * FIXED_INT_MULTIPLIER / 100;
- }
+ case SOLID:
+ case TALK:
+ // Stop walking
+ if (obj._aType == TALK) {
+ obj.setFlagsAndToggles();
+ talk.talkTo(obj._use[0]._target);
+ } else {
+ gotoStand();
+ }
+ break;
- _pickup = isRoseTattoo ? 0 : s.readByte();
- _defaultCommand = isRoseTattoo ? 0 : s.readByte();
- _lookFlag = s.readSint16LE();
- _pickupFlag = isRoseTattoo ? 0 : s.readSint16LE();
- _requiredFlag = s.readSint16LE();
- _noShapeSize.x = s.readUint16LE();
- _noShapeSize.y = s.readUint16LE();
- _status = s.readUint16LE();
- _misc = s.readByte();
- _maxFrames = s.readUint16LE();
- _flags = s.readByte();
+ case TALK_EVERY:
+ if (obj._aType == TALK_EVERY) {
+ obj._type = HIDDEN;
+ obj.setFlagsAndToggles();
+ talk.talkTo(obj._use[0]._target);
+ } else {
+ gotoStand();
+ }
+ break;
- if (!isRoseTattoo)
- _aOpen.load(s);
+ case FLAG_SET:
+ obj.setFlagsAndToggles();
+ obj._type = HIDDEN;
+ break;
- _aType = (AType)s.readByte();
- _lookFrames = s.readByte();
- _seqCounter = s.readByte();
- _lookPosition.x = s.readUint16LE() * FIXED_INT_MULTIPLIER / 100;
- _lookPosition.y = (isRoseTattoo ? s.readSint16LE() : s.readByte()) * FIXED_INT_MULTIPLIER;
- _lookFacing = s.readByte();
- _lookcAnim = s.readByte();
+ case WALK_AROUND:
+ if (objBounds.contains(people[HOLMES]._walkTo.front())) {
+ // Reached zone
+ gotoStand();
+ } else {
+ // Destination not within box, walk to best corner
+ Common::Point walkPos;
- if (!isRoseTattoo)
- _aClose.load(s);
+ if (spritePt.x >= objBounds.left && spritePt.x < objBounds.right) {
+ // Impact occurred due to vertical movement. Determine whether to
+ // travel to the left or right side
+ if (_delta.x > 0)
+ // Go to right side
+ walkPos.x = objBounds.right + CLEAR_DIST_X;
+ else if (_delta.x < 0) {
+ // Go to left side
+ walkPos.x = objBounds.left - CLEAR_DIST_X;
+ } else {
+ // Going straight up or down. So choose best side
+ if (spritePt.x >= (objBounds.left + objBounds.width() / 2))
+ walkPos.x = objBounds.right + CLEAR_DIST_X;
+ else
+ walkPos.x = objBounds.left - CLEAR_DIST_X;
+ }
- _seqStack = s.readByte();
- _seqTo = s.readByte();
- _descOffset = s.readUint16LE();
- _seqCounter2 = s.readByte();
- _seqSize = s.readUint16LE();
+ walkPos.y = (_delta.y >= 0) ? objBounds.top - CLEAR_DIST_Y :
+ objBounds.bottom + CLEAR_DIST_Y;
+ } else {
+ // Impact occurred due to horizontal movement
+ if (_delta.y > 0)
+ // Go to bottom of box
+ walkPos.y = objBounds.bottom + CLEAR_DIST_Y;
+ else if (_delta.y < 0)
+ // Go to top of box
+ walkPos.y = objBounds.top - CLEAR_DIST_Y;
+ else {
+ // Going straight horizontal, so choose best side
+ if (spritePt.y >= (objBounds.top + objBounds.height() / 2))
+ walkPos.y = objBounds.bottom + CLEAR_DIST_Y;
+ else
+ walkPos.y = objBounds.top - CLEAR_DIST_Y;
+ }
- if (isRoseTattoo) {
- for (int idx = 0; idx < 6; ++idx)
- _use[idx].load(s, true);
+ walkPos.x = (_delta.x >= 0) ? objBounds.left - CLEAR_DIST_X :
+ objBounds.right + CLEAR_DIST_X;
+ }
- _quickDraw = s.readByte();
- _scaleVal = s.readUint16LE();
- _requiredFlags1 = s.readSint16LE();
- _gotoSeq = s.readByte();
- _talkSeq = s.readByte();
- _restoreSlot = s.readByte();
- } else {
- s.skip(1);
- _aMove.load(s);
- s.skip(8);
+ walkPos.x += people[HOLMES]._imageFrame->_frame.w / 2;
+ people._walkDest = walkPos;
+ people[HOLMES]._walkTo.push(walkPos);
+ people[HOLMES].setWalking();
+ }
+ break;
- for (int idx = 0; idx < 4; ++idx)
- _use[idx].load(s, false);
+ case DELTA:
+ _position.x += 200;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
}
- //warning("object %s, useAnim %d", _name.c_str(), _use[0]._cAnimNum);
}
-void Object::load3DO(Common::SeekableReadStream &s) {
- int32 streamStartPos = s.pos();
- char buffer[41];
+const Common::Rect Sprite::getOldBounds() const {
+ return Common::Rect(_oldPosition.x, _oldPosition.y, _oldPosition.x + _oldSize.x, _oldPosition.y + _oldSize.y);
+}
- _examine.clear();
- _sequences = nullptr;
- _images = nullptr;
- _imageFrame = nullptr;
+void Sprite::setObjTalkSequence(int seq) {
+ assert(seq != -1 && _type == CHARACTER);
- // on 3DO all of this data is reordered!!!
- // it seems that possibly the 3DO compiler reordered the global struct
- // 3DO size for 1 object is 588 bytes
- s.skip(4);
- _sequenceOffset = s.readUint16LE(); // weird that this seems to be LE
- s.seek(10, SEEK_CUR);
+ if (_seqTo) {
+ // reset to previous value
+ _walkSequences[_sequenceNumber]._sequences[_frameNumber] = _seqTo;
+ _seqTo = 0;
+ }
+
+ _sequenceNumber = _gotoSeq;
+ _frameNumber = 0;
+ checkWalkGraphics();
+}
+
+void Sprite::checkWalkGraphics() {
+ People &people = *_vm->_people;
+
+ if (_images == nullptr) {
+ freeAltGraphics();
+ return;
+ }
+
+ Common::String filename = Common::String::format("%s.vgs", _walkSequences[_sequenceNumber]._vgsName.c_str());
+
+ // Set the adjust depending on if we have to fine tune the x position of this particular graphic
+ _adjust.x = _adjust.y = 0;
+
+ for (int idx = 0; idx < NUM_ADJUSTED_WALKS; ++idx) {
+ if (!scumm_strnicmp(_walkSequences[_sequenceNumber]._vgsName.c_str(), ADJUST_WALKS[idx]._vgsName,
+ strlen(ADJUST_WALKS[idx]._vgsName))) {
+ if (_walkSequences[_sequenceNumber]._horizFlip)
+ _adjust.x = ADJUST_WALKS[idx]._flipXAdjust;
+ else
+ _adjust.x = ADJUST_WALKS[idx]._xAdjust;
+
+ _adjust.y = ADJUST_WALKS[idx]._yAdjust;
+ break;
+ }
+ }
+
+ // See if we're already using Alternate Graphics
+ if (_altSeq) {
+ // See if the VGS file called for is different than the alternate graphics already loaded
+ if (!_walkSequences[_sequenceNumber]._vgsName.compareToIgnoreCase(_walkSequences[_altSeq - 1]._vgsName)) {
+ // Different AltGraphics, Free the old ones
+ freeAltGraphics();
+ }
+ }
+
+ // If there is no Alternate Sequence set, see if we need to load a new one
+ if (!_altSeq) {
+ int npcNum = -1;
+ // Find which NPC this is so we can check the name of the graphics loaded
+ for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
+ if (this == &people[idx]) {
+ npcNum = idx;
+ break;
+ }
+ }
- // Offset 16
- _frameNumber = s.readSint16BE();
- _sequenceNumber = s.readSint16BE();
- _position.x = s.readSint16BE();
- _position.y = s.readSint16BE();
- _delta.x = s.readSint16BE();
- _delta.y = s.readSint16BE();
- _type = (SpriteType)s.readUint16BE();
- _oldPosition.x = s.readSint16BE();
- _oldPosition.y = s.readSint16BE();
- _oldSize.x = s.readUint16BE();
- _oldSize.y = s.readUint16BE();
-
- _goto.x = s.readSint16BE();
- _goto.y = s.readSint16BE();
- _goto.x = _goto.x * FIXED_INT_MULTIPLIER / 100;
- _goto.y = _goto.y * FIXED_INT_MULTIPLIER / 100;
+ if (npcNum != -1) {
+ // See if the VGS file called for is different than the main graphics which are already loaded
+ if (!filename.compareToIgnoreCase(people[npcNum]._walkVGSName)) {
+ // See if this is one of the more used Walk Graphics stored in WALK.LIB
+ for (int idx = 0; idx < NUM_IN_WALK_LIB; ++idx) {
+ if (!scumm_stricmp(filename.c_str(), WALK_LIB_NAMES[idx])) {
+ people._useWalkLib = true;
+ break;
+ }
+ }
- // Offset 42
- warning("pos %d", s.pos());
+ _altImages = new ImageFile(filename);
+ people._useWalkLib = false;
- // Unverified
- _lookFlag = s.readSint16BE();
- _pickupFlag = s.readSint16BE();
- _requiredFlag = s.readSint16BE();
- _noShapeSize.x = s.readUint16BE();
- _noShapeSize.y = s.readUint16BE();
- _status = s.readUint16BE();
- // Unverified END
+ _altSeq = _sequenceNumber + 1;
+ }
+ }
+ }
- _maxFrames = s.readUint16BE();
- // offset 56
- _lookPosition.x = s.readUint16BE() * FIXED_INT_MULTIPLIER / 100;
- // offset 58
- _descOffset = s.readUint16BE();
- _seqSize = s.readUint16BE();
+ // If this is a different seqeunce from the current sequence, reset the appropriate variables
+ if (_sequences != &_walkSequences[_sequenceNumber]._sequences[0]) {
+ _seqTo = _seqCounter = _seqCounter2 = _seqStack = _startSeq = 0;
+ _sequences = &_walkSequences[_sequenceNumber]._sequences[0];
+ _seqSize = _walkSequences[_sequenceNumber]._sequences.size();
+ }
- s.skip(2); // boundary filler
+ setImageFrame();
+}
- // 288 bytes
- for (int idx = 0; idx < 4; ++idx) {
- _use[idx].load3DO(s);
- s.skip(2); // Filler
+void Sprite::freeAltGraphics() {
+ if (_altImages != nullptr) {
+ delete _altImages;
+ _altImages = nullptr;
}
- // 158 bytes
- _aOpen.load(s); // 2 + 12*4 bytes = 50 bytes
- s.skip(2); // Boundary filler
- _aClose.load(s);
- s.skip(2); // Filler
- _aMove.load(s);
- s.skip(2); // Filler
+ _altSeq = 0;
+}
- // offset 508
- // 3DO: name is at the end
- s.read(buffer, 12);
- _name = Common::String(buffer);
- s.read(buffer, 41);
- _description = Common::String(buffer);
+/*----------------------------------------------------------------*/
- // Unverified
- _walkCount = s.readByte();
- _allow = s.readByte();
- _pickup = s.readByte();
- _defaultCommand = s.readByte();
- // Unverified END
+void WalkSequence::load(Common::SeekableReadStream &s) {
+ char buffer[9];
+ s.read(buffer, 9);
+ _vgsName = Common::String(buffer);
+ _horizFlip = s.readByte() != 0;
- // Probably those here?!?!
- _misc = s.readByte();
- _flags = s.readByte();
+ _sequences.resize(s.readUint16LE());
+ s.skip(4); // Skip over pointer field of structure
- // Unverified
- _aType = (AType)s.readByte();
- _lookFrames = s.readByte();
- _seqCounter = s.readByte();
- // Unverified END
+ s.read(&_sequences[0], _sequences.size());
+}
- _lookPosition.y = s.readByte() * FIXED_INT_MULTIPLIER;
- _lookFacing = s.readByte();
+/*----------------------------------------------------------------*/
- // Unverified
- _lookcAnim = s.readByte();
- _seqStack = s.readByte();
- _seqTo = s.readByte();
- _seqCounter2 = s.readByte();
- // Unverified END
+WalkSequences &WalkSequences::operator=(const WalkSequences &src) {
+ resize(src.size());
+ for (uint idx = 0; idx < size(); ++idx) {
+ const WalkSequence &wSrc = src[idx];
+ WalkSequence &wDest = (*this)[idx];
+ wDest._horizFlip = wSrc._horizFlip;
- s.skip(12); // Unknown
+ wDest._sequences.resize(wSrc._sequences.size());
+ Common::copy(&wSrc._sequences[0], &wSrc._sequences[0] + wSrc._sequences.size(), &wDest._sequences[0]);
+ }
- //warning("object %s, offset %d", _name.c_str(), streamPos);
- //warning("object %s, lookPosX %d, lookPosY %d", _name.c_str(), _lookPosition.x, _lookPosition.y);
- //warning("object %s, defCmd %d", _name.c_str(), _defaultCommand);
- int32 dataSize = s.pos() - streamStartPos;
- assert(dataSize == 588);
+ return *this;
}
-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;
+ActionType::ActionType() {
+ _cAnimNum = _cAnimSpeed = 0;
+}
- _seqCounter = _seqCounter2 = 0;
- _seqStack = 0;
- _frameNumber = -1;
+void ActionType::load(Common::SeekableReadStream &s) {
+ char buffer[12];
- 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;
+ _cAnimNum = s.readByte();
+ _cAnimSpeed = s.readByte();
+ if (_cAnimSpeed & 0x80)
+ _cAnimSpeed = -(_cAnimSpeed & 0x7f);
- _imageFrame = &(*_images)[idx];
- }
+ for (int idx = 0; idx < NAMES_COUNT; ++idx) {
+ s.read(buffer, 12);
+ _names[idx] = Common::String(buffer);
}
}
-void Object::checkObject() {
- Scene &scene = *_vm->_scene;
- Sound &sound = *_vm->_sound;
- Talk &talk = *_vm->_talk;
- int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
- bool codeFound;
+/*----------------------------------------------------------------*/
- if (_seqTo) {
- byte *ptr = &_sequences[_frameNumber];
- if (*ptr == _seqTo) {
- // The sequence is completed
- *ptr = _seqTo + SEQ_TO_CODE + 128; // Reset to normal
- _seqTo = 0;
- } else {
- // Continue doing sequence
- if (*ptr > _seqTo)
- *ptr -= 1;
- else
- *ptr += 1;
+UseType::UseType(): ActionType() {
+ _useFlag = 0;
+}
- return;
- }
+void UseType::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
+ char buffer[12];
+
+ if (isRoseTattoo) {
+ s.read(buffer, 12);
+ _verb = Common::String(buffer);
}
- ++_frameNumber;
+ ActionType::load(s);
- do {
- // Check for end of sequence
- codeFound = checkEndOfSequence();
+ _useFlag = s.readSint16LE();
- if (_sequences[_frameNumber] >= 128 && _frameNumber < checkFrame) {
- codeFound = true;
- int v = _sequences[_frameNumber];
+ if (!isRoseTattoo)
+ s.skip(6);
- // Check for a Talk or Listen Sequence
- if (IS_ROSE_TATTOO && v == ALLOW_TALK_CODE) {
- if (_gotoSeq) {
- setObjTalkSequence(_gotoSeq);
- } else {
- ++_frameNumber;
- }
- } else if (IS_ROSE_TATTOO && (v == TALK_SEQ_CODE || v == TALK_LISTEN_CODE)) {
- if (_talkSeq)
- setObjTalkSequence(_talkSeq);
- else
- setObjSequence(0, false);
- } else if (v >= GOTO_CODE) {
- // Goto code found
- v -= GOTO_CODE;
- _seqCounter2 = _seqCounter;
- _seqStack = _frameNumber + 1;
- setObjSequence(v, false);
- } else if (v >= SOUND_CODE && (v < (SOUND_CODE + 30))) {
- codeFound = true;
- ++_frameNumber;
- v -= SOUND_CODE + (IS_SERRATED_SCALPEL ? 1 : 0);
+ s.read(buffer, 12);
+ _target = Common::String(buffer);
+}
- if (sound._soundOn && !_countCAnimFrames) {
- if (!scene._sounds[v]._name.empty() && sound._digitized)
- sound.playLoadedSound(v, WAIT_RETURN_IMMEDIATELY);
- }
- } else if (v >= FLIP_CODE && v < (FLIP_CODE + 3)) {
- // Flip code
- codeFound = true;
- ++_frameNumber;
- v -= FLIP_CODE;
+void UseType::load3DO(Common::SeekableReadStream &s) {
+ char buffer[12];
+
+ _cAnimNum = s.readByte();
+ _cAnimSpeed = s.readByte();
+ if (_cAnimSpeed & 0x80)
+ _cAnimSpeed = -(_cAnimSpeed & 0x7f);
+
+ for (int idx = 0; idx < NAMES_COUNT; ++idx) {
+ s.read(buffer, 12);
+ _names[idx] = Common::String(buffer);
+ }
- // Alter the flipped status
- switch (v) {
- case 0:
- // Clear the flag
- _flags &= ~OBJ_FLIPPED;
- break;
- case 1:
- // Set the flag
- _flags |= OBJ_FLIPPED;
- break;
- case 2:
- // Toggle the flag
- _flags ^= OBJ_FLIPPED;
- break;
- default:
- break;
- }
- } else if (IS_ROSE_TATTOO && v == TELEPORT_CODE) {
- _position.x = READ_LE_UINT16(&_sequences[_frameNumber + 1]);
- _position.y = READ_LE_UINT16(&_sequences[_frameNumber + 3]);
+ _useFlag = s.readSint16BE();
- _frameNumber += 5;
- } else if (IS_ROSE_TATTOO && v == CALL_TALK_CODE) {
- Common::String filename;
- for (int idx = 0; idx < 8; ++idx) {
- if (_sequences[_frameNumber + 1 + idx] != 1)
- filename += (char)_sequences[_frameNumber + 1 + idx];
- else
- break;
- }
+ s.skip(6);
- _frameNumber += 8;
- talk.talkTo(filename);
+ s.read(buffer, 12);
+ _target = Common::String(buffer);
+}
- } else if (IS_ROSE_TATTOO && v == HIDE_CODE) {
- switch (_sequences[_frameNumber + 2]) {
- case 1:
- // Hide Object
- if (scene._bgShapes[_sequences[_frameNumber + 1] - 1]._type != HIDDEN)
- scene._bgShapes[_sequences[_frameNumber + 1] - 1].toggleHidden();
- break;
+/*----------------------------------------------------------------*/
- case 2:
- // Activate Object
- if (scene._bgShapes[_sequences[_frameNumber + 1] - 1]._type == HIDDEN)
- scene._bgShapes[_sequences[_frameNumber + 1] - 1].toggleHidden();
- break;
+bool Object::_countCAnimFrames;
- case 3:
- // Toggle Object
- scene._bgShapes[_sequences[_frameNumber + 1] - 1].toggleHidden();
- break;
+Object::Object(): BaseObject() {
+ _sequenceNumber = 0;
+ _sequenceOffset = 0;
+ _pickup = 0;
+ _defaultCommand = 0;
+ _pickupFlag = 0;
+}
- default:
- break;
- }
- _frameNumber += 3;
-
- } else {
- v -= 128;
+void Object::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
+ char buffer[41];
+ s.read(buffer, 12);
+ _name = Common::String(buffer);
+ s.read(buffer, 41);
+ _description = Common::String(buffer);
- // 68-99 is a squence code
- if (v > SEQ_TO_CODE) {
- byte *p = &_sequences[_frameNumber];
- v -= SEQ_TO_CODE; // # from 1-32
- _seqTo = v;
- *p = *(p - 1);
+ _examine.clear();
+ _sequences = nullptr;
+ _images = nullptr;
+ _imageFrame = nullptr;
- if (*p > 128)
- // If the high bit is set, convert to a real frame
- *p -= (byte)(SEQ_TO_CODE - 128);
+ s.skip(4);
+ _sequenceOffset = s.readUint16LE();
+ s.seek(10, SEEK_CUR);
- if (*p > _seqTo)
- *p -= 1;
- else
- *p += 1;
+ _walkCount = s.readByte();
+ _allow = s.readByte();
+ _frameNumber = s.readSint16LE();
+ _sequenceNumber = s.readSint16LE();
+ _position.x = s.readSint16LE();
+ _position.y = s.readSint16LE();
+ _delta.x = s.readSint16LE();
+ _delta.y = s.readSint16LE();
+ _type = (SpriteType)s.readUint16LE();
+ _oldPosition.x = s.readSint16LE();
+ _oldPosition.y = s.readSint16LE();
+ _oldSize.x = s.readUint16LE();
+ _oldSize.y = s.readUint16LE();
+
+ _goto.x = s.readSint16LE();
+ _goto.y = s.readSint16LE();
+ if (!isRoseTattoo) {
+ _goto.x = _goto.x * FIXED_INT_MULTIPLIER / 100;
+ _goto.y = _goto.y * FIXED_INT_MULTIPLIER / 100;
+ }
- // Will be incremented below to return back to original value
- --_frameNumber;
- v = 0;
+ _pickup = isRoseTattoo ? 0 : s.readByte();
+ _defaultCommand = isRoseTattoo ? 0 : s.readByte();
+ _lookFlag = s.readSint16LE();
+ _pickupFlag = isRoseTattoo ? 0 : s.readSint16LE();
+ _requiredFlag = s.readSint16LE();
+ _noShapeSize.x = s.readUint16LE();
+ _noShapeSize.y = s.readUint16LE();
+ _status = s.readUint16LE();
+ _misc = s.readByte();
+ _maxFrames = s.readUint16LE();
+ _flags = s.readByte();
- } else if (IS_ROSE_TATTOO && v == 10) {
- // Set delta for objects
- _delta = Common::Point(READ_LE_UINT16(&_sequences[_frameNumber + 1]),
- READ_LE_UINT16(&_sequences[_frameNumber + 3]));
- _noShapeSize = Common::Point(0, 0);
- _frameNumber += 4;
+ if (!isRoseTattoo)
+ _aOpen.load(s);
- } else if (v == 10) {
- // Set delta for objects
- Common::Point pt(_sequences[_frameNumber + 1], _sequences[_frameNumber + 2]);
- if (pt.x > 128)
- pt.x = (pt.x - 128) * -1;
- else
- pt.x--;
+ _aType = (AType)s.readByte();
+ _lookFrames = s.readByte();
+ _seqCounter = s.readByte();
+ _lookPosition.x = s.readUint16LE() * FIXED_INT_MULTIPLIER / 100;
+ _lookPosition.y = (isRoseTattoo ? s.readSint16LE() : s.readByte()) * FIXED_INT_MULTIPLIER;
+ _lookFacing = s.readByte();
+ _lookcAnim = s.readByte();
- if (pt.y > 128)
- pt.y = (pt.y - 128) * -1;
- else
- pt.y--;
+ if (!isRoseTattoo)
+ _aClose.load(s);
- _delta = pt;
- _frameNumber += 2;
+ _seqStack = s.readByte();
+ _seqTo = s.readByte();
+ _descOffset = s.readUint16LE();
+ _seqCounter2 = s.readByte();
+ _seqSize = s.readUint16LE();
- } else if (v < USE_COUNT) {
- for (int idx = 0; idx < NAMES_COUNT; ++idx) {
- checkNameForCodes(_use[v]._names[idx], nullptr);
- }
+ if (isRoseTattoo) {
+ for (int idx = 0; idx < 6; ++idx)
+ _use[idx].load(s, true);
- if (_use[v]._useFlag)
- _vm->setFlags(_use[v]._useFlag);
- }
+ _quickDraw = s.readByte();
+ _scaleVal = s.readUint16LE();
+ _requiredFlags1 = s.readSint16LE();
+ _gotoSeq = s.readByte();
+ _talkSeq = s.readByte();
+ _restoreSlot = s.readByte();
+ } else {
+ s.skip(1);
+ _aMove.load(s);
+ s.skip(8);
- ++_frameNumber;
- }
- }
- } while (codeFound);
+ for (int idx = 0; idx < 4; ++idx)
+ _use[idx].load(s, false);
+ }
+ //warning("object %s, useAnim %d", _name.c_str(), _use[0]._cAnimNum);
}
-bool Object::checkEndOfSequence() {
- Screen &screen = *_vm->_screen;
- int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
- bool result = false;
+void Object::load3DO(Common::SeekableReadStream &s) {
+ int32 streamStartPos = s.pos();
+ char buffer[41];
- if (_type == REMOVE || _type == INVALID)
- return false;
+ _examine.clear();
+ _sequences = nullptr;
+ _images = nullptr;
+ _imageFrame = nullptr;
- if (_sequences[_frameNumber] == 0 || _frameNumber >= checkFrame) {
- result = true;
+ // on 3DO all of this data is reordered!!!
+ // it seems that possibly the 3DO compiler reordered the global struct
+ // 3DO size for 1 object is 588 bytes
+ s.skip(4);
+ _sequenceOffset = s.readUint16LE(); // weird that this seems to be LE
+ s.seek(10, SEEK_CUR);
- if (_frameNumber >= (checkFrame - 1)) {
- _frameNumber = START_FRAME;
- } else {
- // Determine next sequence to use
- int seq = _sequences[_frameNumber + 1];
+ // Offset 16
+ _frameNumber = s.readSint16BE();
+ _sequenceNumber = s.readSint16BE();
+ _position.x = s.readSint16BE();
+ _position.y = s.readSint16BE();
+ _delta.x = s.readSint16BE();
+ _delta.y = s.readSint16BE();
+ _type = (SpriteType)s.readUint16BE();
+ _oldPosition.x = s.readSint16BE();
+ _oldPosition.y = s.readSint16BE();
+ _oldSize.x = s.readUint16BE();
+ _oldSize.y = s.readUint16BE();
+
+ _goto.x = s.readSint16BE();
+ _goto.y = s.readSint16BE();
+ _goto.x = _goto.x * FIXED_INT_MULTIPLIER / 100;
+ _goto.y = _goto.y * FIXED_INT_MULTIPLIER / 100;
- if (seq == 99) {
- --_frameNumber;
- screen._backBuffer1.transBlitFrom(*_imageFrame, _position);
- screen._backBuffer2.transBlitFrom(*_imageFrame, _position);
- _type = INVALID;
- } else if (IS_ROSE_TATTOO && _talkSeq && seq == 0) {
- setObjTalkSequence(_talkSeq);
- } else {
- setObjSequence(seq, false);
- }
- }
+ // Offset 42
+ warning("pos %d", s.pos());
+
+ // Unverified
+ _lookFlag = s.readSint16BE();
+ _pickupFlag = s.readSint16BE();
+ _requiredFlag = s.readSint16BE();
+ _noShapeSize.x = s.readUint16BE();
+ _noShapeSize.y = s.readUint16BE();
+ _status = s.readUint16BE();
+ // Unverified END
- if (_allow && _frameNumber == 0) {
- // canimation just ended
- if (_type != NO_SHAPE && _type != REMOVE) {
- _type = REMOVE;
+ _maxFrames = s.readUint16BE();
+ // offset 56
+ _lookPosition.x = s.readUint16BE() * FIXED_INT_MULTIPLIER / 100;
+ // offset 58
+ _descOffset = s.readUint16BE();
+ _seqSize = s.readUint16BE();
- if (!_countCAnimFrames) {
- // Save details before shape is removed
- _delta.x = _imageFrame->_frame.w;
- _delta.y = _imageFrame->_frame.h;
- _position += _imageFrame->_offset;
+ s.skip(2); // boundary filler
- // Free the images
- delete _images;
- _images = nullptr;
- _imageFrame = nullptr;
- }
- } else {
- _type = INVALID;
- }
- }
+ // 288 bytes
+ for (int idx = 0; idx < 4; ++idx) {
+ _use[idx].load3DO(s);
+ s.skip(2); // Filler
}
- return result;
-}
+ // 158 bytes
+ _aOpen.load(s); // 2 + 12*4 bytes = 50 bytes
+ s.skip(2); // Boundary filler
+ _aClose.load(s);
+ s.skip(2); // Filler
+ _aMove.load(s);
+ s.skip(2); // Filler
-void Object::setObjSequence(int seq, bool wait) {
- Scene &scene = *_vm->_scene;
- int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
+ // offset 508
+ // 3DO: name is at the end
+ s.read(buffer, 12);
+ _name = Common::String(buffer);
+ s.read(buffer, 41);
+ _description = Common::String(buffer);
- if (seq >= 128) {
- // Loop the sequence until the count exceeded
- seq -= 128;
+ // Unverified
+ _walkCount = s.readByte();
+ _allow = s.readByte();
+ _pickup = s.readByte();
+ _defaultCommand = s.readByte();
+ // Unverified END
- ++_seqCounter;
- if (_seqCounter >= seq) {
- // Go to next sequence
- if (_seqStack) {
- _frameNumber = _seqStack;
- _seqStack = 0;
- _seqCounter = _seqCounter2;
- _seqCounter2 = 0;
- if (_frameNumber >= checkFrame)
- _frameNumber = START_FRAME;
+ // Probably those here?!?!
+ _misc = s.readByte();
+ _flags = s.readByte();
- return;
- }
+ // Unverified
+ _aType = (AType)s.readByte();
+ _lookFrames = s.readByte();
+ _seqCounter = s.readByte();
+ // Unverified END
- _frameNumber += 2;
- if (_frameNumber >= checkFrame)
- _frameNumber = 0;
+ _lookPosition.y = s.readByte() * FIXED_INT_MULTIPLIER;
+ _lookFacing = s.readByte();
- _seqCounter = 0;
- if (_sequences[_frameNumber] == 0)
- seq = _sequences[_frameNumber + 1];
- else
- return;
- } else {
- // Find beginning of sequence
- do {
- --_frameNumber;
- } while (_frameNumber > 0 && _sequences[_frameNumber] != 0);
+ // Unverified
+ _lookcAnim = s.readByte();
+ _seqStack = s.readByte();
+ _seqTo = s.readByte();
+ _seqCounter2 = s.readByte();
+ // Unverified END
- if (_frameNumber != 0)
- _frameNumber += 2;
+ s.skip(12); // Unknown
- return;
- }
- } else {
- // Reset sequence counter
- _seqCounter = 0;
- }
+ //warning("object %s, offset %d", _name.c_str(), streamPos);
+ //warning("object %s, lookPosX %d, lookPosY %d", _name.c_str(), _lookPosition.x, _lookPosition.y);
+ //warning("object %s, defCmd %d", _name.c_str(), _defaultCommand);
+ int32 dataSize = s.pos() - streamStartPos;
+ assert(dataSize == 588);
+}
- int idx = 0;
- int seqCc = 0;
+void Object::toggleHidden() {
+ if (_type != HIDDEN && _type != HIDE_SHAPE && _type != INVALID) {
+ if (_seqTo != 0)
+ _sequences[_frameNumber] = _seqTo + SEQ_TO_CODE + 128;
+ _seqTo = 0;
- while (seqCc < seq && idx < checkFrame) {
- ++idx;
- if (_sequences[idx] == 0) {
- ++seqCc;
- idx += 2;
- }
- }
+ 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;
- if (idx >= checkFrame)
- idx = 0;
- _frameNumber = idx;
+ _seqCounter = _seqCounter2 = 0;
+ _seqStack = 0;
+ _frameNumber = -1;
- if (wait) {
- seqCc = idx;
- while (_sequences[idx] != 0)
- ++idx;
+ 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;
- idx = idx - seqCc + 2;
- for (; idx > 0; --idx)
- scene.doBgAnim();
+ _imageFrame = &(*_images)[idx];
+ }
}
}
@@ -1244,103 +1340,6 @@ void Object::setObjTalkSequence(int seq) {
}
}
-int Object::checkNameForCodes(const Common::String &name, const char *const messages[]) {
- People &people = *_vm->_people;
- Scene &scene = *_vm->_scene;
- Screen &screen = *_vm->_screen;
- Talk &talk = *_vm->_talk;
- UserInterface &ui = *_vm->_ui;
- bool printed = false;
-
- scene.toggleObject(name);
-
- if (name.hasPrefix("*")) {
- // A code was found
- printed = true;
- char ch = (name == "*") ? 0 : toupper(name[1]);
-
- switch (ch) {
- case 'C':
- talk.talkTo(name.c_str() + 2);
- break;
-
- case 'T':
- case 'B':
- case 'F':
- case 'W':
- // Nothing: action was already done before canimation
- break;
-
- case 'G':
- case 'A': {
- // 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);
-
- if (ch == 'G')
- _position = Common::Point(atoi(sx.c_str()), atoi(sy.c_str()));
- else
- _position += Common::Point(atoi(sx.c_str()), atoi(sy.c_str()));
- break;
- }
-
- default:
- if (ch >= '0' && ch <= '9') {
- scene._goToScene = atoi(name.c_str() + 1);
-
- if (IS_SERRATED_SCALPEL && scene._goToScene < 97) {
- Scalpel::ScalpelMap &map = *(Scalpel::ScalpelMap *)_vm->_map;
- if (map[scene._goToScene].x) {
- map._overPos.x = (map[scene._goToScene].x - 6) * FIXED_INT_MULTIPLIER;
- map._overPos.y = (map[scene._goToScene].y + 9) * FIXED_INT_MULTIPLIER;
- }
- }
-
- const char *p;
- if ((p = strchr(name.c_str(), ',')) != nullptr) {
- ++p;
-
- Common::String s(p, p + 3);
- people._hSavedPos.x = atoi(s.c_str());
-
- s = Common::String(p + 3, p + 6);
- people._hSavedPos.y = atoi(s.c_str());
-
- s = Common::String(p + 6, p + 9);
- people._hSavedFacing = atoi(s.c_str());
- if (people._hSavedFacing == 0)
- people._hSavedFacing = 10;
- } else if ((p = strchr(name.c_str(), '/')) != nullptr) {
- people._hSavedPos = Common::Point(1, 0);
- people._hSavedFacing = 100 + atoi(p + 1);
- }
- } else {
- scene._goToScene = 100;
- }
-
- people[HOLMES]._position = Point32(0, 0);
- break;
- }
- } else if (name.hasPrefix("!")) {
- // Message attached to canimation
- int messageNum = atoi(name.c_str() + 1);
- ui._infoFlag = true;
- ui.clearInfo();
- screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", messages[messageNum]);
- ui._menuCounter = 25;
- } else if (name.hasPrefix("@")) {
- // Message attached to canimation
- ui._infoFlag = true;
- ui.clearInfo();
- screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", name.c_str() + 1);
- printed = true;
- ui._menuCounter = 25;
- }
-
- return printed;
-}
-
void Object::setFlagsAndToggles() {
Scene &scene = *_vm->_scene;
Talk &talk = *_vm->_talk;
diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h
index e73a8c3..3512930 100644
--- a/engines/sherlock/objects.h
+++ b/engines/sherlock/objects.h
@@ -167,6 +167,23 @@ struct UseType: public ActionType {
};
class BaseObject {
+protected:
+ static SherlockEngine *_vm;
+protected:
+ /**
+ * This will check to see if the object has reached the end of a sequence.
+ * If it has, it switch to whichever next sequence should be started.
+ * @returns true if the end of a sequence was reached
+ */
+ bool checkEndOfSequence();
+
+ /**
+ * Scans through the sequences array and finds the designated sequence.
+ * It then sets the frame number of the start of that sequence
+ */
+ void setObjSequence(int seq, bool wait);
+public:
+ static bool _countCAnimFrames;
public:
SpriteType _type; // Type of object/sprite
Common::String _description; // Description lines
@@ -210,6 +227,7 @@ public:
public:
BaseObject();
virtual ~BaseObject() {}
+ static void setVm(SherlockEngine *vm);
/**
* Returns true if the the object has an Allow Talk Code in the sequence that it's
@@ -218,12 +236,32 @@ public:
* If it's above 128, then it's one of the Listen sequences.
*/
bool hasAborts() const;
+
+ /**
+ * Check the state of the object
+ */
+ void checkObject();
+
+ /**
+ * Checks for codes
+ * @param name The name to check for codes
+ * @param messages Provides a lookup list of messages that can be printed
+ * @returns 0 if no codes are found, 1 if codes were found
+ */
+ int checkNameForCodes(const Common::String &name, const char *const messages[]);
+
+ /**
+ * Adjusts the frame and sequence variables of a sprite that corresponds to the current speaker
+ * so that it points to the beginning of the sequence number's talk sequence in the object's
+ * sequence buffer
+ * @param seq Which sequence to use (if there's more than 1)
+ * @remarks 1: First talk seq, 2: second talk seq, etc.
+ */
+ virtual void setObjTalkSequence(int seq) = 0;
};
class Sprite: public BaseObject {
protected:
- static SherlockEngine *_vm;
-
/**
* Free the alternate graphics used by NPCs
*/
@@ -275,7 +313,7 @@ public:
* @param seq Which sequence to use (if there's more than 1)
* @remarks 1: First talk seq, 2: second talk seq, etc.
*/
- void setObjTalkSequence(int seq);
+ virtual void setObjTalkSequence(int seq);
/**
* Return frame width
@@ -319,25 +357,6 @@ enum { OBJ_BEHIND = 1, OBJ_FLIPPED = 2, OBJ_FORWARD = 4, TURNON_OBJ = 0x20, TURN
#define USE_COUNT 4
class Object: public BaseObject {
-private:
- static SherlockEngine *_vm;
-
- /**
- * This will check to see if the object has reached the end of a sequence.
- * If it has, it switch to whichever next sequence should be started.
- * @returns true if the end of a sequence was reached
- */
- bool checkEndOfSequence();
-
- /**
- * Scans through the sequences array and finds the designated sequence.
- * It then sets the frame number of the start of that sequence
- */
- void setObjSequence(int seq, bool wait);
-public:
- static bool _countCAnimFrames;
-
- static void setVm(SherlockEngine *vm);
public:
Common::String _name; // Name
Common::String _examine; // Examine in-depth description
@@ -367,19 +386,6 @@ public:
void toggleHidden();
/**
- * Check the state of the object
- */
- void checkObject();
-
- /**
- * Checks for codes
- * @param name The name to check for codes
- * @param messages Provides a lookup list of messages that can be printed
- * @returns 0 if no codes are found, 1 if codes were found
- */
- int checkNameForCodes(const Common::String &name, const char *const messages[]);
-
- /**
* Handle setting any flags associated with the object
*/
void setFlagsAndToggles();
@@ -428,7 +434,7 @@ public:
* @param seq Which sequence to use (if there's more than 1)
* @remarks 1: First talk seq, 2: second talk seq, etc.
*/
- void setObjTalkSequence(int seq);
+ virtual void setObjTalkSequence(int seq);
};
diff --git a/engines/sherlock/scalpel/scalpel_scene.cpp b/engines/sherlock/scalpel/scalpel_scene.cpp
index 7239392..af70903 100644
--- a/engines/sherlock/scalpel/scalpel_scene.cpp
+++ b/engines/sherlock/scalpel/scalpel_scene.cpp
@@ -598,7 +598,7 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
++frames;
} else {
// Forward direction
- Object::_countCAnimFrames = true;
+ BaseObject::_countCAnimFrames = true;
while (cObj._type == ACTIVE_BG_SHAPE) {
cObj.checkObject();
@@ -611,7 +611,7 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
if (frames > 1)
--frames;
- Object::_countCAnimFrames = false;
+ BaseObject::_countCAnimFrames = false;
cObj._type = cAnim._type;
cObj._frameNumber = -1;
More information about the Scummvm-git-logs
mailing list