SHERLOCK: Implemented checkSprite

This commit is contained in:
Paul Gilbert 2015-03-21 20:25:15 -04:00
parent 26c5168074
commit 7f04ea4425
17 changed files with 355 additions and 53 deletions

View file

@ -66,7 +66,7 @@ Animation::Animation(SherlockEngine *vm): _vm(vm) {
bool Animation::playPrologue(const Common::String &filename, int minDelay, int fade, bool Animation::playPrologue(const Common::String &filename, int minDelay, int fade,
bool setPalette, int speed) { bool setPalette, int speed) {
EventsManager &events = *_vm->_events; Events &events = *_vm->_events;
Screen &screen = *_vm->_screen; Screen &screen = *_vm->_screen;
Sound &sound = *_vm->_sound; Sound &sound = *_vm->_sound;
int soundNumber = 0; int soundNumber = 0;
@ -123,7 +123,7 @@ bool Animation::playPrologue(const Common::String &filename, int minDelay, int f
pt.x = stream->readUint16LE(); pt.x = stream->readUint16LE();
pt.y = stream->readUint16LE(); pt.y = stream->readUint16LE();
} else { } else {
pt = images[imageFrame]._position; pt = images[imageFrame]._offset;
} }
// Draw the sprite // Draw the sprite

View file

@ -30,7 +30,7 @@
namespace Sherlock { namespace Sherlock {
EventsManager::EventsManager(SherlockEngine *vm) { Events::Events(SherlockEngine *vm) {
_vm = vm; _vm = vm;
_cursorImages = nullptr; _cursorImages = nullptr;
_cursorId = INVALID_CURSOR; _cursorId = INVALID_CURSOR;
@ -40,14 +40,14 @@ EventsManager::EventsManager(SherlockEngine *vm) {
_mouseButtons = 0; _mouseButtons = 0;
} }
EventsManager::~EventsManager() { Events::~Events() {
delete _cursorImages; delete _cursorImages;
} }
/** /**
* Load a set of cursors from the specified file * Load a set of cursors from the specified file
*/ */
void EventsManager::loadCursors(const Common::String &filename) { void Events::loadCursors(const Common::String &filename) {
hideCursor(); hideCursor();
delete _cursorImages; delete _cursorImages;
@ -57,7 +57,7 @@ void EventsManager::loadCursors(const Common::String &filename) {
/** /**
* Set the cursor to show * Set the cursor to show
*/ */
void EventsManager::changeCursor(CursorId cursorId) { void Events::setCursor(CursorId cursorId) {
if (cursorId == _cursorId) if (cursorId == _cursorId)
return; return;
@ -73,28 +73,35 @@ void EventsManager::changeCursor(CursorId cursorId) {
/** /**
* Show the mouse cursor * Show the mouse cursor
*/ */
void EventsManager::showCursor() { void Events::showCursor() {
CursorMan.showMouse(true); CursorMan.showMouse(true);
} }
/** /**
* Hide the mouse cursor * Hide the mouse cursor
*/ */
void EventsManager::hideCursor() { void Events::hideCursor() {
CursorMan.showMouse(false); CursorMan.showMouse(false);
} }
/**
* Returns the cursor
*/
CursorId Events::getCursor() const {
return _cursorId;
}
/** /**
* Returns true if the mouse cursor is visible * Returns true if the mouse cursor is visible
*/ */
bool EventsManager::isCursorVisible() { bool Events::isCursorVisible() const {
return CursorMan.isVisible(); return CursorMan.isVisible();
} }
/** /**
* Check for any pending events * Check for any pending events
*/ */
void EventsManager::pollEvents() { void Events::pollEvents() {
checkForNextFrameCounter(); checkForNextFrameCounter();
Common::Event event; Common::Event event;
@ -138,7 +145,7 @@ void EventsManager::pollEvents() {
* Poll for events and introduce a small delay, to allow the system to * Poll for events and introduce a small delay, to allow the system to
* yield to other running programs * yield to other running programs
*/ */
void EventsManager::pollEventsAndWait() { void Events::pollEventsAndWait() {
pollEvents(); pollEvents();
g_system->delayMillis(10); g_system->delayMillis(10);
} }
@ -146,7 +153,7 @@ void EventsManager::pollEventsAndWait() {
/** /**
* Check whether it's time to display the next screen frame * Check whether it's time to display the next screen frame
*/ */
bool EventsManager::checkForNextFrameCounter() { bool Events::checkForNextFrameCounter() {
// Check for next game frame // Check for next game frame
uint32 milli = g_system->getMillis(); uint32 milli = g_system->getMillis();
if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) { if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) {
@ -171,7 +178,7 @@ bool EventsManager::checkForNextFrameCounter() {
/** /**
* Clear any current keypress or mouse click * Clear any current keypress or mouse click
*/ */
void EventsManager::clearEvents() { void Events::clearEvents() {
_pendingKeys.clear(); _pendingKeys.clear();
_mouseClicked = false; _mouseClicked = false;
} }
@ -179,12 +186,12 @@ void EventsManager::clearEvents() {
/** /**
* Delay for a given number of game frames, where each frame is 1/60th of a second * Delay for a given number of game frames, where each frame is 1/60th of a second
*/ */
void EventsManager::wait(int numFrames) { void Events::wait(int numFrames) {
uint32 totalMilli = numFrames * 1000 / GAME_FRAME_RATE; uint32 totalMilli = numFrames * 1000 / GAME_FRAME_RATE;
delay(totalMilli); delay(totalMilli);
} }
bool EventsManager::delay(uint32 time, bool interruptable) { bool Events::delay(uint32 time, bool interruptable) {
// Different handling for really short versus extended times // Different handling for really short versus extended times
if (time < 10) { if (time < 10) {
// For really short periods, simply delay by the desired amount // For really short periods, simply delay by the desired amount
@ -216,7 +223,7 @@ bool EventsManager::delay(uint32 time, bool interruptable) {
/** /**
* Wait for the next frame * Wait for the next frame
*/ */
void EventsManager::waitForNextFrame() { void Events::waitForNextFrame() {
_mouseClicked = false; _mouseClicked = false;
_mouseButtons = 0; _mouseButtons = 0;

View file

@ -37,7 +37,7 @@ enum CursorId { ARROW = 0, MAGNIFY = 1, WAIT = 2, INVALID_CURSOR = -1 };
class SherlockEngine; class SherlockEngine;
class EventsManager { class Events {
private: private:
SherlockEngine *_vm; SherlockEngine *_vm;
uint32 _frameCounter; uint32 _frameCounter;
@ -52,18 +52,20 @@ public:
bool _mouseClicked; bool _mouseClicked;
Common::Stack<Common::KeyState> _pendingKeys; Common::Stack<Common::KeyState> _pendingKeys;
public: public:
EventsManager(SherlockEngine *vm); Events(SherlockEngine *vm);
~EventsManager(); ~Events();
void loadCursors(const Common::String &filename); void loadCursors(const Common::String &filename);
void changeCursor(CursorId cursorId); void setCursor(CursorId cursorId);
void showCursor(); void showCursor();
void hideCursor(); void hideCursor();
bool isCursorVisible(); CursorId getCursor() const;
bool isCursorVisible() const;
void pollEvents(); void pollEvents();

View file

@ -33,6 +33,10 @@ namespace Sherlock {
#define LEFT_LIMIT 0 #define LEFT_LIMIT 0
#define RIGHT_LIMIT SHERLOCK_SCREEN_WIDTH #define RIGHT_LIMIT SHERLOCK_SCREEN_WIDTH
// Distance to walk around WALK_AROUND boxes
#define CLEAR_DIST_X 5
#define CLEAR_DIST_Y 0
SherlockEngine *Sprite::_vm; SherlockEngine *Sprite::_vm;
/** /**
@ -77,11 +81,12 @@ 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;
Talk &talk = *_vm->_talk;
if (_type == INVALID || (_type == CHARACTER && _vm->_animating)) if (_type == INVALID || (_type == CHARACTER && _vm->_animating))
return; return;
if (!_vm->_talkCounter && _type == CHARACTER && _walkCount) { if (!talk._talkCounter && _type == CHARACTER && _walkCount) {
// Handle active movement for the sprite // Handle active movement for the sprite
_position += _delta; _position += _delta;
--_walkCount; --_walkCount;
@ -163,6 +168,190 @@ void Sprite::adjustSprite() {
} }
} }
/**
* Checks the sprite's position to see if it's collided with any special objects
*/
void Sprite::checkSprite() {
Events &events = *_vm->_events;
People &people = *_vm->_people;
Scene &scene = *_vm->_scene;
Screen &screen = *_vm->_screen;
Talk &talk = *_vm->_talk;
Common::Point pt;
Common::Rect objBounds;
Common::Point spritePt(_position.x / 100, _position.y / 100);
if (!talk._talkCounter && _type == CHARACTER) {
pt = _walkCount ? _position + _delta : _position;
pt.x /= 100;
pt.y /= 100;
for (uint idx = 0; idx < scene._bgShapes.size() && !talk._talkToAbort; ++idx) {
Object &obj = scene._bgShapes[idx];
if (obj._aType > PERSON && _type != INVALID && _type != HIDDEN) {
if (_type == NO_SHAPE) {
objBounds = Common::Rect(_position.x, _position.y,
_position.x + _noShapeSize.x, _position.y + _noShapeSize.y);
} else {
int xp = _position.x + _imageFrame->_offset.x;
int yp = _position.y + _imageFrame->_offset.y;
objBounds = Common::Rect(xp, yp,
xp + _imageFrame->_frame.w, yp + _imageFrame->_frame.h);
}
}
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;
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;
// 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;
for (int idx = palStart; idx < (palStart + palLength); ++idx)
screen._sMap[idx] = screen._cMap[idx] * palPercent / 100;
events.pollEvents();
screen.setPalette(screen._sMap);
}
}
break;
case TALK:
case TALK_EVERY:
_type = HIDDEN;
obj.setFlagsAndToggles();
talk.talkTo(obj._use[0]._target);
break;
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;
case SOLID:
case TALK:
// Stop walking
if (obj._aType == TALK) {
obj.setFlagsAndToggles();
talk.talkTo(obj._use[0]._target);
} else {
people.gotoStand(*this);
}
break;
case TALK_EVERY:
if (obj._aType == TALK_EVERY) {
obj._type = HIDDEN;
obj.setFlagsAndToggles();
talk.talkTo(obj._use[0]._target);
} else {
people.gotoStand(*this);
}
break;
case FLAG_SET:
obj.setFlagsAndToggles();
obj._type = HIDDEN;
break;
case WALK_AROUND:
if (objBounds.contains(people._walkTo.top())) {
// Reached zone
people.gotoStand(*this);
} else {
// Destination not within box, walk to best corner
Common::Point walkPos;
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;
}
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;
}
walkPos.x = (_delta.x >= 0) ? objBounds.left - CLEAR_DIST_X :
objBounds.right + CLEAR_DIST_X;
}
walkPos.x += people[AL]._imageFrame->_frame.w / 2;
people._walkDest = walkPos;
people._walkTo.push(walkPos);
people.setWalking();
}
break;
case DELTA:
_position.x += 200;
break;
}
}
}
}
}
}
/*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/
void ActionType::synchronize(Common::SeekableReadStream &s) { void ActionType::synchronize(Common::SeekableReadStream &s) {
@ -463,6 +652,10 @@ int Object::checkNameForCodes(const Common::String &name, Common::StringArray *m
return 0; return 0;
} }
void Object::setFlagsAndToggles() {
// TODO
}
/*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/
void CAnim::synchronize(Common::SeekableReadStream &s) { void CAnim::synchronize(Common::SeekableReadStream &s) {

View file

@ -115,6 +115,8 @@ public:
void setImageFrame(); void setImageFrame();
void adjustSprite(); void adjustSprite();
void checkSprite();
}; };
struct ActionType { struct ActionType {
@ -200,6 +202,8 @@ public:
void checkObject(Object &o); void checkObject(Object &o);
int checkNameForCodes(const Common::String &name, Common::StringArray *messages); int checkNameForCodes(const Common::String &name, Common::StringArray *messages);
void setFlagsAndToggles();
}; };
struct CAnim { struct CAnim {

View file

@ -298,10 +298,10 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette) {
frame._width = stream.readUint16LE() + 1; frame._width = stream.readUint16LE() + 1;
frame._height = stream.readUint16LE() + 1; frame._height = stream.readUint16LE() + 1;
frame._flags = stream.readByte(); frame._flags = stream.readByte();
frame._position.x = stream.readUint16LE(); frame._offset.x = stream.readUint16LE();
frame._position.y = stream.readByte(); frame._offset.y = stream.readByte();
frame._rleEncoded = !skipPalette && (frame._position.x == 1); frame._rleEncoded = !skipPalette && (frame._offset.x == 1);
if (frame._flags & 0xFF) { if (frame._flags & 0xFF) {
// Nibble packed frame data // Nibble packed frame data

View file

@ -93,7 +93,7 @@ struct ImageFrame {
uint16 _width, _height; uint16 _width, _height;
int _flags; int _flags;
bool _rleEncoded; bool _rleEncoded;
Common::Point _position; Common::Point _offset;
byte _rleMarker; byte _rleMarker;
Graphics::Surface _frame; Graphics::Surface _frame;

View file

@ -325,7 +325,7 @@ void ScalpelEngine::startScene() {
} }
_events->loadCursors("rmouse.vgs"); _events->loadCursors("rmouse.vgs");
_events->changeCursor(ARROW); _events->setCursor(ARROW);
if (_scene->_goToRoom == 99) { if (_scene->_goToRoom == 99) {
// Chess Board // Chess Board

View file

@ -90,7 +90,7 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) {
_changes = false; _changes = false;
_charPoint = _oldCharPoint = 0; _charPoint = _oldCharPoint = 0;
_windowOpen = _infoFlag = false; _windowOpen = _infoFlag = false;
_menuMode = _keyboardInput = 0; _keyboardInput = 0;
_walkedInScene = false; _walkedInScene = false;
_ongoingCans = 0; _ongoingCans = 0;
_version = 0; _version = 0;
@ -99,6 +99,9 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) {
_hsavedPos = Common::Point(-1, -1); _hsavedPos = Common::Point(-1, -1);
_hsavedFs = -1; _hsavedFs = -1;
_cAnimFramePause = 0; _cAnimFramePause = 0;
_menuMode = STD_MODE;
_invMode = INVMODE_0;
_restoreFlag = false;
_controlPanel = new ImageFile("controls.vgs"); _controlPanel = new ImageFile("controls.vgs");
_controls = nullptr; // new ImageFile("menu.all"); _controls = nullptr; // new ImageFile("menu.all");
@ -119,7 +122,8 @@ void Scene::clear() {
void Scene::selectScene() { void Scene::selectScene() {
// Reset fields // Reset fields
_windowOpen = _infoFlag = false; _windowOpen = _infoFlag = false;
_menuMode = _keyboardInput = 0; _menuMode = STD_MODE;
_keyboardInput = 0;
_oldKey = _help = _oldHelp = 0; _oldKey = _help = _oldHelp = 0;
_oldTemp = _temp = 0; _oldTemp = _temp = 0;
@ -142,7 +146,7 @@ void Scene::selectScene() {
* that it should point to after loading; _misc is then set to 0. * that it should point to after loading; _misc is then set to 0.
*/ */
bool Scene::loadScene(const Common::String &filename) { bool Scene::loadScene(const Common::String &filename) {
EventsManager &events = *_vm->_events; Events &events = *_vm->_events;
People &people = *_vm->_people; People &people = *_vm->_people;
Screen &screen = *_vm->_screen; Screen &screen = *_vm->_screen;
Sound &sound = *_vm->_sound; Sound &sound = *_vm->_sound;
@ -512,12 +516,14 @@ void Scene::checkInventory() {
* in the scene * in the scene
*/ */
void Scene::transitionToScene() { void Scene::transitionToScene() {
const int FS_TRANS[8] = {
STOP_UP, STOP_UPRIGHT, STOP_RIGHT, STOP_DOWNRIGHT, STOP_DOWN,
STOP_DOWNLEFT, STOP_LEFT, STOP_UPLEFT
};
People &people = *_vm->_people; People &people = *_vm->_people;
Screen &screen = *_vm->_screen; Screen &screen = *_vm->_screen;
Talk &talk = *_vm->_talk;
const int FS_TRANS[8] = {
STOP_UP, STOP_UPRIGHT, STOP_RIGHT, STOP_DOWNRIGHT, STOP_DOWN,
STOP_DOWNLEFT, STOP_LEFT, STOP_UPLEFT
};
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
@ -563,7 +569,7 @@ void Scene::transitionToScene() {
Common::Point bottomRight; Common::Point bottomRight;
if (obj._type != NO_SHAPE) { if (obj._type != NO_SHAPE) {
topLeft += obj._imageFrame->_position; topLeft += obj._imageFrame->_offset;
bottomRight.x = topLeft.x + obj._imageFrame->_frame.w; bottomRight.x = topLeft.x + obj._imageFrame->_frame.w;
bottomRight.y = topLeft.y + obj._imageFrame->_frame.h; bottomRight.y = topLeft.y + obj._imageFrame->_frame.h;
} else { } else {
@ -583,7 +589,7 @@ void Scene::transitionToScene() {
_vm->setFlags(obj._use[useNum]._useFlag); _vm->setFlags(obj._use[useNum]._useFlag);
} }
if (!_vm->_talkToAbort) { if (!talk._talkToAbort) {
for (int nameIdx = 0; nameIdx < 4; ++nameIdx) { for (int nameIdx = 0; nameIdx < 4; ++nameIdx) {
toggleObject(obj._use[useNum]._names[nameIdx]); toggleObject(obj._use[useNum]._names[nameIdx]);
} }
@ -787,9 +793,10 @@ void Scene::checkBgShapes(ImageFrame *frame, const Common::Point &pt) {
* A negative playRate can also be specified to play the animation in reverse * A negative playRate can also be specified to play the animation in reverse
*/ */
int Scene::startCAnim(int cAnimNum, int playRate) { int Scene::startCAnim(int cAnimNum, int playRate) {
EventsManager &events = *_vm->_events; Events &events = *_vm->_events;
People &people = *_vm->_people; People &people = *_vm->_people;
Resources &res = *_vm->_res; Resources &res = *_vm->_res;
Talk &talk = *_vm->_talk;
Common::Point tpPos, walkPos; Common::Point tpPos, walkPos;
int tpDir, walkDir; int tpDir, walkDir;
int tFrames; int tFrames;
@ -818,7 +825,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) {
tpDir = cAnim._teleportDir; tpDir = cAnim._teleportDir;
} }
events.changeCursor(WAIT); events.setCursor(WAIT);
_canimShapes.push_back(Object()); _canimShapes.push_back(Object());
Object &cObj = _canimShapes[_canimShapes.size() - 1]; Object &cObj = _canimShapes[_canimShapes.size() - 1];
@ -828,7 +835,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) {
people.walkToCoords(walkPos, walkDir); people.walkToCoords(walkPos, walkDir);
} }
if (_vm->_talkToAbort) if (talk._talkToAbort)
return 1; return 1;
// Copy the canimation into the bgShapes type canimation structure so it can be played // Copy the canimation into the bgShapes type canimation structure so it can be played
@ -968,7 +975,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) {
// Set canim to REMOVE type and free memory // Set canim to REMOVE type and free memory
cObj.checkObject(_bgShapes[0]); cObj.checkObject(_bgShapes[0]);
if (gotoCode > 0 && !_vm->_talkToAbort) { if (gotoCode > 0 && !talk._talkToAbort) {
_goToRoom = gotoCode; _goToRoom = gotoCode;
if (_goToRoom < 97 && _vm->_map[_goToRoom].x) { if (_goToRoom < 97 && _vm->_map[_goToRoom].x) {
@ -978,7 +985,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) {
people.loadWalk(); people.loadWalk();
if (tpPos.x != -1 && !_vm->_talkToAbort) { if (tpPos.x != -1 && !talk._talkToAbort) {
// Teleport to ending coordinates // Teleport to ending coordinates
people[AL]._position = tpPos; people[AL]._position = tpPos;
people[AL]._sequenceNumber = tpDir; people[AL]._sequenceNumber = tpDir;
@ -997,6 +1004,51 @@ void Scene::printObjDesc(const Common::String &str, bool firstTime) {
* Animate all objects and people. * Animate all objects and people.
*/ */
void Scene::doBgAnim() { void Scene::doBgAnim() {
Events &events = *_vm->_events;
People &people = *_vm->_people;
Screen &screen = *_vm->_screen;
Sound &sound = *_vm->_sound;
Talk &talk = *_vm->_talk;
Surface surface = screen._backBuffer.getSubArea(Common::Rect(0, 0,
SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCENE_HEIGHT));
int cursorId = events.getCursor();
Common::Point mousePos = events.mousePos();
talk._talkToAbort = false;
// Animate the mouse cursor
if (cursorId >= WAIT) {
if (++cursorId > (WAIT + 2))
cursorId = WAIT;
events.setCursor((CursorId)cursorId);
}
// Check for setting magnifying glass cursor
if (_menuMode == INV_MODE || _menuMode == USE_MODE || _menuMode == GIVE_MODE) {
if (_invMode == INVMODE_1) {
// Only show Magnifying glass cursor if it's not on the inventory command line
if (mousePos.y < CONTROLS_Y || mousePos.y >(CONTROLS_Y1 + 13))
events.setCursor(MAGNIFY);
else
events.setCursor(ARROW);
} else {
events.setCursor(ARROW);
}
}
if (sound._diskSoundPlaying && !*sound._soundIsOn) {
// Loaded sound just finished playing
// TODO: This is horrible.. refactor into the Sound class
delete[] sound._digiBuf;
sound._diskSoundPlaying = false;
}
if (_restoreFlag) {
if (people[AL]._type == CHARACTER)
people[AL].checkSprite();
}
// TODO // TODO
} }

View file

@ -37,6 +37,30 @@ namespace Sherlock {
#define CONTROLS_Y 138 #define CONTROLS_Y 138
#define CONTROLS_Y1 151 #define CONTROLS_Y1 151
enum MenuMode {
STD_MODE = 0,
LOOK_MODE = 1,
MOVE_MODE = 2,
TALK_MODE = 3,
PICKUP_MODE = 4,
OPEN_MODE = 5,
CLOSE_MODE = 6,
INV_MODE = 7,
USE_MODE = 8,
GIVE_MODE = 9,
JOURNAL_MODE = 10,
FILES_MODE = 11,
SETUP_MODE = 12
};
enum InvMode {
INVMODE_0 = 0,
INVMODE_1 = 1,
INVMODE_2 = 2,
INVMODE_3 = 3,
INVMODE_255 = 255
};
class SherlockEngine; class SherlockEngine;
struct BgFileHeader { struct BgFileHeader {
@ -90,6 +114,8 @@ private:
Common::String _rrmName; Common::String _rrmName;
int _cAnimFramePause; int _cAnimFramePause;
Common::String _cAnimStr; Common::String _cAnimStr;
MenuMode _menuMode;
InvMode _invMode;
bool loadScene(const Common::String &filename); bool loadScene(const Common::String &filename);
@ -120,7 +146,7 @@ public:
ImageFile *_controls; ImageFile *_controls;
ImageFile *_controlPanel; ImageFile *_controlPanel;
bool _windowOpen, _infoFlag; bool _windowOpen, _infoFlag;
int _menuMode, _keyboardInput; int _keyboardInput;
int _oldKey, _help, _oldHelp; int _oldKey, _help, _oldHelp;
int _oldTemp, _temp; int _oldTemp, _temp;
bool _walkedInScene; bool _walkedInScene;
@ -143,6 +169,7 @@ public:
Common::Point _hsavedPos; Common::Point _hsavedPos;
int _hsavedFs; int _hsavedFs;
Common::Array<Object> _canimShapes; Common::Array<Object> _canimShapes;
bool _restoreFlag;
public: public:
Scene(SherlockEngine *vm); Scene(SherlockEngine *vm);
~Scene(); ~Scene();

View file

@ -181,7 +181,7 @@ bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, co
* Do a random pixel transition in from _backBuffer surface to the screen * Do a random pixel transition in from _backBuffer surface to the screen
*/ */
void Screen::randomTransition() { void Screen::randomTransition() {
EventsManager &events = *_vm->_events; Events &events = *_vm->_events;
const int TRANSITION_MULTIPLIER = 0x15a4e35; const int TRANSITION_MULTIPLIER = 0x15a4e35;
_dirtyRects.clear(); _dirtyRects.clear();
@ -210,7 +210,7 @@ void Screen::randomTransition() {
* Transition to the surface from _backBuffer using a vertical transition * Transition to the surface from _backBuffer using a vertical transition
*/ */
void Screen::verticalTransition() { void Screen::verticalTransition() {
EventsManager &events = *_vm->_events; Events &events = *_vm->_events;
byte table[SHERLOCK_SCREEN_WIDTH]; byte table[SHERLOCK_SCREEN_WIDTH];
Common::fill(&table[0], &table[SHERLOCK_SCREEN_WIDTH], 0); Common::fill(&table[0], &table[SHERLOCK_SCREEN_WIDTH], 0);

View file

@ -43,11 +43,9 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam
_talk = nullptr; _talk = nullptr;
_useEpilogue2 = false; _useEpilogue2 = false;
_justLoaded = false; _justLoaded = false;
_talkToAbort = false;
_onChessboard = false; _onChessboard = false;
_slowChess = false; _slowChess = false;
_animating = false; _animating = false;
_talkCounter = 0;
} }
SherlockEngine::~SherlockEngine() { SherlockEngine::~SherlockEngine() {
@ -75,14 +73,14 @@ void SherlockEngine::initialize() {
_res = new Resources(); _res = new Resources();
_animation = new Animation(this); _animation = new Animation(this);
_debugger = new Debugger(this); _debugger = new Debugger(this);
_events = new EventsManager(this); _events = new Events(this);
_inventory = new Inventory(); _inventory = new Inventory();
_journal = new Journal(); _journal = new Journal();
_people = new People(this); _people = new People(this);
_scene = new Scene(this); _scene = new Scene(this);
_screen = new Screen(this); _screen = new Screen(this);
_sound = new Sound(this); _sound = new Sound(this);
_talk = new Talk(); _talk = new Talk(this);
} }
Common::Error SherlockEngine::run() { Common::Error SherlockEngine::run() {

View file

@ -78,7 +78,7 @@ public:
const SherlockGameDescription *_gameDescription; const SherlockGameDescription *_gameDescription;
Animation *_animation; Animation *_animation;
Debugger *_debugger; Debugger *_debugger;
EventsManager *_events; Events *_events;
Inventory *_inventory; Inventory *_inventory;
Journal *_journal; Journal *_journal;
People *_people; People *_people;
@ -96,11 +96,9 @@ public:
int _oldCharPoint; // Old scene int _oldCharPoint; // Old scene
Common::Point _over; // Old map position Common::Point _over; // Old map position
Common::Array<Common::Point> _map; // Map locations for each scene Common::Array<Common::Point> _map; // Map locations for each scene
bool _talkToAbort;
bool _onChessboard; bool _onChessboard;
bool _slowChess; bool _slowChess;
bool _animating; bool _animating;
int _talkCounter;
public: public:
SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc); SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
virtual ~SherlockEngine(); virtual ~SherlockEngine();

View file

@ -31,6 +31,9 @@ Sound::Sound(SherlockEngine *vm): _vm(vm) {
_playingEpilogue = false; _playingEpilogue = false;
_music = false; _music = false;
_digitized = false; _digitized = false;
_diskSoundPlaying = false;
_soundIsOn = nullptr;
_digiBuf = nullptr;
} }
void Sound::loadSound(const Common::String &name, int priority) { void Sound::loadSound(const Common::String &name, int priority) {

View file

@ -44,6 +44,9 @@ public:
bool _playingEpilogue; bool _playingEpilogue;
bool _music; bool _music;
bool _digitized; bool _digitized;
bool _diskSoundPlaying;
byte *_soundIsOn;
byte *_digiBuf;
public: public:
Sound(SherlockEngine *vm); Sound(SherlockEngine *vm);

View file

@ -21,10 +21,17 @@
*/ */
#include "sherlock/talk.h" #include "sherlock/talk.h"
#include "sherlock/sherlock.h"
namespace Sherlock { namespace Sherlock {
Talk::Talk() { Talk::Talk(SherlockEngine *vm): _vm(vm) {
_talkCounter = 0;
_talkToAbort = false;
}
void Talk::talkTo(const Common::String &name) {
// TODO
} }
} // End of namespace Sherlock } // End of namespace Sherlock

View file

@ -37,11 +37,19 @@ public:
int &operator[](int idx) { return _data[idx]; } int &operator[](int idx) { return _data[idx]; }
}; };
class SherlockEngine;
class Talk { class Talk {
private:
SherlockEngine *_vm;
public: public:
Common::Array<TalkHistoryEntry> _history; Common::Array<TalkHistoryEntry> _history;
bool _talkToAbort;
int _talkCounter;
public: public:
Talk(); Talk(SherlockEngine *vm);
void talkTo(const Common::String &name);
}; };
} // End of namespace Sherlock } // End of namespace Sherlock