SHERLOCK: Implemented checkObject and some support methods

This commit is contained in:
Paul Gilbert 2015-03-21 18:18:12 -04:00
parent 8f4b4a7bc2
commit 26c5168074
15 changed files with 521 additions and 33 deletions

View file

@ -144,7 +144,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f
Common::String::format("%s%01d", baseName.c_str(), soundNumber) : Common::String::format("%s%01d", baseName.c_str(), soundNumber) :
Common::String::format("%s%02d", baseName.c_str(), soundNumber); Common::String::format("%s%02d", baseName.c_str(), soundNumber);
if (sound._voicesEnabled) if (sound._voicesOn)
sound.playSound(fname); sound.playSound(fname);
} }

View file

@ -33,7 +33,7 @@ namespace Sherlock {
EventsManager::EventsManager(SherlockEngine *vm) { EventsManager::EventsManager(SherlockEngine *vm) {
_vm = vm; _vm = vm;
_cursorImages = nullptr; _cursorImages = nullptr;
_cursorIndex = -1; _cursorId = INVALID_CURSOR;
_frameCounter = 1; _frameCounter = 1;
_priorFrameTime = 0; _priorFrameTime = 0;
_mouseClicked = false; _mouseClicked = false;
@ -57,11 +57,14 @@ void EventsManager::loadCursors(const Common::String &filename) {
/** /**
* Set the cursor to show * Set the cursor to show
*/ */
void EventsManager::changeCursor(int cursorIndex) { void EventsManager::changeCursor(CursorId cursorId) {
_cursorIndex = cursorIndex; if (cursorId == _cursorId)
return;
_cursorId = cursorId;
// Set the cursor data // Set the cursor data
Graphics::Surface &s = (*_cursorImages)[cursorIndex]; Graphics::Surface &s = (*_cursorImages)[cursorId];
CursorMan.replaceCursor(s.getPixels(), s.w, s.h, s.w / 2, s.h / 2, 0xff); CursorMan.replaceCursor(s.getPixels(), s.w, s.h, s.w / 2, s.h / 2, 0xff);
showCursor(); showCursor();

View file

@ -33,6 +33,8 @@ namespace Sherlock {
#define GAME_FRAME_RATE 60 #define GAME_FRAME_RATE 60
#define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE) #define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE)
enum CursorId { ARROW = 0, MAGNIFY = 1, WAIT = 2, INVALID_CURSOR = -1 };
class SherlockEngine; class SherlockEngine;
class EventsManager { class EventsManager {
@ -45,7 +47,7 @@ private:
bool checkForNextFrameCounter(); bool checkForNextFrameCounter();
public: public:
int _cursorIndex; CursorId _cursorId;
byte _mouseButtons; byte _mouseButtons;
bool _mouseClicked; bool _mouseClicked;
Common::Stack<Common::KeyState> _pendingKeys; Common::Stack<Common::KeyState> _pendingKeys;
@ -55,7 +57,7 @@ public:
void loadCursors(const Common::String &filename); void loadCursors(const Common::String &filename);
void changeCursor(int cursorIndex); void changeCursor(CursorId cursorId);
void showCursor(); void showCursor();

View file

@ -77,7 +77,6 @@ void Sprite::setImageFrame() {
void Sprite::adjustSprite() { void Sprite::adjustSprite() {
People &people = *_vm->_people; People &people = *_vm->_people;
Scene &scene = *_vm->_scene; Scene &scene = *_vm->_scene;
int checkFrame = _allow ? MAX_FRAME : 32000;
if (_type == INVALID || (_type == CHARACTER && _vm->_animating)) if (_type == INVALID || (_type == CHARACTER && _vm->_animating))
return; return;
@ -202,6 +201,17 @@ void UseType::synchronize(Common::SeekableReadStream &s) {
/*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/
SherlockEngine *Object::_vm;
bool Object::_countCAnimFrames;
void Object::setVm(SherlockEngine *vm) {
_vm = vm;
_countCAnimFrames = false;
}
/**
* Load the object data from the passed stream
*/
void Object::synchronize(Common::SeekableReadStream &s) { void Object::synchronize(Common::SeekableReadStream &s) {
char buffer[50]; char buffer[50];
@ -225,8 +235,8 @@ void Object::synchronize(Common::SeekableReadStream &s) {
_sequenceNumber = s.readSint16LE(); _sequenceNumber = s.readSint16LE();
_position.x = s.readSint16LE(); _position.x = s.readSint16LE();
_position.y = s.readSint16LE(); _position.y = s.readSint16LE();
_movement.x = s.readSint16LE(); _delta.x = s.readSint16LE();
_movement.y = s.readSint16LE(); _delta.y = s.readSint16LE();
_type = (SpriteType)s.readUint16LE(); _type = (SpriteType)s.readUint16LE();
_oldPosition.x = s.readSint16LE(); _oldPosition.x = s.readSint16LE();
_oldPosition.y = s.readSint16LE(); _oldPosition.y = s.readSint16LE();
@ -268,6 +278,9 @@ void Object::synchronize(Common::SeekableReadStream &s) {
_use[idx].synchronize(s); _use[idx].synchronize(s);
} }
/**
* Toggle the type of an object between hidden and active
*/
void Object::toggleHidden() { void Object::toggleHidden() {
if (_type != HIDDEN && _type != HIDE_SHAPE && _type != INVALID) { if (_type != HIDDEN && _type != HIDE_SHAPE && _type != INVALID) {
if (_seqTo != 0) if (_seqTo != 0)
@ -303,6 +316,153 @@ void Object::toggleHidden() {
} }
} }
/**
* Check the state of the object
*/
void Object::checkObject(Object &o) {
Scene &scene = *_vm->_scene;
Sound &sound = *_vm->_sound;
int checkFrame = _allow ? MAX_FRAME : 32000;
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--;
else
*ptr++;
return;
}
}
++_frameNumber;
do {
// Check for end of sequence
codeFound = checkEndOfSequence();
if (_sequences[_frameNumber] >= 128 && _frameNumber < checkFrame) {
codeFound = true;
int v = _sequences[_frameNumber];
if (v >= 228) {
// Goto code found
v -= 228;
_seqcounter2 = _seqCounter;
_seqStack = _frameNumber + 1;
setObjSequence(v, false);
} else if (v >= SOUND_CODE && (v <= (SOUND_CODE + 29))) {
codeFound = true;
++_frameNumber;
v -= SOUND_CODE;
if (sound._soundOn && !_countCAnimFrames) {
if (!scene._sounds[v - 1]._name.empty() && sound._digitized)
sound.playLoadedSound(v - 1, 0);
}
} else if (v >= FLIP_CODE && v <= (FLIP_CODE + 2)) {
// Flip code
codeFound = true;
++_frameNumber;
v -= FLIP_CODE;
// Alter the flipped status
switch (v) {
case 0:
// Clear the flag
_flags &= ~2;
break;
case 1:
// Set the flag
_flags |= 2;
break;
case 2:
// Toggle the flag
_flags ^= 2;
break;
default:
break;
}
} else {
v -= 128;
// 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);
if (*p > 128)
// If the high bit is set, convert to a real frame
*p -= (byte)(SEQ_TO_CODE - 128);
if (*p > _seqTo)
*p -= 1;
else
*p += 1;
// Will be incremented below to return back to original value
--_frameNumber;
v = 0;
} 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--;
if (pt.y > 128)
pt.y = (pt.y - 128) * -1;
else
pt.y;
_delta = pt;
_frameNumber += 2;
} else if (v < 4) {
for (int idx = 0; idx < 4; ++idx) {
o.checkNameForCodes(_use[v]._names[idx], nullptr);
}
if (_use[v]._useFlag)
_vm->setFlags(_use[v]._useFlag);
}
++_frameNumber;
}
}
} while (codeFound);
}
bool Object::checkEndOfSequence() const {
// TODO
return false;
}
void Object::setObjSequence(int seq, bool wait) {
// TODO
}
/**
* Checks for codes
* @param name The name to check for codes
* @param messages If provided, any messages to be returned
* @returns 0 if no codes are found, 1 if codes were found
*/
int Object::checkNameForCodes(const Common::String &name, Common::StringArray *messages) {
// TODO
return 0;
}
/*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/
void CAnim::synchronize(Common::SeekableReadStream &s) { void CAnim::synchronize(Common::SeekableReadStream &s) {
@ -318,10 +478,10 @@ void CAnim::synchronize(Common::SeekableReadStream &s) {
_flags = s.readByte(); _flags = s.readByte();
_goto.x = s.readSint16LE(); _goto.x = s.readSint16LE();
_goto.y = s.readSint16LE(); _goto.y = s.readSint16LE();
_sequenceNumber = s.readSint16LE(); _gotoDir = s.readSint16LE();
_teleportPos.x = s.readSint16LE(); _teleportPos.x = s.readSint16LE();
_teleportPos.y = s.readSint16LE(); _teleportPos.y = s.readSint16LE();
_teleportS = s.readSint16LE(); _teleportDir = s.readSint16LE();
} }
/*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/

View file

@ -137,7 +137,18 @@ struct UseType {
void synchronize(Common::SeekableReadStream &s); void synchronize(Common::SeekableReadStream &s);
}; };
struct Object { class Object {
private:
static SherlockEngine *_vm;
bool checkEndOfSequence() const;
void setObjSequence(int seq, bool wait);
public:
static bool _countCAnimFrames;
static void setVm(SherlockEngine *vm);
public:
Common::String _name; // Name Common::String _name; // Name
Common::String _description; // Description Common::String _description; // Description
Common::String _examine; // Examine in-depth description Common::String _examine; // Examine in-depth description
@ -151,7 +162,7 @@ struct Object {
int _sequenceNumber; // Sequence being used int _sequenceNumber; // Sequence being used
SpriteType _type; // Object type SpriteType _type; // Object type
Common::Point _position; // Current position Common::Point _position; // Current position
Common::Point _movement; // Momvement amount Common::Point _delta; // Momvement amount
Common::Point _oldPosition; // Old position Common::Point _oldPosition; // Old position
Common::Point _oldSize; // Image's old size Common::Point _oldSize; // Image's old size
Common::Point _goto; // Walk destination Common::Point _goto; // Walk destination
@ -185,19 +196,23 @@ struct Object {
void synchronize(Common::SeekableReadStream &s); void synchronize(Common::SeekableReadStream &s);
void toggleHidden(); void toggleHidden();
void checkObject(Object &o);
int checkNameForCodes(const Common::String &name, Common::StringArray *messages);
}; };
struct CAnim { struct CAnim {
Common::String _name; // Name Common::String _name; // Name
int _sequences[MAX_FRAME]; // Animation sequences byte _sequences[MAX_FRAME]; // Animation sequences
Common::Point _position; // Position Common::Point _position; // Position
int _size; // Size of uncompressed animation int _size; // Size of uncompressed animation
SpriteType _type; SpriteType _type;
int _flags; // Tells if can be walked behind int _flags; // Tells if can be walked behind
Common::Point _goto; // coords holmes should walk to before starting canim Common::Point _goto; // coords holmes should walk to before starting canim
int _sequenceNumber; int _gotoDir;
Common::Point _teleportPos; // Location Holmes shoul teleport to after Common::Point _teleportPos; // Location Holmes shoul teleport to after
int _teleportS; // playing canim int _teleportDir; // playing canim
void synchronize(Common::SeekableReadStream &s); void synchronize(Common::SeekableReadStream &s);
}; };

View file

@ -289,4 +289,9 @@ void People::gotoStand(Sprite &sprite) {
_allowWalkAbort = true; _allowWalkAbort = true;
} }
void People::walkToCoords(const Common::Point &destPos, int destDir) {
// TODO
warning("TODO: walkToCoords");
}
} // End of namespace Sherlock } // End of namespace Sherlock

View file

@ -79,6 +79,8 @@ public:
void setWalking(); void setWalking();
void gotoStand(Sprite &sprite); void gotoStand(Sprite &sprite);
void walkToCoords(const Common::Point &destPos, int destDir);
}; };
} // End of namespace Sherlock } // End of namespace Sherlock

View file

@ -129,7 +129,7 @@ void Resources::addToCache(const Common::String &filename) {
} }
/** /**
* Adds a resource from a library file tot he cache * Adds a resource from a library file to the cache
*/ */
void Resources::addToCache(const Common::String &filename, const Common::String &libFilename) { void Resources::addToCache(const Common::String &filename, const Common::String &libFilename) {
// Get the resource // Get the resource
@ -140,6 +140,16 @@ void Resources::addToCache(const Common::String &filename, const Common::String
delete stream; delete stream;
} }
/**
* Adds a given stream to the cache under the given name
*/
void Resources::addToCache(const Common::String &filename, Common::SeekableReadStream &stream) {
_cache.load(filename, stream);
}
/**
* Returns a stream for a given file
*/
Common::SeekableReadStream *Resources::load(const Common::String &filename) { Common::SeekableReadStream *Resources::load(const Common::String &filename) {
// First check if the file is directly in the cache // First check if the file is directly in the cache
if (_cache.isCached(filename)) if (_cache.isCached(filename))

View file

@ -76,6 +76,7 @@ public:
void addToCache(const Common::String &filename); void addToCache(const Common::String &filename);
void addToCache(const Common::String &filename, const Common::String &libFilename); void addToCache(const Common::String &filename, const Common::String &libFilename);
void addToCache(const Common::String &filename, Common::SeekableReadStream &stream);
bool isInCache(const Common::String &filename) const { return _cache.isCached(filename); } bool isInCache(const Common::String &filename) const { return _cache.isCached(filename); }
Common::SeekableReadStream *load(const Common::String &filename); Common::SeekableReadStream *load(const Common::String &filename);

View file

@ -183,7 +183,7 @@ bool ScalpelEngine::showOfficeCutscene() {
void ScalpelEngine::startScene() { void ScalpelEngine::startScene() {
if (_scene->_goToRoom == 100 || _scene->_goToRoom == 98) { if (_scene->_goToRoom == 100 || _scene->_goToRoom == 98) {
// Chessboard selection // Chessboard selection
if (_sound->_musicEnabled) { if (_sound->_musicOn) {
if (_sound->loadSong(100)) { if (_sound->loadSong(100)) {
if (_sound->_music) if (_sound->_music)
_sound->startSong(); _sound->startSong();
@ -208,7 +208,7 @@ void ScalpelEngine::startScene() {
case 52: case 52:
case 53: case 53:
case 70: case 70:
if (_sound->_musicEnabled && _sound->loadSong(_scene->_goToRoom)) { if (_sound->_musicOn && _sound->loadSong(_scene->_goToRoom)) {
if (_sound->_music) if (_sound->_music)
_sound->startSong(); _sound->startSong();
} }
@ -325,7 +325,7 @@ void ScalpelEngine::startScene() {
} }
_events->loadCursors("rmouse.vgs"); _events->loadCursors("rmouse.vgs");
_events->changeCursor(0); _events->changeCursor(ARROW);
if (_scene->_goToRoom == 99) { if (_scene->_goToRoom == 99) {
// Chess Board // Chess Board

View file

@ -98,6 +98,7 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) {
_invGraphicItems = 0; _invGraphicItems = 0;
_hsavedPos = Common::Point(-1, -1); _hsavedPos = Common::Point(-1, -1);
_hsavedFs = -1; _hsavedFs = -1;
_cAnimFramePause = 0;
_controlPanel = new ImageFile("controls.vgs"); _controlPanel = new ImageFile("controls.vgs");
_controls = nullptr; // new ImageFile("menu.all"); _controls = nullptr; // new ImageFile("menu.all");
@ -124,7 +125,7 @@ void Scene::selectScene() {
// Load the scene // Load the scene
Common::String sceneFile = Common::String::format("res%02d", _goToRoom); Common::String sceneFile = Common::String::format("res%02d", _goToRoom);
Common::String roomName = Common::String::format("res%02d.rrm", _goToRoom); _rrmName = Common::String::format("res%02d.rrm", _goToRoom);
_currentScene = _goToRoom; _currentScene = _goToRoom;
_goToRoom = -1; _goToRoom = -1;
@ -312,7 +313,7 @@ bool Scene::loadScene(const Common::String &filename) {
_sounds[idx].synchronize(*rrmStream); _sounds[idx].synchronize(*rrmStream);
// If sound is turned on, load the sounds into memory // If sound is turned on, load the sounds into memory
if (sound._sfxEnabled) { if (sound._soundOn) {
for (int idx = 0; idx < numSounds; ++idx) { for (int idx = 0; idx < numSounds; ++idx) {
sound.loadSound(_sounds[idx]._name, _sounds[idx]._priority); sound.loadSound(_sounds[idx]._name, _sounds[idx]._priority);
_sounds[idx]._name = ""; _sounds[idx]._name = "";
@ -374,7 +375,7 @@ bool Scene::loadScene(const Common::String &filename) {
checkInventory(); checkInventory();
// Handle starting any music for the scene // Handle starting any music for the scene
if (sound._musicEnabled && sound.loadSong(_currentScene)) { if (sound._musicOn && sound.loadSong(_currentScene)) {
if (sound._music) if (sound._music)
sound.startSong(); sound.startSong();
} }
@ -516,6 +517,7 @@ void Scene::transitionToScene() {
STOP_DOWNLEFT, STOP_LEFT, STOP_UPLEFT STOP_DOWNLEFT, STOP_LEFT, STOP_UPLEFT
}; };
People &people = *_vm->_people; People &people = *_vm->_people;
Screen &screen = *_vm->_screen;
if (_hsavedPos.x < 1) { if (_hsavedPos.x < 1) {
// No exit information from last scene-check entrance info // No exit information from last scene-check entrance info
@ -539,7 +541,7 @@ void Scene::transitionToScene() {
} }
} }
int startcAnimNum = -1; int cAnimNum = -1;
if (_hsavedFs < 101) { if (_hsavedFs < 101) {
// Standard info, so set it // Standard info, so set it
@ -547,7 +549,7 @@ void Scene::transitionToScene() {
people[PLAYER]._sequenceNumber = _hsavedFs; people[PLAYER]._sequenceNumber = _hsavedFs;
} else { } else {
// It's canimation information // It's canimation information
startcAnimNum = _hsavedFs - 101; cAnimNum = _hsavedFs - 101;
// Prevent Holmes from being drawn // Prevent Holmes from being drawn
people[PLAYER]._position = Common::Point(0, 0); people[PLAYER]._position = Common::Point(0, 0);
@ -599,7 +601,22 @@ void Scene::transitionToScene() {
} }
updateBackground(); updateBackground();
// TODO
if (screen._fadeStyle)
screen.randomTransition();
else
screen.blitFrom(screen._backBuffer);
if (cAnimNum != -1) {
CAnim &c = _cAnim[cAnimNum];
Common::Point pt = c._position;
c._position = Common::Point(-1, -1);
people[AL]._position = Common::Point(0, 0);
startCAnim(cAnimNum, 1);
c._position = pt;
}
} }
/** /**
@ -722,9 +739,265 @@ Exit *Scene::checkForExit(const Common::Rect &r) {
return nullptr; return nullptr;
} }
/**
* Checks all the background shapes. If a background shape is animating,
* it will flag it as needing to be drawn. If a non-animating shape is
* colliding with another shape, it will also flag it as needing drawing
*/
void Scene::checkBgShapes(ImageFrame *frame, const Common::Point &pt) { void Scene::checkBgShapes(ImageFrame *frame, const Common::Point &pt) {
// Iterate through the shapes
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
Object &obj = _bgShapes[idx];
if (obj._type == STATIC_BG_SHAPE || obj._type == ACTIVE_BG_SHAPE) {
if ((obj._flags & 5) == 1) {
obj._misc = (pt.y < (obj._position.y + obj._imageFrame->_frame.h - 1)) ?
NORMAL_FORWARD : NORMAL_BEHIND;
} else if (!(obj._flags & 1)) {
obj._misc = BEHIND;
} else if (obj._flags & 4) {
obj._misc = FORWARD;
}
}
}
// Iterate through the canimshapes
for (uint idx = 0; idx < _canimShapes.size(); ++idx) {
Object &obj = _canimShapes[idx];
if (obj._type == STATIC_BG_SHAPE || obj._type == ACTIVE_BG_SHAPE) {
if ((obj._flags & 5) == 1) {
obj._misc = (pt.y < (obj._position.y + obj._imageFrame->_frame.h - 1)) ?
NORMAL_FORWARD : NORMAL_BEHIND;
}
else if (!(obj._flags & 1)) {
obj._misc = BEHIND;
}
else if (obj._flags & 4) {
obj._misc = FORWARD;
}
}
}
}
/**
* Attempt to start a canimation sequence. It will load the requisite graphics, and
* then copy the canim object into the _canimShapes array to start the animation.
*
* @param cAnimNum The canim object within the current scene
* @param playRate Play rate. 0 is invalid; 1=normal speed, 2=1/2 speed, etc.
* A negative playRate can also be specified to play the animation in reverse
*/
int Scene::startCAnim(int cAnimNum, int playRate) {
EventsManager &events = *_vm->_events;
People &people = *_vm->_people;
Resources &res = *_vm->_res;
Common::Point tpPos, walkPos;
int tpDir, walkDir;
int tFrames;
int gotoCode = -1;
// Validation
if (cAnimNum >= (int)_cAnim.size())
// number out of bounds
return -1;
if (_canimShapes.size() >= 3 || playRate == 0)
// Too many active animations, or invalid play rate
return 0;
CAnim &cAnim = _cAnim[cAnimNum];
if (playRate < 0) {
// Reverse direction
walkPos = cAnim._teleportPos;
walkDir = cAnim._teleportDir;
tpPos = cAnim._goto;
tpDir = cAnim._gotoDir;
} else {
// Forward direction
walkPos = cAnim._goto;
walkDir = cAnim._gotoDir;
tpPos = cAnim._teleportPos;
tpDir = cAnim._teleportDir;
}
events.changeCursor(WAIT);
_canimShapes.push_back(Object());
Object &cObj = _canimShapes[_canimShapes.size() - 1];
if (walkPos.x != -1) {
// Holmes must walk to the walk point before the cAnimation is started
if (people[AL]._position != walkPos)
people.walkToCoords(walkPos, walkDir);
}
if (_vm->_talkToAbort)
return 1;
// Copy the canimation into the bgShapes type canimation structure so it can be played
cObj._allow = cAnimNum + 1; // Keep track of the parent structure
cObj._name = _cAnim[cAnimNum]._name; // Copy name
// Remove any attempt to draw object frame
if (cAnim._type == NO_SHAPE && cAnim._sequences[0] < 100)
cAnim._sequences[0] = 0;
cObj._sequences = cAnim._sequences;
cObj._images = nullptr;
cObj._position = cAnim._position;
cObj._delta = Common::Point(0, 0);
cObj._type = cAnim._type;
cObj._flags = cAnim._flags;
cObj._maxFrames = 0;
cObj._frameNumber = -1;
cObj._sequenceNumber = cAnimNum;
cObj._oldPosition = Common::Point(0, 0);
cObj._oldPosition = Common::Point(0, 0);
cObj._goto = Common::Point(0, 0);
cObj._status = 0;
cObj._misc = 0;
cObj._imageFrame = nullptr;
if (cAnim._name.size() > 0 && cAnim._type != NO_SHAPE) {
if (tpPos.x != -1)
people[AL]._type = REMOVE;
Common::String fname = cAnim._name + ".vgs";
if (!res.isInCache(fname)) {
// Set up RRM scene data
Common::SeekableReadStream *rrmStream = res.load(_rrmName);
rrmStream->seek(44 + cAnimNum * 4);
rrmStream->seek(rrmStream->readUint32LE());
// Load the canimation into the cache
Common::SeekableReadStream *imgStream = !_lzwMode ? rrmStream :
decompressLZ(*rrmStream, cAnim._size);
res.addToCache(fname, *imgStream);
if (_lzwMode)
delete imgStream;
delete rrmStream;
}
// Now load the resource as an image
cObj._maxFrames = cObj._images->size();
cObj._images = new ImageFile(fname);
cObj._imageFrame = &(*cObj._images)[0];
int frames = 0;
if (playRate < 0) {
// Reverse direction
// Count number of frames
while (cObj._sequences[frames] && frames < MAX_FRAME)
++frames;
}
else {
// Forward direction
Object::_countCAnimFrames = true;
while (cObj._type == ACTIVE_BG_SHAPE) {
cObj.checkObject(_bgShapes[0]);
++frames;
if (frames >= 1000)
error("CAnim has infinite loop sequence");
}
if (frames > 1)
--frames;
Object::_countCAnimFrames = false;
cObj._type = cAnim._type;
cObj._frameNumber = -1;
cObj._position = cAnim._position;
cObj._delta = Common::Point(0, 0);
}
// Return if animation has no frames in it
if (frames == 0)
return -2;
++frames;
int repeat = ABS(playRate);
int dir;
if (playRate < 0) {
// Play in reverse
dir = -2;
cObj._frameNumber = frames - 3;
} else {
dir = 0;
}
tFrames = frames - 1;
int pauseFrame = (_cAnimFramePause) ? frames - _cAnimFramePause : -1;
while (--frames) {
if (frames == pauseFrame)
printObjDesc(_cAnimStr, true);
doBgAnim();
// Repeat same frame
int temp = repeat;
while (--temp > 0) {
cObj._frameNumber--;
doBgAnim();
}
cObj._frameNumber += dir;
}
people[AL]._type = CHARACTER;
}
// Teleport to ending coordinates if necessary
if (tpPos.x != -1) {
people[AL]._position = tpPos; // Place the player
people[AL]._sequenceNumber = tpDir;
people.gotoStand(people[AL]);
}
if (playRate < 0)
// Reverse direction - set to end sequence
cObj._frameNumber = tFrames - 1;
if (cObj._frameNumber <= 26)
gotoCode = cObj._sequences[cObj._frameNumber + 3];
// Set canim to REMOVE type and free memory
cObj.checkObject(_bgShapes[0]);
if (gotoCode > 0 && !_vm->_talkToAbort) {
_goToRoom = gotoCode;
if (_goToRoom < 97 && _vm->_map[_goToRoom].x) {
_overPos = _vm->_map[_goToRoom];
}
}
people.loadWalk();
if (tpPos.x != -1 && !_vm->_talkToAbort) {
// Teleport to ending coordinates
people[AL]._position = tpPos;
people[AL]._sequenceNumber = tpDir;
people.gotoStand(people[AL]);
}
return 1;
}
void Scene::printObjDesc(const Common::String &str, bool firstTime) {
// TODO // TODO
} }
/**
* Animate all objects and people.
*/
void Scene::doBgAnim() {
// TODO
}
} // End of namespace Sherlock } // End of namespace Sherlock

View file

@ -87,6 +87,9 @@ struct SceneSound {
class Scene { class Scene {
private: private:
SherlockEngine *_vm; SherlockEngine *_vm;
Common::String _rrmName;
int _cAnimFramePause;
Common::String _cAnimStr;
bool loadScene(const Common::String &filename); bool loadScene(const Common::String &filename);
@ -101,6 +104,10 @@ private:
void updateBackground(); void updateBackground();
void checkBgShapes(ImageFrame *frame, const Common::Point &pt); void checkBgShapes(ImageFrame *frame, const Common::Point &pt);
int startCAnim(int cAnimNum, int playRate);
void doBgAnim();
public: public:
int _currentScene; int _currentScene;
int _goToRoom; int _goToRoom;
@ -147,6 +154,8 @@ public:
void checkSceneFlags(bool mode); void checkSceneFlags(bool mode);
Exit *checkForExit(const Common::Rect &r); Exit *checkForExit(const Common::Rect &r);
void printObjDesc(const Common::String &str, bool firstTime);
}; };
} // End of namespace Sherlock } // End of namespace Sherlock

View file

@ -70,6 +70,7 @@ void SherlockEngine::initialize() {
DebugMan.addDebugChannel(kDebugScript, "scripts", "Script debug level"); DebugMan.addDebugChannel(kDebugScript, "scripts", "Script debug level");
ImageFile::setVm(this); ImageFile::setVm(this);
Object::setVm(this);
Sprite::setVm(this); Sprite::setVm(this);
_res = new Resources(); _res = new Resources();
_animation = new Animation(this); _animation = new Animation(this);

View file

@ -25,11 +25,12 @@
namespace Sherlock { namespace Sherlock {
Sound::Sound(SherlockEngine *vm): _vm(vm) { Sound::Sound(SherlockEngine *vm): _vm(vm) {
_sfxEnabled = true; _soundOn = true;
_musicEnabled = true; _musicOn = true;
_voicesEnabled = true; _voicesOn = true;
_playingEpilogue = false; _playingEpilogue = false;
_music = false; _music = false;
_digitized = false;
} }
void Sound::loadSound(const Common::String &name, int priority) { void Sound::loadSound(const Common::String &name, int priority) {
@ -44,6 +45,10 @@ void Sound::cacheSound(const Common::String &name, int index) {
// TODO // TODO
} }
void Sound::playLoadedSound(int bufNum, int waitMode) {
// TODO
}
void Sound::playCachedSound(int index) { void Sound::playCachedSound(int index) {
// TODO // TODO
} }

View file

@ -38,17 +38,19 @@ class Sound {
private: private:
SherlockEngine *_vm; SherlockEngine *_vm;
public: public:
bool _sfxEnabled; bool _soundOn;
bool _musicEnabled; bool _musicOn;
bool _voicesEnabled; bool _voicesOn;
bool _playingEpilogue; bool _playingEpilogue;
bool _music; bool _music;
bool _digitized;
public: public:
Sound(SherlockEngine *vm); Sound(SherlockEngine *vm);
void loadSound(const Common::String &name, int priority); void loadSound(const Common::String &name, int priority);
void playSound(const Common::String &name, WaitType waitType = WAIT_RETURN_IMMEDIATELY); void playSound(const Common::String &name, WaitType waitType = WAIT_RETURN_IMMEDIATELY);
void cacheSound(const Common::String &name, int index); void cacheSound(const Common::String &name, int index);
void playLoadedSound(int bufNum, int waitMode);
void playCachedSound(int index); void playCachedSound(int index);
void clearCache(); void clearCache();
void stopSound(); void stopSound();