SHERLOCK: Implemented checkSprite
This commit is contained in:
parent
26c5168074
commit
7f04ea4425
17 changed files with 355 additions and 53 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue