SHERLOCK: Move method comments from cpp to headers

This commit is contained in:
Paul Gilbert 2015-05-19 07:37:55 -04:00
parent 0faf1c0b8f
commit 1df183ffcb
41 changed files with 1205 additions and 1071 deletions

View file

@ -31,9 +31,6 @@ static const int NO_FRAMES = FRAMES_END;
Animation::Animation(SherlockEngine *vm) : _vm(vm) {
}
/**
* Play a full-screen animation
*/
bool Animation::play(const Common::String &filename, int minDelay, int fade,
bool setPalette, int speed) {
Events &events = *_vm->_events;
@ -136,18 +133,12 @@ bool Animation::play(const Common::String &filename, int minDelay, int fade,
return !skipped && !_vm->shouldQuit();
}
/**
* Load the prologue name array
*/
void Animation::setPrologueNames(const char *const *names, int count) {
for (int idx = 0; idx < count; ++idx, ++names) {
_prologueNames.push_back(*names);
}
}
/**
* Load the prologue frame array
*/
void Animation::setPrologueFrames(const int *frames, int count, int maxFrames) {
_prologueFrames.resize(count);
@ -157,18 +148,12 @@ void Animation::setPrologueFrames(const int *frames, int count, int maxFrames) {
}
}
/**
* Load the title name array
*/
void Animation::setTitleNames(const char *const *names, int count) {
for (int idx = 0; idx < count; ++idx, ++names) {
_titleNames.push_back(*names);
}
}
/**
* Load the title frame array
*/
void Animation::setTitleFrames(const int *frames, int count, int maxFrames) {
_titleFrames.resize(count);
@ -178,9 +163,6 @@ void Animation::setTitleFrames(const int *frames, int count, int maxFrames) {
}
}
/**
* Checks for whether an animation is being played that has associated sound
*/
const int *Animation::checkForSoundFrames(const Common::String &filename) {
const int *frames = &NO_FRAMES;

View file

@ -39,10 +39,12 @@ private:
Common::Array<const char *> _prologueNames;
Common::Array<Common::Array<int> > _prologueFrames;
Common::Array<const char *> _titleNames;
Common::Array<Common::Array<int> > _titleFrames;
/**
* Checks for whether an animation is being played that has associated sound
*/
const int *checkForSoundFrames(const Common::String &filename);
public:
Common::String _soundLibraryFilename;
@ -50,12 +52,29 @@ public:
public:
Animation(SherlockEngine *vm);
/**
* Load the prologue name array
*/
void setPrologueNames(const char *const *names, int count);
/**
* Load the prologue frame array
*/
void setPrologueFrames(const int *frames, int count, int maxFrames);
/**
* Load the title name array
*/
void setTitleNames(const char *const *names, int count);
/**
* Load the title frame array
*/
void setTitleFrames(const int *frames, int count, int maxFrames);
/**
* Play a full-screen animation
*/
bool play(const Common::String &filename, int minDelay, int fade, bool setPalette, int speed);
};

View file

@ -30,9 +30,6 @@ Debugger::Debugger(SherlockEngine *vm) : GUI::Debugger(), _vm(vm) {
registerCmd("scene", WRAP_METHOD(Debugger, cmdScene));
}
/**
* Converts a decimal or hexadecimal string into a number
*/
int Debugger::strToInt(const char *s) {
if (!*s)
// No string at all
@ -49,9 +46,6 @@ int Debugger::strToInt(const char *s) {
return (int)tmp;
}
/**
* Switch to another scene
*/
bool Debugger::cmdScene(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Format: scene <room>\n");

View file

@ -34,8 +34,14 @@ class Debugger : public GUI::Debugger {
private:
SherlockEngine *_vm;
/**
* Converts a decimal or hexadecimal string into a number
*/
int strToInt(const char *s);
/**
* Switch to another scene
*/
bool cmdScene(int argc, const char **argv);
public:
Debugger(SherlockEngine *vm);

View file

@ -36,16 +36,10 @@ struct SherlockGameDescription {
GameType gameID;
};
/**
* Returns the Id of the game
*/
GameType SherlockEngine::getGameID() const {
return _gameDescription->gameID;
}
/**
* Returns the platform the game's datafiles are for
*/
Common::Platform SherlockEngine::getPlatform() const {
return _gameDescription->desc.platform;
}
@ -135,17 +129,37 @@ public:
return "Sherlock Engine (C) 1992-1996 Mythos Software, 1992-1996 (C) Electronic Arts";
}
/**
* Creates an instance of the game engine
*/
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
/**
* Returns a list of features the game's MetaEngine support
*/
virtual bool hasFeature(MetaEngineFeature f) const;
/**
* Return a list of savegames
*/
virtual SaveStateList listSaves(const char *target) const;
/**
* Returns the maximum number of allowed save slots
*/
virtual int getMaximumSaveSlot() const;
/**
* Deletes a savegame in the specified slot
*/
virtual void removeSaveState(const char *target, int slot) const;
/**
* Given a specified savegame slot, returns extended information for the save
*/
SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
};
/**
* Creates an instance of the game engine
*/
bool SherlockMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
const Sherlock::SherlockGameDescription *gd = (const Sherlock::SherlockGameDescription *)desc;
if (gd) {
@ -164,9 +178,6 @@ bool SherlockMetaEngine::createInstance(OSystem *syst, Engine **engine, const AD
return gd != 0;
}
/**
* Returns a list of features the game's MetaEngine support
*/
bool SherlockMetaEngine::hasFeature(MetaEngineFeature f) const {
return
(f == kSupportsListSaves) ||
@ -176,9 +187,6 @@ bool SherlockMetaEngine::hasFeature(MetaEngineFeature f) const {
(f == kSavesSupportThumbnail);
}
/**
* Returns a list of features the game itself supports
*/
bool Sherlock::SherlockEngine::hasFeature(EngineFeature f) const {
return
(f == kSupportsRTL) ||
@ -186,38 +194,23 @@ bool Sherlock::SherlockEngine::hasFeature(EngineFeature f) const {
(f == kSupportsSavingDuringRuntime);
}
/**
* Returns whether the version is a demo
*/
bool Sherlock::SherlockEngine::isDemo() const {
return _gameDescription->desc.flags & ADGF_DEMO;
}
/**
* Return a list of savegames
*/
SaveStateList SherlockMetaEngine::listSaves(const char *target) const {
return Sherlock::SaveManager::getSavegameList(target);
}
/**
* Returns the maximum number of allowed save slots
*/
int SherlockMetaEngine::getMaximumSaveSlot() const {
return MAX_SAVEGAME_SLOTS;
}
/**
* Deletes a savegame in the specified slot
*/
void SherlockMetaEngine::removeSaveState(const char *target, int slot) const {
Common::String filename = Sherlock::SaveManager(nullptr, target).generateSaveName(slot);
g_system->getSavefileManager()->removeSavefile(filename);
}
/**
* Given a specified savegame slot, returns extended information for the save
*/
SaveStateDescriptor SherlockMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
Common::String filename = Sherlock::SaveManager(nullptr, target).generateSaveName(slot);
Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename);

View file

@ -48,9 +48,6 @@ Events::~Events() {
delete _cursorImages;
}
/**
* Load a set of cursors from the specified file
*/
void Events::loadCursors(const Common::String &filename) {
hideCursor();
delete _cursorImages;
@ -59,9 +56,6 @@ void Events::loadCursors(const Common::String &filename) {
_cursorId = INVALID_CURSOR;
}
/**
* Set the cursor to show
*/
void Events::setCursor(CursorId cursorId) {
if (cursorId == _cursorId)
return;
@ -74,53 +68,31 @@ void Events::setCursor(CursorId cursorId) {
setCursor(s);
}
/**
* Set the cursor to show from a passed frame
*/
void Events::setCursor(const Graphics::Surface &src) {
CursorMan.replaceCursor(src.getPixels(), src.w, src.h, 0, 0, 0xff);
showCursor();
}
/**
* Show the mouse cursor
*/
void Events::showCursor() {
CursorMan.showMouse(true);
}
/**
* Hide the mouse cursor
*/
void Events::hideCursor() {
CursorMan.showMouse(false);
}
/**
* Returns the cursor
*/
CursorId Events::getCursor() const {
return _cursorId;
}
/**
* Returns true if the mouse cursor is visible
*/
bool Events::isCursorVisible() const {
return CursorMan.isVisible();
}
/**
* Move the mouse
*/
void Events::moveMouse(const Common::Point &pt) {
g_system->warpMouse(pt.x, pt.y);
}
/**
* Check for any pending events
*/
void Events::pollEvents() {
checkForNextFrameCounter();
@ -162,18 +134,11 @@ void Events::pollEvents() {
}
}
/**
* Poll for events and introduce a small delay, to allow the system to
* yield to other running programs
*/
void Events::pollEventsAndWait() {
pollEvents();
g_system->delayMillis(10);
}
/**
* Check whether it's time to display the next screen frame
*/
bool Events::checkForNextFrameCounter() {
// Check for next game frame
uint32 milli = g_system->getMillis();
@ -193,23 +158,14 @@ bool Events::checkForNextFrameCounter() {
return false;
}
/**
* Get the current mouse position
*/
Common::Point Events::mousePos() const {
return g_system->getEventManager()->getMousePos();
}
/**
* Get a pending keypress
*/
Common::KeyState Events::getKey() {
return _pendingKeys.pop();
}
/**
* Clear any current keypress or mouse click
*/
void Events::clearEvents() {
_pendingKeys.clear();
_mouseButtons = 0;
@ -218,24 +174,15 @@ void Events::clearEvents() {
_oldButtons = _oldRightButton = false;
}
/**
* Clear any pending keyboard inputs
*/
void Events::clearKeyboard() {
_pendingKeys.clear();
}
/**
* Delay for a given number of game frames, where each frame is 1/60th of a second
*/
void Events::wait(int numFrames) {
uint32 totalMilli = numFrames * 1000 / GAME_FRAME_RATE;
delay(totalMilli);
}
/**
* Does a delay of the specified number of milliseconds
*/
bool Events::delay(uint32 time, bool interruptable) {
// Different handling for really short versus extended times
if (time < 10) {
@ -265,12 +212,6 @@ bool Events::delay(uint32 time, bool interruptable) {
}
}
/**
* Sets the pressed and released button flags on the raw button state previously set in pollEvents calls.
* @remarks The events manager has separate variables for the raw immediate and old button state
* versus the current buttons states for the frame. This method is expected to be called only once
* per game frame
*/
void Events::setButtonState() {
_released = _rightReleased = false;
if (_mouseButtons & 1)
@ -290,9 +231,6 @@ void Events::setButtonState() {
}
}
/**
* Checks to see to see if a key or a mouse button is pressed.
*/
bool Events::checkInput() {
setButtonState();
return kbHit() || _pressed || _released || _rightPressed || _rightReleased;

View file

@ -45,6 +45,9 @@ private:
ImageFile *_cursorImages;
int _mouseButtons;
/**
* Check whether it's time to display the next screen frame
*/
bool checkForNextFrameCounter();
public:
CursorId _cursorId;
@ -59,42 +62,102 @@ public:
Events(SherlockEngine *vm);
~Events();
/**
* Load a set of cursors from the specified file
*/
void loadCursors(const Common::String &filename);
/**
* Set the cursor to show
*/
void setCursor(CursorId cursorId);
/**
* Set the cursor to show from a passed frame
*/
void setCursor(const Graphics::Surface &src);
/**
* Show the mouse cursor
*/
void showCursor();
/**
* Hide the mouse cursor
*/
void hideCursor();
/**
* Returns the cursor
*/
CursorId getCursor() const;
/**
* Returns true if the mouse cursor is visible
*/
bool isCursorVisible() const;
/**
* Move the mouse
*/
void moveMouse(const Common::Point &pt);
/**
* Check for any pending events
*/
void pollEvents();
/**
* Poll for events and introduce a small delay, to allow the system to
* yield to other running programs
*/
void pollEventsAndWait();
/**
* Get the current mouse position
*/
Common::Point mousePos() const;
uint32 getFrameCounter() const { return _frameCounter; }
bool kbHit() const { return !_pendingKeys.empty(); }
/**
* Get a pending keypress
*/
Common::KeyState getKey();
/**
* Clear any current keypress or mouse click
*/
void clearEvents();
/**
* Clear any pending keyboard inputs
*/
void clearKeyboard();
/**
* Delay for a given number of game frames, where each frame is 1/60th of a second
*/
void wait(int numFrames);
/**
* Does a delay of the specified number of milliseconds
*/
bool delay(uint32 time, bool interruptable = false);
/**
* Sets the pressed and released button flags on the raw button state previously set in pollEvents calls.
* @remarks The events manager has separate variables for the raw immediate and old button state
* versus the current buttons states for the frame. This method is expected to be called only once
* per game frame
*/
void setButtonState();
/**
* Checks to see to see if a key or a mouse button is pressed.
*/
bool checkInput();
};

View file

@ -31,9 +31,6 @@ InventoryItem::InventoryItem(int requiredFlag, const Common::String &name,
_examine(examine), _lookFlag(0) {
}
/**
* Synchronize the data for an inventory item
*/
void InventoryItem::synchronize(Common::Serializer &s) {
s.syncAsSint16LE(_requiredFlag);
s.syncAsSint16LE(_lookFlag);
@ -56,9 +53,6 @@ Inventory::~Inventory() {
freeGraphics();
}
/**
* Free inventory data
*/
void Inventory::freeInv() {
freeGraphics();
@ -66,9 +60,6 @@ void Inventory::freeInv() {
_invGraphicsLoaded = false;
}
/**
* Free any loaded inventory graphics
*/
void Inventory::freeGraphics() {
for (uint idx = 0; idx < MAX_VISIBLE_INVENTORY; ++idx)
delete _invShapes[idx];
@ -77,10 +68,6 @@ void Inventory::freeGraphics() {
_invGraphicsLoaded = false;
}
/**
* Load the list of names the inventory items correspond to, if not already loaded,
* and then calls loadGraphics to load the associated graphics
*/
void Inventory::loadInv() {
// Exit if the inventory names are already loaded
if (_names.size() > 0)
@ -104,9 +91,6 @@ void Inventory::loadInv() {
loadGraphics();
}
/**
* Load the list of names of graphics for the inventory
*/
void Inventory::loadGraphics() {
if (_invGraphicsLoaded)
return;
@ -126,10 +110,6 @@ void Inventory::loadGraphics() {
_invGraphicsLoaded = true;
}
/**
* Searches through the list of names that correspond to the inventory items
* and returns the number that matches the passed name
*/
int Inventory::findInv(const Common::String &name) {
for (int idx = 0; idx < (int)_names.size(); ++idx) {
if (name.equalsIgnoreCase(_names[idx]))
@ -140,9 +120,6 @@ int Inventory::findInv(const Common::String &name) {
error("Couldn't find inventory item - %s", name.c_str());
}
/**
* Display the character's inventory. The slamIt parameter specifies:
*/
void Inventory::putInv(InvSlamMode slamIt) {
Screen &screen = *_vm->_screen;
UserInterface &ui = *_vm->_ui;
@ -198,9 +175,6 @@ void Inventory::putInv(InvSlamMode slamIt) {
}
}
/**
* Put the game into inventory mode and open the interface window.
*/
void Inventory::drawInventory(InvNewMode mode) {
Screen &screen = *_vm->_screen;
UserInterface &ui = *_vm->_ui;
@ -270,10 +244,6 @@ void Inventory::drawInventory(InvNewMode mode) {
ui._oldUse = -1;
}
/**
* Prints the line of inventory commands at the top of an inventory window with
* the correct highlighting
*/
void Inventory::invCommands(bool slamIt) {
Screen &screen = *_vm->_screen;
UserInterface &ui = *_vm->_ui;
@ -333,9 +303,6 @@ void Inventory::invCommands(bool slamIt) {
}
}
/**
* Set the highlighting color of a given inventory item
*/
void Inventory::highlight(int index, byte color) {
Screen &screen = *_vm->_screen;
Surface &bb = *screen._backBuffer;
@ -348,9 +315,6 @@ void Inventory::highlight(int index, byte color) {
screen.slamArea(8 + slot * 52, 165, 44, 30);
}
/**
* Support method for refreshing the display of the inventory
*/
void Inventory::refreshInv() {
Screen &screen = *_vm->_screen;
Talk &talk = *_vm->_talk;
@ -373,9 +337,6 @@ void Inventory::refreshInv() {
}
}
/**
* Adds a shape from the scene to the player's inventory
*/
int Inventory::putNameInInventory(const Common::String &name) {
Scene &scene = *_vm->_scene;
int matches = 0;
@ -391,10 +352,6 @@ int Inventory::putNameInInventory(const Common::String &name) {
return matches;
}
/**
* Moves a specified item into the player's inventory If the item has a *PICKUP* use action,
* then the item in the use action are added to the inventory.
*/
int Inventory::putItemInInventory(Object &obj) {
Scene &scene = *_vm->_scene;
int matches = 0;
@ -456,9 +413,6 @@ int Inventory::putItemInInventory(Object &obj) {
return matches;
}
/**
* Copy the passed object into the inventory
*/
void Inventory::copyToInventory(Object &obj) {
InventoryItem invItem;
invItem._name = obj._name;
@ -471,9 +425,6 @@ void Inventory::copyToInventory(Object &obj) {
++_holdings;
}
/**
* Deletes a specified item from the player's inventory
*/
int Inventory::deleteItemFromInventory(const Common::String &name) {
int invNum = -1;
@ -493,9 +444,6 @@ int Inventory::deleteItemFromInventory(const Common::String &name) {
return 1;
}
/**
* Synchronize the data for a savegame
*/
void Inventory::synchronize(Common::Serializer &s) {
s.syncAsSint16LE(_holdings);

View file

@ -66,6 +66,9 @@ struct InventoryItem {
InventoryItem(int requiredFlag, const Common::String &name,
const Common::String &description, const Common::String &examine);
/**
* Synchronize the data for an inventory item
*/
void synchronize(Common::Serializer &s);
};
@ -74,6 +77,9 @@ private:
SherlockEngine *_vm;
Common::StringArray _names;
/**
* Copy the passed object into the inventory
*/
void copyToInventory(Object &obj);
public:
ImageFile *_invShapes[MAX_VISIBLE_INVENTORY];
@ -82,34 +88,81 @@ public:
int _invIndex;
int _holdings; // Used to hold number of visible items in active inventory.
// Since Inventory array also contains some special hidden items
/**
* Free any loaded inventory graphics
*/
void freeGraphics();
public:
Inventory(SherlockEngine *vm);
~Inventory();
/**
* Free inventory data
*/
void freeInv();
/**
* Load the list of names the inventory items correspond to, if not already loaded,
* and then calls loadGraphics to load the associated graphics
*/
void loadInv();
/**
* Load the list of names of graphics for the inventory
*/
void loadGraphics();
/**
* Searches through the list of names that correspond to the inventory items
* and returns the number that matches the passed name
*/
int findInv(const Common::String &name);
/**
* Display the character's inventory. The slamIt parameter specifies:
*/
void putInv(InvSlamMode slamIt);
/**
* Put the game into inventory mode and open the interface window.
*/
void drawInventory(InvNewMode flag);
/**
* Prints the line of inventory commands at the top of an inventory window with
* the correct highlighting
*/
void invCommands(bool slamIt);
/**
* Set the highlighting color of a given inventory item
*/
void highlight(int index, byte color);
/**
* Support method for refreshing the display of the inventory
*/
void refreshInv();
/**
* Adds a shape from the scene to the player's inventory
*/
int putNameInInventory(const Common::String &name);
/**
* Moves a specified item into the player's inventory If the item has a *PICKUP* use action,
* then the item in the use action are added to the inventory.
*/
int putItemInInventory(Object &obj);
/**
* Deletes a specified item from the player's inventory
*/
int deleteItemFromInventory(const Common::String &name);
/**
* Synchronize the data for a savegame
*/
void synchronize(Common::Serializer &s);
};

View file

@ -67,10 +67,6 @@ Journal::Journal(SherlockEngine *vm) : _vm(vm) {
}
}
/**
* Records statements that are said, in the order which they are said. The player
* can then read the journal to review them
*/
void Journal::record(int converseNum, int statementNum, bool replyOnly) {
int saveIndex = _index;
int saveSub = _sub;
@ -96,9 +92,6 @@ void Journal::record(int converseNum, int statementNum, bool replyOnly) {
}
}
/**
* Load the list of location names that the journal will make reference to
*/
void Journal::loadJournalLocations() {
Resources &res = *_vm->_res;
@ -137,12 +130,6 @@ void Journal::loadJournalLocations() {
delete loc;
}
/**
* Loads the description for the current display index in the journal, and then
* word wraps the result to prepare it for being displayed
* @param alreadyLoaded Indicates whether the journal file is being loaded for the
* first time, or being reloaded
*/
void Journal::loadJournalFile(bool alreadyLoaded) {
Screen &screen = *_vm->_screen;
Talk &talk = *_vm->_talk;
@ -459,9 +446,6 @@ void Journal::loadJournalFile(bool alreadyLoaded) {
}
}
/**
* Draw the journal background, frame, and interface buttons
*/
void Journal::drawJournalFrame() {
Resources &res = *_vm->_res;
Screen &screen = *_vm->_screen;
@ -516,9 +500,6 @@ void Journal::drawJournalFrame() {
COMMAND_NULL, false, "Print Text");
}
/**
* Display the journal
*/
void Journal::drawInterface() {
Screen &screen = *_vm->_screen;
@ -536,9 +517,6 @@ void Journal::drawInterface() {
screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
}
/**
* Display the arrows that can be used to scroll up and down pages
*/
void Journal::doArrows() {
Screen &screen = *_vm->_screen;
byte color;
@ -560,9 +538,6 @@ void Journal::doArrows() {
screen.buttonPrint(Common::Point(JOURNAL_POINTS[6][2], JOURNAL_BUTTONS_Y + 11), color, false, "First Page");
}
/**
* Displays a page of the journal at the current index
*/
bool Journal::drawJournal(int direction, int howFar) {
Events &events = *_vm->_events;
Screen &screen = *_vm->_screen;
@ -808,9 +783,6 @@ bool Journal::drawJournal(int direction, int howFar) {
return direction >= 3 && searchSuccessful;
}
/**
* Returns the button, if any, that is under the specified position
*/
JournalButton Journal::getHighlightedButton(const Common::Point &pt) {
if (pt.x > JOURNAL_POINTS[0][0] && pt.x < JOURNAL_POINTS[0][1] && pt.y >= JOURNAL_BUTTONS_Y &&
pt.y < (JOURNAL_BUTTONS_Y + 10))
@ -851,9 +823,6 @@ JournalButton Journal::getHighlightedButton(const Common::Point &pt) {
return BTN_NONE;
}
/**
* Handle events whilst the journal is being displayed
*/
bool Journal::handleEvents(int key) {
Events &events = *_vm->_events;
Screen &screen = *_vm->_screen;
@ -1024,9 +993,6 @@ bool Journal::handleEvents(int key) {
return doneFlag;
}
/**
* Show the search submenu and allow the player to enter a search string
*/
int Journal::getSearchString(bool printError) {
enum Button { BTN_NONE, BTN_EXIT, BTN_BACKWARD, BTN_FORWARD };
@ -1193,17 +1159,11 @@ int Journal::getSearchString(bool printError) {
return done;
}
/**
* Reset viewing position to the start of the journal
*/
void Journal::resetPosition() {
_index = _sub = _up = _down = 0;
_page = 1;
}
/**
* Synchronize the data for a savegame
*/
void Journal::synchronize(Common::Serializer &s) {
s.syncAsSint16LE(_index);
s.syncAsSint16LE(_sub);

View file

@ -67,30 +67,70 @@ private:
int _page;
Common::String _find;
/**
* Load the list of location names that the journal will make reference to
*/
void loadJournalLocations();
/**
* Loads the description for the current display index in the journal, and then
* word wraps the result to prepare it for being displayed
* @param alreadyLoaded Indicates whether the journal file is being loaded for the
* first time, or being reloaded
*/
void loadJournalFile(bool alreadyLoaded);
/**
* Display the arrows that can be used to scroll up and down pages
*/
void doArrows();
/**
* Displays a page of the journal at the current index
*/
bool drawJournal(int direction, int howFar);
/**
* Show the search submenu and allow the player to enter a search string
*/
int getSearchString(bool printError);
/**
* Draw the journal background, frame, and interface buttons
*/
void drawJournalFrame();
/**
* Returns the button, if any, that is under the specified position
*/
JournalButton getHighlightedButton(const Common::Point &pt);
public:
Journal(SherlockEngine *vm);
/**
* Records statements that are said, in the order which they are said. The player
* can then read the journal to review them
*/
void record(int converseNum, int statementNum, bool replyOnly = false);
/**
* Display the journal
*/
void drawInterface();
/**
* Handle events whilst the journal is being displayed
*/
bool handleEvents(int key);
/**
* Reset viewing position to the start of the journal
*/
void resetPosition();
/**
* Synchronize the data for a savegame
*/
void synchronize(Common::Serializer &s);
};

View file

@ -25,9 +25,6 @@
namespace Sherlock {
/**
* Load the data for the paths between locations on the map
*/
void MapPaths::load(int numLocations, Common::SeekableReadStream &s) {
_numLocations = numLocations;
_paths.resize(_numLocations * _numLocations);
@ -43,9 +40,6 @@ void MapPaths::load(int numLocations, Common::SeekableReadStream &s) {
}
}
/**
* Get the path between two locations on the map
*/
const byte *MapPaths::getPath(int srcLocation, int destLocation) {
return &_paths[srcLocation * _numLocations + destLocation][0];
}
@ -73,26 +67,17 @@ Map::Map(SherlockEngine *vm) : _vm(vm), _topLine(SHERLOCK_SCREEN_WIDTH, 12) {
loadData();
}
/**
* Loads the list of points for locations on the map for each scene
*/
void Map::loadPoints(int count, const int *xList, const int *yList, const int *transList) {
for (int idx = 0; idx < count; ++idx, ++xList, ++yList, ++transList) {
_points.push_back(MapEntry(*xList, *yList, *transList));
}
}
/**
* Load the sequence data for player icon animations
*/
void Map::loadSequences(int count, const byte *seq) {
for (int idx = 0; idx < count; ++idx, seq += MAX_FRAME)
Common::copy(seq, seq + MAX_FRAME, &_sequences[idx][0]);
}
/**
* Load data needed for the map
*/
void Map::loadData() {
// Load the list of location names
Common::SeekableReadStream *txtStream = _vm->_res->load("chess.txt");
@ -125,9 +110,6 @@ void Map::loadData() {
delete pathStream;
}
/**
* Show the map
*/
int Map::show() {
Events &events = *_vm->_events;
People &people = *_vm->_people;
@ -279,9 +261,6 @@ int Map::show() {
return _charPoint;
}
/**
* Load and initialize all the sprites that are needed for the map display
*/
void Map::setupSprites() {
Events &events = *_vm->_events;
People &people = *_vm->_people;
@ -318,9 +297,6 @@ void Map::setupSprites() {
scene._bgShapes.clear();
}
/**
* Free the sprites and data used by the map
*/
void Map::freeSprites() {
delete _mapCursors;
delete _shapes;
@ -328,9 +304,6 @@ void Map::freeSprites() {
_iconSave.free();
}
/**
* Draws an icon for every place that's currently known
*/
void Map::showPlaces() {
Screen &screen = *_vm->_screen;
@ -349,25 +322,16 @@ void Map::showPlaces() {
}
}
/**
* Makes a copy of the top rows of the screen that are used to display location names
*/
void Map::saveTopLine() {
_topLine.blitFrom(_vm->_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, 12));
}
/**
* Erases anything shown in the top line by restoring the previously saved original map background
*/
void Map::eraseTopLine() {
Screen &screen = *_vm->_screen;
screen._backBuffer1.blitFrom(_topLine, Common::Point(0, 0));
screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, _topLine.h);
}
/**
* Prints the name of the specified icon
*/
void Map::showPlaceName(int idx, bool highlighted) {
People &people = *_vm->_people;
Screen &screen = *_vm->_screen;
@ -393,9 +357,6 @@ void Map::showPlaceName(int idx, bool highlighted) {
}
}
/**
* Update all on-screen sprites to account for any scrolling of the map
*/
void Map::updateMap(bool flushScreen) {
Events &events = *_vm->_events;
People &people = *_vm->_people;
@ -442,9 +403,6 @@ void Map::updateMap(bool flushScreen) {
}
}
/**
* Handle moving icon for player from their previous location on the map to a destination location
*/
void Map::walkTheStreets() {
People &people = *_vm->_people;
Common::Array<Common::Point> tempPath;
@ -503,9 +461,6 @@ void Map::walkTheStreets() {
people._walkTo.push(destPos);
}
/**
* Save the area under the player's icon
*/
void Map::saveIcon(ImageFrame *src, const Common::Point &pt) {
Screen &screen = *_vm->_screen;
Common::Point size(src->_width, src->_height);
@ -540,9 +495,6 @@ void Map::saveIcon(ImageFrame *src, const Common::Point &pt) {
_savedSize = size;
}
/**
* Restore the area under the player's icon
*/
void Map::restoreIcon() {
Screen &screen = *_vm->_screen;
@ -551,9 +503,6 @@ void Map::restoreIcon() {
screen._backBuffer1.blitFrom(_iconSave, _savedPos, Common::Rect(0, 0, _savedSize.x, _savedSize.y));
}
/**
* Handles highlighting map icons, showing their names
*/
void Map::highlightIcon(const Common::Point &pt) {
int oldPoint = _point;
@ -592,9 +541,6 @@ void Map::highlightIcon(const Common::Point &pt) {
}
}
/**
* Synchronize the data for a savegame
*/
void Map::synchronize(Common::Serializer &s) {
s.syncAsSint16LE(_bigPos.x);
s.syncAsSint16LE(_bigPos.y);

View file

@ -49,8 +49,14 @@ private:
int _numLocations;
Common::Array< Common::Array<byte> > _paths;
public:
/**
* Load the data for the paths between locations on the map
*/
void load(int numLocations, Common::SeekableReadStream &s);
/**
* Get the path between two locations on the map
*/
const byte *getPath(int srcLocation, int destLocation);
};
@ -75,24 +81,64 @@ private:
bool _drawMap;
Surface _iconSave;
private:
/**
* Load data needed for the map
*/
void loadData();
/**
* Load and initialize all the sprites that are needed for the map display
*/
void setupSprites();
/**
* Free the sprites and data used by the map
*/
void freeSprites();
/**
* Draws an icon for every place that's currently known
*/
void showPlaces();
/**
* Makes a copy of the top rows of the screen that are used to display location names
*/
void saveTopLine();
/**
* Erases anything shown in the top line by restoring the previously saved original map background
*/
void eraseTopLine();
/**
* Prints the name of the specified icon
*/
void showPlaceName(int idx, bool highlighted);
/**
* Update all on-screen sprites to account for any scrolling of the map
*/
void updateMap(bool flushScreen);
/**
* Handle moving icon for player from their previous location on the map to a destination location
*/
void walkTheStreets();
/**
* Save the area under the player's icon
*/
void saveIcon(ImageFrame *src, const Common::Point &pt);
/**
* Restore the area under the player's icon
*/
void restoreIcon();
/**
* Handles highlighting map icons, showing their names
*/
void highlightIcon(const Common::Point &pt);
public:
bool _active;
@ -105,11 +151,24 @@ public:
const MapEntry &operator[](int idx) { return _points[idx]; }
/**
* Loads the list of points for locations on the map for each scene
*/
void loadPoints(int count, const int *xList, const int *yList, const int *transList);
/**
* Load the sequence data for player icon animations
*/
void loadSequences(int count, const byte *seq);
/**
* Show the map
*/
int show();
/**
* Synchronize the data for a savegame
*/
void synchronize(Common::Serializer &s);
};

View file

@ -41,9 +41,6 @@ namespace Sherlock {
SherlockEngine *Sprite::_vm;
/**
* Reset the data for the sprite
*/
void Sprite::clear() {
_name = "";
_description = "";
@ -68,18 +65,12 @@ void Sprite::clear() {
_numFrames = 0;
}
/**
* Updates the image frame poiner for the sprite
*/
void Sprite::setImageFrame() {
int imageNumber = (*_sequences)[_sequenceNumber][_frameNumber] +
(*_sequences)[_sequenceNumber][0] - 2;
_imageFrame = &(*_images)[imageNumber];
}
/**
* This adjusts the sprites position, as well as it's animation sequence:
*/
void Sprite::adjustSprite() {
Map &map = *_vm->_map;
People &people = *_vm->_people;
@ -175,9 +166,6 @@ 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;
@ -364,9 +352,6 @@ void Sprite::checkSprite() {
/*----------------------------------------------------------------*/
/**
* Load the data for the action
*/
void ActionType::load(Common::SeekableReadStream &s) {
char buffer[12];
@ -388,9 +373,6 @@ UseType::UseType() {
_useFlag = 0;
}
/**
* Load the data for the UseType
*/
void UseType::load(Common::SeekableReadStream &s) {
char buffer[12];
@ -454,9 +436,6 @@ Object::Object() {
_seqSize = 0;
}
/**
* Load the data for the object
*/
void Object::load(Common::SeekableReadStream &s) {
char buffer[41];
s.read(buffer, 12);
@ -522,9 +501,6 @@ void Object::load(Common::SeekableReadStream &s) {
_use[idx].load(s);
}
/**
* Toggle the type of an object between hidden and active
*/
void Object::toggleHidden() {
if (_type != HIDDEN && _type != HIDE_SHAPE && _type != INVALID) {
if (_seqTo != 0)
@ -560,9 +536,6 @@ void Object::toggleHidden() {
}
}
/**
* Check the state of the object
*/
void Object::checkObject() {
Scene &scene = *_vm->_scene;
Sound &sound = *_vm->_sound;
@ -686,11 +659,6 @@ void Object::checkObject() {
} while (codeFound);
}
/**
* 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 Object::checkEndOfSequence() {
Screen &screen = *_vm->_screen;
int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
@ -743,10 +711,6 @@ bool Object::checkEndOfSequence() {
return result;
}
/**
* Scans through the sequences array and finds the designated sequence.
* It then sets the frame number of the start of that sequence
*/
void Object::setObjSequence(int seq, bool wait) {
Scene &scene = *_vm->_scene;
int checkFrame = _allow ? MAX_FRAME : FRAMES_END;
@ -820,12 +784,6 @@ void Object::setObjSequence(int seq, bool wait) {
}
}
/**
* 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 Object::checkNameForCodes(const Common::String &name, const char *const messages[]) {
Map &map = *_vm->_map;
People &people = *_vm->_people;
@ -921,9 +879,6 @@ int Object::checkNameForCodes(const Common::String &name, const char *const mess
return printed;
}
/**
* Handle setting any flags associated with the object
*/
void Object::setFlagsAndToggles() {
Scene &scene = *_vm->_scene;
Talk &talk = *_vm->_talk;
@ -949,10 +904,6 @@ void Object::setFlagsAndToggles() {
}
}
/**
* Adjusts the sprite's position and animation sequence, advancing by 1 frame.
* If the end of the sequence is reached, the appropriate action is taken.
*/
void Object::adjustObject() {
if (_type == REMOVE)
return;
@ -975,10 +926,6 @@ void Object::adjustObject() {
}
}
/**
* Handles trying to pick up an object. If allowed, plays an y necessary animation for picking
* up the item, and then adds it to the player's inventory
*/
int Object::pickUpObject(const char *const messages[]) {
Inventory &inv = *_vm->_inventory;
People &people = *_vm->_people;
@ -1065,9 +1012,6 @@ int Object::pickUpObject(const char *const messages[]) {
return numObjects;
}
/**
* Returns the current bounds for the sprite
*/
const Common::Rect Object::getNewBounds() const {
Common::Point pt = _position;
if (_imageFrame)
@ -1076,17 +1020,11 @@ const Common::Rect Object::getNewBounds() const {
return Common::Rect(pt.x, pt.y, pt.x + frameWidth(), pt.y + frameHeight());
}
/**
* Returns the bounds for a sprite without a shape
*/
const Common::Rect Object::getNoShapeBounds() const {
return Common::Rect(_position.x, _position.y,
_position.x + _noShapeSize.x, _position.y + _noShapeSize.y);
}
/**
* Returns the old bounsd for the sprite from the previous frame
*/
const Common::Rect Object::getOldBounds() const {
return Common::Rect(_oldPosition.x, _oldPosition.y,
_oldPosition.x + _oldSize.x, _oldPosition.y + _oldSize.y);
@ -1094,9 +1032,6 @@ const Common::Rect Object::getOldBounds() const {
/*----------------------------------------------------------------*/
/**
* Load the data for the animation
*/
void CAnim::load(Common::SeekableReadStream &s) {
char buffer[12];
s.read(buffer, 12);

View file

@ -129,15 +129,34 @@ public:
Sprite() { clear(); }
static void setVm(SherlockEngine *vm) { _vm = vm; }
/**
* Reset the data for the sprite
*/
void clear();
/**
* Updates the image frame poiner for the sprite
*/
void setImageFrame();
/**
* This adjusts the sprites position, as well as it's animation sequence:
*/
void adjustSprite();
/**
* Checks the sprite's position to see if it's collided with any special objects
*/
void checkSprite();
/**
* Return frame width
*/
int frameWidth() const { return _imageFrame ? _imageFrame->_frame.w : 0; }
/**
* Return frame height
*/
int frameHeight() const { return _imageFrame ? _imageFrame->_frame.h : 0; }
};
@ -149,6 +168,9 @@ struct ActionType {
int _cAnimSpeed;
Common::String _names[NAMES_COUNT];
/**
* Load the data for the action
*/
void load(Common::SeekableReadStream &s);
};
@ -160,6 +182,10 @@ struct UseType {
Common::String _target;
UseType();
/**
* Load the data for the UseType
*/
void load(Common::SeekableReadStream &s);
};
@ -170,8 +196,17 @@ class Object {
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;
@ -224,24 +259,69 @@ public:
Object();
/**
* Load the data for the object
*/
void load(Common::SeekableReadStream &s);
/**
* Toggle the type of an object between hidden and active
*/
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();
/**
* Adjusts the sprite's position and animation sequence, advancing by 1 frame.
* If the end of the sequence is reached, the appropriate action is taken.
*/
void adjustObject();
/**
* Handles trying to pick up an object. If allowed, plays an y necessary animation for picking
* up the item, and then adds it to the player's inventory
*/
int pickUpObject(const char *const messages[]);
/**
* Return the frame width
*/
int frameWidth() const { return _imageFrame ? _imageFrame->_frame.w : 0; }
/**
* Return the frame height
*/
int frameHeight() const { return _imageFrame ? _imageFrame->_frame.h : 0; }
/**
* Returns the current bounds for the sprite
*/
const Common::Rect getNewBounds() const;
/**
* Returns the bounds for a sprite without a shape
*/
const Common::Rect getNoShapeBounds() const;
/**
* Returns the old bounsd for the sprite from the previous frame
*/
const Common::Rect getOldBounds() const;
};
@ -257,6 +337,9 @@ struct CAnim {
Common::Point _teleportPos; // Location Holmes shoul teleport to after
int _teleportDir; // playing canim
/**
* Load the data for the animation
*/
void load(Common::SeekableReadStream &s);
};

View file

@ -217,9 +217,6 @@ People::~People() {
delete[] _portrait._sequences;
}
/**
* Reset the player data
*/
void People::reset() {
// Note: The engine has theoretical support for two player characters but only the first one is used.
// Watson is, instead, handled by a different sprite in each scene, with a very simple initial movement, if any
@ -247,9 +244,6 @@ void People::reset() {
_walkTo.clear();
}
/**
* Load the walking images for Sherlock
*/
bool People::loadWalk() {
if (_walkLoaded) {
return false;
@ -262,9 +256,6 @@ bool People::loadWalk() {
}
}
/**
* If the walk data has been loaded, then it will be freed
*/
bool People::freeWalk() {
if (_walkLoaded) {
delete _player._images;
@ -277,11 +268,6 @@ bool People::freeWalk() {
}
}
/**
* Set the variables for moving a character from one poisition to another
* in a straight line - goAllTheWay must have been previously called to
* check for any obstacles in the path.
*/
void People::setWalking() {
Map &map = *_vm->_map;
Scene &scene = *_vm->_scene;
@ -427,10 +413,6 @@ void People::setWalking() {
_player._frameNumber = oldFrame;
}
/**
* Bring a moving character to a standing position. If the Scalpel chessboard
* is being displayed, then the chraracter will always face down.
*/
void People::gotoStand(Sprite &sprite) {
Map &map = *_vm->_map;
_walkTo.clear();
@ -481,9 +463,6 @@ void People::gotoStand(Sprite &sprite) {
_allowWalkAbort = true;
}
/**
* Walk to the co-ordinates passed, and then face the given direction
*/
void People::walkToCoords(const Common::Point &destPos, int destDir) {
Events &events = *_vm->_events;
Scene &scene = *_vm->_scene;
@ -516,11 +495,6 @@ void People::walkToCoords(const Common::Point &destPos, int destDir) {
}
}
/**
* Called to set the character walking to the current cursor location.
* It uses the zones and the inter-zone points to determine a series
* of steps to walk to get to that position.
*/
void People::goAllTheWay() {
Scene &scene = *_vm->_scene;
Common::Point srcPt(_player._position.x / 100 + _player.frameWidth() / 2,
@ -608,9 +582,6 @@ void People::goAllTheWay() {
}
}
/**
* Finds the scene background object corresponding to a specified speaker
*/
int People::findSpeaker(int speaker) {
Scene &scene = *_vm->_scene;
@ -629,9 +600,6 @@ int People::findSpeaker(int speaker) {
return -1;
}
/**
* Turn off any currently active portraits, and removes them from being drawn
*/
void People::clearTalking() {
Scene &scene = *_vm->_scene;
Screen &screen = *_vm->_screen;
@ -662,9 +630,6 @@ void People::clearTalking() {
}
}
/**
* Setup the data for an animating speaker portrait at the top of the screen
*/
void People::setTalking(int speaker) {
Resources &res = *_vm->_res;
@ -724,9 +689,6 @@ void People::setTalking(int speaker) {
}
}
/**
* Synchronize the data for a savegame
*/
void People::synchronize(Common::Serializer &s) {
s.syncAsByte(_holmesOn);
s.syncAsSint16LE(_player._position.x);

View file

@ -102,27 +102,69 @@ public:
return _data[idx];
}
/**
* Returns true if Sherlock is visible on the screen and enabled
*/
bool isHolmesActive() const { return _walkLoaded && _holmesOn; }
/**
* Reset the player data
*/
void reset();
/**
* Load the walking images for Sherlock
*/
bool loadWalk();
/**
* If the walk data has been loaded, then it will be freed
*/
bool freeWalk();
/**
* Set the variables for moving a character from one poisition to another
* in a straight line - goAllTheWay must have been previously called to
* check for any obstacles in the path.
*/
void setWalking();
/**
* Bring a moving character to a standing position. If the Scalpel chessboard
* is being displayed, then the chraracter will always face down.
*/
void gotoStand(Sprite &sprite);
/**
* Walk to the co-ordinates passed, and then face the given direction
*/
void walkToCoords(const Common::Point &destPos, int destDir);
/**
* Called to set the character walking to the current cursor location.
* It uses the zones and the inter-zone points to determine a series
* of steps to walk to get to that position.
*/
void goAllTheWay();
/**
* Finds the scene background object corresponding to a specified speaker
*/
int findSpeaker(int speaker);
/**
* Turn off any currently active portraits, and removes them from being drawn
*/
void clearTalking();
/**
* Setup the data for an animating speaker portrait at the top of the screen
*/
void setTalking(int speaker);
/**
* Synchronize the data for a savegame
*/
void synchronize(Common::Serializer &s);
};

View file

@ -31,18 +31,10 @@ namespace Sherlock {
Cache::Cache(SherlockEngine *vm) : _vm(vm) {
}
/**
* Returns true if a given file is currently being cached
*/
bool Cache::isCached(const Common::String &filename) const {
return _resources.contains(filename);
}
/**
* Loads a file into the cache if it's not already present, and returns it.
* If the file is LZW compressed, automatically decompresses it and loads
* the uncompressed version into memory
*/
void Cache::load(const Common::String &name) {
// First check if the entry already exists
if (_resources.contains(name))
@ -58,9 +50,6 @@ void Cache::load(const Common::String &name) {
f.close();
}
/**
* Load a cache entry based on a passed stream
*/
void Cache::load(const Common::String &name, Common::SeekableReadStream &stream) {
// First check if the entry already exists
if (_resources.contains(name))
@ -88,9 +77,6 @@ void Cache::load(const Common::String &name, Common::SeekableReadStream &stream)
}
}
/**
* Get a file from the cache
*/
Common::SeekableReadStream *Cache::get(const Common::String &filename) const {
// Return a memory stream that encapsulates the data
const CacheEntry &cacheEntry = _resources[filename];
@ -111,10 +97,6 @@ Resources::Resources(SherlockEngine *vm) : _vm(vm), _cache(vm) {
}
}
/**
* Adds the specified file to the cache. If it's a library file, takes care of
* loading it's index for future use
*/
void Resources::addToCache(const Common::String &filename) {
_cache.load(filename);
@ -127,9 +109,6 @@ void Resources::addToCache(const Common::String &filename) {
delete stream;
}
/**
* Adds a resource from a library file to the cache
*/
void Resources::addToCache(const Common::String &filename, const Common::String &libFilename) {
// Get the resource
Common::SeekableReadStream *stream = load(filename, libFilename);
@ -139,16 +118,10 @@ void Resources::addToCache(const Common::String &filename, const Common::String
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) {
// First check if the file is directly in the cache
if (_cache.isCached(filename))
@ -184,9 +157,6 @@ Common::SeekableReadStream *Resources::load(const Common::String &filename) {
return stream;
}
/**
* Checks the passed stream, and if is compressed, deletes it and replaces it with it's uncompressed data
*/
void Resources::decompressIfNecessary(Common::SeekableReadStream *&stream) {
bool isCompressed = stream->readUint32BE() == MKTAG('L', 'Z', 'V', 26);
stream->seek(-4, SEEK_CUR);
@ -198,9 +168,6 @@ void Resources::decompressIfNecessary(Common::SeekableReadStream *&stream) {
}
}
/**
* Loads a specific resource from a given library file
*/
Common::SeekableReadStream *Resources::load(const Common::String &filename, const Common::String &libraryFile) {
// Open up the library for access
Common::SeekableReadStream *libStream = load(libraryFile);
@ -219,17 +186,11 @@ Common::SeekableReadStream *Resources::load(const Common::String &filename, cons
return stream;
}
/**
* Returns true if the given file exists on disk or in the cache
*/
bool Resources::exists(const Common::String &filename) const {
Common::File f;
return f.exists(filename) || _cache.isCached(filename);
}
/**
* Reads in the index from a library file, and caches it's index for later use
*/
void Resources::loadLibraryIndex(const Common::String &libFilename,
Common::SeekableReadStream *stream) {
uint32 offset, nextOffset;
@ -266,15 +227,63 @@ void Resources::loadLibraryIndex(const Common::String &libFilename,
}
}
/**
* Returns the index of the last loaded resource in it's given library file.
* This will be used primarily when loading talk files, so the engine can
* update the given conversation number in the journal
*/
int Resources::resourceIndex() const {
return _resourceIndex;
}
Common::SeekableReadStream *Resources::decompressLZ(Common::SeekableReadStream &source) {
if (_vm->getGameID() == GType_SerratedScalpel) {
uint32 id = source.readUint32BE();
assert(id == MKTAG('L', 'Z', 'V', 0x1A));
}
uint32 size = source.readUint32LE();
return decompressLZ(source, size);
}
Common::SeekableReadStream *Resources::decompressLZ(Common::SeekableReadStream &source, uint32 outSize) {
byte lzWindow[4096];
uint16 lzWindowPos;
uint16 cmd;
byte *outBuffer = (byte *)malloc(outSize);
byte *outBufferEnd = outBuffer + outSize;
Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES);
memset(lzWindow, 0xFF, 0xFEE);
lzWindowPos = 0xFEE;
cmd = 0;
do {
cmd >>= 1;
if (!(cmd & 0x100))
cmd = source.readByte() | 0xFF00;
if (cmd & 1) {
byte literal = source.readByte();
*outBuffer++ = literal;
lzWindow[lzWindowPos] = literal;
lzWindowPos = (lzWindowPos + 1) & 0x0FFF;
}
else {
int copyPos, copyLen;
copyPos = source.readByte();
copyLen = source.readByte();
copyPos = copyPos | ((copyLen & 0xF0) << 4);
copyLen = (copyLen & 0x0F) + 3;
while (copyLen--) {
byte literal = lzWindow[copyPos];
copyPos = (copyPos + 1) & 0x0FFF;
*outBuffer++ = literal;
lzWindow[lzWindowPos] = literal;
lzWindowPos = (lzWindowPos + 1) & 0x0FFF;
}
}
} while (outBuffer < outBufferEnd);
return outS;
}
/*----------------------------------------------------------------*/
SherlockEngine *ImageFile::_vm;
@ -302,9 +311,6 @@ ImageFile::~ImageFile() {
(*this)[idx]._frame.free();
}
/**
* Load the data of the sprite
*/
void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool animImages) {
loadPalette(stream);
@ -350,9 +356,6 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool
}
}
/**
* Gets the palette at the start of the sprite file
*/
void ImageFile::loadPalette(Common::SeekableReadStream &stream) {
// Check for palette
int v1 = stream.readUint16LE() + 1;
@ -372,9 +375,6 @@ void ImageFile::loadPalette(Common::SeekableReadStream &stream) {
}
}
/**
* Decompress a single frame for the sprite
*/
void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) {
frame._frame.create(frame._width, frame._height, Graphics::PixelFormat::createFormatCLUT8());
@ -411,62 +411,4 @@ void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) {
}
}
/**
* Decompress an LZW compressed resource
*/
Common::SeekableReadStream *Resources::decompressLZ(Common::SeekableReadStream &source) {
if (_vm->getGameID() == GType_SerratedScalpel) {
uint32 id = source.readUint32BE();
assert(id == MKTAG('L', 'Z', 'V', 0x1A));
}
uint32 size = source.readUint32LE();
return decompressLZ(source, size);
}
/**
* Decompresses an LZW block of data with a specified output size
*/
Common::SeekableReadStream *Resources::decompressLZ(Common::SeekableReadStream &source, uint32 outSize) {
byte lzWindow[4096];
uint16 lzWindowPos;
uint16 cmd;
byte *outBuffer = (byte *)malloc(outSize);
byte *outBufferEnd = outBuffer + outSize;
Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES);
memset(lzWindow, 0xFF, 0xFEE);
lzWindowPos = 0xFEE;
cmd = 0;
do {
cmd >>= 1;
if (!(cmd & 0x100))
cmd = source.readByte() | 0xFF00;
if (cmd & 1) {
byte literal = source.readByte();
*outBuffer++ = literal;
lzWindow[lzWindowPos] = literal;
lzWindowPos = (lzWindowPos + 1) & 0x0FFF;
} else {
int copyPos, copyLen;
copyPos = source.readByte();
copyLen = source.readByte();
copyPos = copyPos | ((copyLen & 0xF0) << 4);
copyLen = (copyLen & 0x0F) + 3;
while (copyLen--) {
byte literal = lzWindow[copyPos];
copyPos = (copyPos + 1) & 0x0FFF;
*outBuffer++ = literal;
lzWindow[lzWindowPos] = literal;
lzWindowPos = (lzWindowPos + 1) & 0x0FFF;
}
}
} while (outBuffer < outBufferEnd);
return outS;
}
} // End of namespace Sherlock

View file

@ -57,11 +57,26 @@ private:
public:
Cache(SherlockEngine *_vm);
/**
* Returns true if a given file is currently being cached
*/
bool isCached(const Common::String &filename) const;
/**
* Loads a file into the cache if it's not already present, and returns it.
* If the file is LZW compressed, automatically decompresses it and loads
* the uncompressed version into memory
*/
void load(const Common::String &name);
/**
* Load a cache entry based on a passed stream
*/
void load(const Common::String &name, Common::SeekableReadStream &stream);
/**
* Get a file from the cache
*/
Common::SeekableReadStream *get(const Common::String &filename) const;
};
@ -72,26 +87,66 @@ private:
LibraryIndexes _indexes;
int _resourceIndex;
/**
* Reads in the index from a library file, and caches it's index for later use
*/
void loadLibraryIndex(const Common::String &libFilename, Common::SeekableReadStream *stream);
public:
Resources(SherlockEngine *vm);
/**
* Adds the specified file to the cache. If it's a library file, takes care of
* loading it's index for future use
*/
void addToCache(const Common::String &filename);
/**
* Adds a resource from a library file to the cache
*/
void addToCache(const Common::String &filename, const Common::String &libFilename);
/**
* Adds a given stream to the cache under the given name
*/
void addToCache(const Common::String &filename, Common::SeekableReadStream &stream);
bool isInCache(const Common::String &filename) const { return _cache.isCached(filename); }
/**
* Checks the passed stream, and if is compressed, deletes it and replaces it with it's uncompressed data
*/
void decompressIfNecessary(Common::SeekableReadStream *&stream);
/**
* Returns a stream for a given file
*/
Common::SeekableReadStream *load(const Common::String &filename);
/**
* Loads a specific resource from a given library file
*/
Common::SeekableReadStream *load(const Common::String &filename, const Common::String &libraryFile);
/**
* Returns true if the given file exists on disk or in the cache
*/
bool exists(const Common::String &filename) const;
/**
* Returns the index of the last loaded resource in it's given library file.
* This will be used primarily when loading talk files, so the engine can
* update the given conversation number in the journal
*/
int resourceIndex() const;
/**
* Decompresses an LZW block of data with a specified output size
*/
static Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, uint32 outSize);
/**
* Decompress an LZW compressed resource
*/
Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source);
};
@ -111,8 +166,19 @@ class ImageFile : public Common::Array<ImageFrame> {
private:
static SherlockEngine *_vm;
/**
* Load the data of the sprite
*/
void load(Common::SeekableReadStream &stream, bool skipPalette, bool animImages);
/**
* Gets the palette at the start of the sprite file
*/
void loadPalette(Common::SeekableReadStream &stream);
/**
* Decompress a single frame for the sprite
*/
void decompressFrame(ImageFrame &frame, const byte *src);
public:
byte _palette[256 * 3];

View file

@ -55,9 +55,6 @@ SaveManager::~SaveManager() {
}
}
/**
* Shows the in-game dialog interface for loading and saving games
*/
void SaveManager::drawInterface() {
Screen &screen = *_vm->_screen;
UserInterface &ui = *_vm->_ui;
@ -107,9 +104,6 @@ void SaveManager::drawInterface() {
_envMode = SAVEMODE_NONE;
}
/**
* Build up a savegame list, with empty slots given an explicit Empty message
*/
void SaveManager::createSavegameList() {
Screen &screen = *_vm->_screen;
@ -137,9 +131,6 @@ void SaveManager::createSavegameList() {
}
}
/**
* Load a list of savegames
*/
SaveStateList SaveManager::getSavegameList(const Common::String &target) {
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
Common::StringArray filenames;
@ -175,9 +166,6 @@ SaveStateList SaveManager::getSavegameList(const Common::String &target) {
const char *const SAVEGAME_STR = "SHLK";
#define SAVEGAME_STR_SIZE 4
/**
* Read in the header information for a savegame
*/
bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
header._thumbnail = nullptr;
@ -212,9 +200,6 @@ bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHea
return true;
}
/**
* Write out the header information for a savegame
*/
void SaveManager::writeSavegameHeader(Common::OutSaveFile *out, SherlockSavegameHeader &header) {
// Write out a savegame header
out->write(SAVEGAME_STR, SAVEGAME_STR_SIZE + 1);
@ -245,9 +230,6 @@ void SaveManager::writeSavegameHeader(Common::OutSaveFile *out, SherlockSavegame
out->writeUint32LE(_vm->_events->getFrameCounter());
}
/**
* Creates a thumbnail for the current on-screen contents
*/
void SaveManager::createThumbnail() {
if (_saveThumb) {
_saveThumb->free();
@ -260,9 +242,6 @@ void SaveManager::createThumbnail() {
::createThumbnail(_saveThumb, (const byte *)_vm->_screen->getPixels(), SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT, thumbPalette);
}
/**
* Return the index of the button the mouse is over, if any
*/
int SaveManager::getHighlightedButton() const {
Common::Point pt = _vm->_events->mousePos();
@ -275,9 +254,6 @@ int SaveManager::getHighlightedButton() const {
return -1;
}
/**
* Handle highlighting buttons
*/
void SaveManager::highlightButtons(int btnIndex) {
Screen &screen = *_vm->_screen;
byte color = (btnIndex == 0) ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND;
@ -309,9 +285,6 @@ void SaveManager::highlightButtons(int btnIndex) {
screen.buttonPrint(Common::Point(ENV_POINTS[5][2], CONTROLS_Y), color, 1, "Quit");
}
/**
* Load the game in the specified slot
*/
void SaveManager::loadGame(int slot) {
Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(
generateSaveName(slot));
@ -335,9 +308,6 @@ void SaveManager::loadGame(int slot) {
delete saveFile;
}
/**
* Save the game in the specified slot with the given name
*/
void SaveManager::saveGame(int slot, const Common::String &name) {
Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving(
generateSaveName(slot));
@ -354,17 +324,10 @@ void SaveManager::saveGame(int slot, const Common::String &name) {
delete out;
}
/**
* Support method that generates a savegame name
* @param slot Slot number
*/
Common::String SaveManager::generateSaveName(int slot) {
return Common::String::format("%s.%03d", _target.c_str(), slot);
}
/**
* Synchronize the data for a savegame
*/
void SaveManager::synchronize(Common::Serializer &s) {
Inventory &inv = *_vm->_inventory;
Journal &journal = *_vm->_journal;
@ -391,9 +354,6 @@ void SaveManager::synchronize(Common::Serializer &s) {
_justLoaded = true;
}
/**
* Make sure that the selected savegame is on-screen
*/
bool SaveManager::checkGameOnScreen(int slot) {
Screen &screen = *_vm->_screen;

View file

@ -56,8 +56,14 @@ private:
Common::String _target;
Graphics::Surface *_saveThumb;
/**
* Build up a savegame list, with empty slots given an explicit Empty message
*/
void createSavegameList();
/**
* Synchronize the data for a savegame
*/
void synchronize(Common::Serializer &s);
public:
Common::StringArray _savegames;
@ -68,27 +74,65 @@ public:
SaveManager(SherlockEngine *vm, const Common::String &target);
~SaveManager();
/**
* Shows the in-game dialog interface for loading and saving games
*/
void drawInterface();
/**
* Creates a thumbnail for the current on-screen contents
*/
void createThumbnail();
/**
* Load a list of savegames
*/
static SaveStateList getSavegameList(const Common::String &target);
/**
* Support method that generates a savegame name
* @param slot Slot number
*/
Common::String generateSaveName(int slot);
/**
* Write out the header information for a savegame
*/
void writeSavegameHeader(Common::OutSaveFile *out, SherlockSavegameHeader &header);
/**
* Read in the header information for a savegame
*/
static bool readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header);
/**
* Return the index of the button the mouse is over, if any
*/
int getHighlightedButton() const;
/**
* Handle highlighting buttons
*/
void highlightButtons(int btnIndex);
/**
* Load the game in the specified slot
*/
void loadGame(int slot);
/**
* Save the game in the specified slot with the given name
*/
void saveGame(int slot, const Common::String &name);
/**
* Make sure that the selected savegame is on-screen
*/
bool checkGameOnScreen(int slot);
/**
* Prompts the user to enter a filename in a given slot
*/
bool getFilename(int slot);
};

View file

@ -64,9 +64,6 @@ Darts::Darts(ScalpelEngine *vm) : _vm(vm) {
_oldDartButtons = false;
}
/**
* Main method for playing darts game
*/
void Darts::playDarts() {
Events &events = *_vm->_events;
Screen &screen = *_vm->_screen;
@ -182,9 +179,6 @@ void Darts::playDarts() {
screen.setFont(oldFont);
}
/**
* Load the graphics needed for the dart game
*/
void Darts::loadDarts() {
Screen &screen = *_vm->_screen;
@ -195,9 +189,6 @@ void Darts::loadDarts() {
screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
}
/**
* Initializes the variables needed for the dart game
*/
void Darts::initDarts() {
_dartScore1 = _dartScore2 = 301;
_roundNumber = 1;
@ -220,17 +211,11 @@ void Darts::initDarts() {
_opponent = OPPONENT_NAMES[_level];
}
/**
* Frees the images used by the dart game
*/
void Darts::closeDarts() {
delete _dartImages;
_dartImages = nullptr;
}
/**
* Show the names of the people playing, Holmes and his opponent
*/
void Darts::showNames(int playerNum) {
Screen &screen = *_vm->_screen;
byte color = playerNum == 0 ? PLAYER_COLOR : DART_COL_FORE;
@ -263,9 +248,6 @@ void Darts::showNames(int playerNum) {
screen._backBuffer2.blitFrom(screen._backBuffer1);
}
/**
* Show the player score and game status
*/
void Darts::showStatus(int playerNum) {
Screen &screen = *_vm->_screen;
byte color;
@ -284,12 +266,6 @@ void Darts::showStatus(int playerNum) {
screen.slamRect(Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, SHERLOCK_SCREEN_WIDTH, STATUS_INFO_Y + 48));
}
/**
* Throws a single dart.
* @param dartNum Dart number
* @param computer 0 = Player, 1 = 1st player computer, 2 = 2nd player computer
* @returns Score for what dart hit
*/
int Darts::throwDart(int dartNum, int computer) {
Events &events = *_vm->_events;
Screen &screen = *_vm->_screen;
@ -348,9 +324,6 @@ int Darts::throwDart(int dartNum, int computer) {
return dartScore(dartPos);
}
/**
* Draw a dart moving towards the board
*/
void Darts::drawDartThrow(const Common::Point &pt) {
Events &events = *_vm->_events;
Screen &screen = *_vm->_screen;
@ -390,9 +363,6 @@ void Darts::drawDartThrow(const Common::Point &pt) {
screen.slamRect(oldDrawBounds);
}
/**
* Erases the power bars
*/
void Darts::erasePowerBars() {
Screen &screen = *_vm->_screen;
@ -404,11 +374,6 @@ void Darts::erasePowerBars() {
screen.slamArea(DARTBARVX - 1, DARTHEIGHTY - 1, 11, DARTBARSIZE + 3);
}
/**
* Show a gradually incrementing incrementing power that bar. If goToPower is provided, it will
* increment to that power level ignoring all keyboard input (ie. for computer throws).
* Otherwise, it will increment until either a key/mouse button is pressed, or it reaches the end
*/
int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, bool isVertical) {
Events &events = *_vm->_events;
Screen &screen = *_vm->_screen;
@ -459,9 +424,6 @@ int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, bool i
return MIN(idx * 100 / DARTBARSIZE, 100);
}
/**
* Returns true if a mouse button or key is pressed.
*/
bool Darts::dartHit() {
Events &events = *_vm->_events;
@ -481,9 +443,6 @@ bool Darts::dartHit() {
return (events._pressed && !_oldDartButtons) ? 1 : 0;
}
/**
* Return the score of the given location on the dart-board
*/
int Darts::dartScore(const Common::Point &pt) {
Common::Point pos(pt.x - 37, pt.y - 33);
Graphics::Surface &scoreImg = (*_dartImages)[1]._frame;
@ -497,10 +456,6 @@ int Darts::dartScore(const Common::Point &pt) {
return score;
}
/**
* Calculates where a computer player is trying to throw their dart, and choose the actual
* point that was hit with some margin of error
*/
Common::Point Darts::getComputerDartDest(int playerNum) {
Common::Point target;
int score = playerNum == 0 ? _dartScore1 : _dartScore2;
@ -556,9 +511,6 @@ Common::Point Darts::getComputerDartDest(int playerNum) {
return target;
}
/**
* Returns the center position for the area of the dartboard with a given number
*/
bool Darts::findNumberOnBoard(int aim, Common::Point &pt) {
ImageFrame &board = (*_dartImages)[1];
@ -598,10 +550,6 @@ bool Darts::findNumberOnBoard(int aim, Common::Point &pt) {
return done;
}
/**
* Set a global flag to 0 or 1 depending on whether the passed flag is negative or positive.
* @remarks We don't use the global setFlags method because we don't want to check scene flags
*/
void Darts::setFlagsForDarts(int flagNum) {
_vm->_flags[ABS(flagNum)] = flagNum >= 0;
}

View file

@ -44,30 +44,88 @@ private:
int _roundScore;
bool _oldDartButtons;
/**
* Load the graphics needed for the dart game
*/
void loadDarts();
/**
* Initializes the variables needed for the dart game
*/
void initDarts();
/**
* Frees the images used by the dart game
*/
void closeDarts();
/**
* Show the names of the people playing, Holmes and his opponent
*/
void showNames(int playerNum);
/**
* Show the player score and game status
*/
void showStatus(int playerNum);
/**
* Throws a single dart.
* @param dartNum Dart number
* @param computer 0 = Player, 1 = 1st player computer, 2 = 2nd player computer
* @returns Score for what dart hit
*/
int throwDart(int dartNum, int computer);
/**
* Draw a dart moving towards the board
*/
void drawDartThrow(const Common::Point &pt);
/**
* Erases the power bars
*/
void erasePowerBars();
/**
* Show a gradually incrementing incrementing power that bar. If goToPower is provided, it will
* increment to that power level ignoring all keyboard input (ie. for computer throws).
* Otherwise, it will increment until either a key/mouse button is pressed, or it reaches the end
*/
int doPowerBar(const Common::Point &pt, byte color, int goToPower, bool isVertical);
/**
* Returns true if a mouse button or key is pressed.
*/
bool dartHit();
/**
* Return the score of the given location on the dart-board
*/
int dartScore(const Common::Point &pt);
/**
* Calculates where a computer player is trying to throw their dart, and choose the actual
* point that was hit with some margin of error
*/
Common::Point getComputerDartDest(int playerNum);
/**
* Returns the center position for the area of the dartboard with a given number
*/
bool findNumberOnBoard(int aim, Common::Point &pt);
/**
* Set a global flag to 0 or 1 depending on whether the passed flag is negative or positive.
* @remarks We don't use the global setFlags method because we don't want to check scene flags
*/
void setFlagsForDarts(int flagNum);
public:
Darts(ScalpelEngine *vm);
/**
* Main method for playing darts game
*/
void playDarts();
};

View file

@ -238,9 +238,6 @@ ScalpelEngine::~ScalpelEngine() {
delete _darts;
}
/**
* Game initialization
*/
void ScalpelEngine::initialize() {
SherlockEngine::initialize();
@ -276,9 +273,6 @@ void ScalpelEngine::initialize() {
_scene->_goToScene = 4;
}
/**
* Show the opening sequence
*/
void ScalpelEngine::showOpening() {
if (isDemo() && _interactiveFl)
return;
@ -296,9 +290,6 @@ void ScalpelEngine::showOpening() {
_sound->stopMusic();
}
/**
* Show the starting city cutscene which shows the game title
*/
bool ScalpelEngine::showCityCutscene() {
byte palette[PALETTE_SIZE];
@ -371,9 +362,6 @@ bool ScalpelEngine::showCityCutscene() {
return finished;
}
/**
* Show the back alley where the initial murder takes place
*/
bool ScalpelEngine::showAlleyCutscene() {
byte palette[PALETTE_SIZE];
_sound->playMusic("prolog2.mus");
@ -411,9 +399,6 @@ bool ScalpelEngine::showAlleyCutscene() {
return finished;
}
/**
* Show the Baker Street outside cutscene
*/
bool ScalpelEngine::showStreetCutscene() {
_animation->_gfxLibraryFilename = "TITLE.LIB";
_animation->_soundLibraryFilename = "TITLE.SND";
@ -430,9 +415,7 @@ bool ScalpelEngine::showStreetCutscene() {
return finished;
}
/**
* Show the game credits
*/
bool ScalpelEngine::scrollCredits() {
// Load the images for displaying credit text
Common::SeekableReadStream *stream = _res->load("credits.vgs", "title.lib");
@ -465,9 +448,6 @@ bool ScalpelEngine::scrollCredits() {
return true;
}
/**
* Show Holmes and Watson at the breakfast table, lestrade's note, and then the scrolling credits
*/
bool ScalpelEngine::showOfficeCutscene() {
_sound->playMusic("PROLOG4.MUS");
_animation->_gfxLibraryFilename = "TITLE2.LIB";
@ -511,11 +491,6 @@ bool ScalpelEngine::showOfficeCutscene() {
return finished;
}
/**
* Load the default inventory for the game, which includes both the initial active inventory,
* as well as special pending inventory items which can appear automatically in the player's
* inventory once given required flags are set
*/
void ScalpelEngine::loadInventory() {
Inventory &inv = *_inventory;
@ -537,9 +512,6 @@ void ScalpelEngine::loadInventory() {
inv.push_back(InventoryItem(586, "Pawn ticket", "A pawn ticket", "_ITEM16A"));
}
/**
* Transition to show an image
*/
void ScalpelEngine::showLBV(const Common::String &filename) {
Common::SeekableReadStream *stream = _res->load(filename, "title.lib");
ImageFile images(*stream);
@ -550,9 +522,6 @@ void ScalpelEngine::showLBV(const Common::String &filename) {
_screen->verticalTransition();
}
/**
* Starting a scene within the game
*/
void ScalpelEngine::startScene() {
if (_scene->_goToScene == OVERHEAD_MAP || _scene->_goToScene == OVERHEAD_MAP2) {
// Show the map
@ -709,9 +678,6 @@ void ScalpelEngine::startScene() {
_mapResult = _scene->_goToScene;
}
/**
* Takes care of clearing the mirror in scene 12 (mansion drawing room), in case anything drew over it
*/
void ScalpelEngine::eraseMirror12() {
Common::Point pt((*_people)[AL]._position.x / 100, (*_people)[AL]._position.y / 100);
@ -722,9 +688,6 @@ void ScalpelEngine::eraseMirror12() {
}
}
/**
* Takes care of drawing Holme's reflection onto the mirror in scene 12 (mansion drawing room)
*/
void ScalpelEngine::doMirror12() {
People &people = *_people;
Common::Point pt((*_people)[AL]._position.x / 100, (*_people)[AL]._position.y / 100);
@ -798,9 +761,6 @@ void ScalpelEngine::doMirror12() {
}
}
/**
* This clears the mirror in scene 12 (mansion drawing room) in case anything messed draw over it
*/
void ScalpelEngine::flushMirror12() {
Common::Point pt((*_people)[AL]._position.x / 100, (*_people)[AL]._position.y / 100);

View file

@ -39,27 +39,74 @@ private:
Darts *_darts;
int _mapResult;
/**
* Show the starting city cutscene which shows the game title
*/
bool showCityCutscene();
/**
* Show the back alley where the initial murder takes place
*/
bool showAlleyCutscene();
/**
* Show the Baker Street outside cutscene
*/
bool showStreetCutscene();
/**
* Show Holmes and Watson at the breakfast table, lestrade's note, and then the scrolling credits
*/
bool showOfficeCutscene();
/**
* Show the game credits
*/
bool scrollCredits();
/**
* Load the default inventory for the game, which includes both the initial active inventory,
* as well as special pending inventory items which can appear automatically in the player's
* inventory once given required flags are set
*/
void loadInventory();
/**
* Transition to show an image
*/
void showLBV(const Common::String &filename);
protected:
/**
* Game initialization
*/
virtual void initialize();
/**
* Show the opening sequence
*/
virtual void showOpening();
/**
* Starting a scene within the game
*/
virtual void startScene();
public:
ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
virtual ~ScalpelEngine();
/**
* Takes care of clearing the mirror in scene 12 (mansion drawing room), in case anything drew over it
*/
void eraseMirror12();
/**
* Takes care of drawing Holme's reflection onto the mirror in scene 12 (mansion drawing room)
*/
void doMirror12();
/**
* This clears the mirror in scene 12 (mansion drawing room) in case anything messed draw over it
*/
void flushMirror12();
};

View file

@ -33,9 +33,6 @@ static const int FS_TRANS[8] = {
/*----------------------------------------------------------------*/
/**
* Load the data for the object
*/
void BgFileHeader::load(Common::SeekableReadStream &s) {
_numStructs = s.readUint16LE();
_numImages = s.readUint16LE();
@ -47,9 +44,6 @@ void BgFileHeader::load(Common::SeekableReadStream &s) {
/*----------------------------------------------------------------*/
/**
* Load the data for the object
*/
void BgFileHeaderInfo::load(Common::SeekableReadStream &s) {
_filesize = s.readUint32LE();
_maxFrames = s.readByte();
@ -61,9 +55,6 @@ void BgFileHeaderInfo::load(Common::SeekableReadStream &s) {
/*----------------------------------------------------------------*/
/**
* Load the data for the object
*/
void Exit::load(Common::SeekableReadStream &s) {
int xp = s.readSint16LE();
int yp = s.readSint16LE();
@ -80,9 +71,6 @@ void Exit::load(Common::SeekableReadStream &s) {
/*----------------------------------------------------------------*/
/**
* Load the data for the object
*/
void SceneEntry::load(Common::SeekableReadStream &s) {
_startPosition.x = s.readSint16LE();
_startPosition.y = s.readSint16LE();
@ -90,9 +78,6 @@ void SceneEntry::load(Common::SeekableReadStream &s) {
_allow = s.readByte();
}
/**
* Load the data for the object
*/
void SceneSound::load(Common::SeekableReadStream &s) {
char buffer[9];
s.read(buffer, 8);
@ -104,9 +89,6 @@ void SceneSound::load(Common::SeekableReadStream &s) {
/*----------------------------------------------------------------*/
/**
* Retuurn the index of the passed object in the array
*/
int ObjectArray::indexOf(const Object &obj) const {
for (uint idx = 0; idx < size(); ++idx) {
if (&(*this)[idx] == &obj)
@ -143,9 +125,6 @@ Scene::~Scene() {
freeScene();
}
/**
* Handles loading the scene specified by _goToScene
*/
void Scene::selectScene() {
Events &events = *_vm->_events;
People &people = *_vm->_people;
@ -189,9 +168,6 @@ void Scene::selectScene() {
talk._scriptMoreFlag = 0;
}
/**
* Fres all the graphics and other dynamically allocated data for the scene
*/
void Scene::freeScene() {
if (_currentScene == -1)
return;
@ -221,15 +197,6 @@ void Scene::freeScene() {
_currentScene = -1;
}
/**
* Loads the data associated for a given scene. The .BGD file's format is:
* BGHEADER: Holds an index for the rest of the file
* STRUCTS: The objects for the scene
* IMAGES: The graphic information for the structures
*
* The _misc field of the structures contains the number of the graphic image
* that it should point to after loading; _misc is then set to 0.
*/
bool Scene::loadScene(const Common::String &filename) {
Events &events = *_vm->_events;
Map &map = *_vm->_map;
@ -513,10 +480,6 @@ bool Scene::loadScene(const Common::String &filename) {
return flag;
}
/**
* Set objects to their current persistent state. This includes things such as
* opening or moving them
*/
void Scene::checkSceneStatus() {
if (_sceneStats[_currentScene][64]) {
for (uint idx = 0; idx < 64; ++idx) {
@ -542,10 +505,6 @@ void Scene::checkSceneStatus() {
}
}
/**
* Restores objects to the correct status. This ensures that things like being opened or moved
* will remain the same on future visits to the scene
*/
void Scene::saveSceneStatus() {
// Flag any objects for the scene that have been altered
int count = MIN((int)_bgShapes.size(), 64);
@ -559,11 +518,6 @@ void Scene::saveSceneStatus() {
_sceneStats[_currentScene][64] = true;
}
/**
* Check the scene's objects against the game flags. If false is passed,
* it means the scene has just been loaded. A value of true means that the scene
* is in use (ie. not just loaded)
*/
void Scene::checkSceneFlags(bool flag) {
SpriteType mode = flag ? HIDE_SHAPE : HIDDEN;
@ -616,11 +570,6 @@ void Scene::checkSceneFlags(bool flag) {
}
}
/**
* Checks scene objects against the player's inventory items. If there are any
* matching names, it means the given item has already been picked up, and should
* be hidden in the scene.
*/
void Scene::checkInventory() {
for (uint shapeIdx = 0; shapeIdx < _bgShapes.size(); ++shapeIdx) {
for (int invIdx = 0; invIdx < _vm->_inventory->_holdings; ++invIdx) {
@ -632,10 +581,6 @@ void Scene::checkInventory() {
}
}
/**
* Set up any entrance co-ordinates or entrance canimations, and then transition
* in the scene
*/
void Scene::transitionToScene() {
People &people = *_vm->_people;
SaveManager &saves = *_vm->_saves;
@ -750,10 +695,6 @@ void Scene::transitionToScene() {
}
}
/**
* Scans through the object list to find one with a matching name, and will
* call toggleHidden with all matches found. Returns the numer of matches found
*/
int Scene::toggleObject(const Common::String &name) {
int count = 0;
@ -767,10 +708,6 @@ int Scene::toggleObject(const Common::String &name) {
return count;
}
/**
* Update the screen back buffer with all of the scene objects which need
* to be drawn
*/
void Scene::updateBackground() {
People &people = *_vm->_people;
Screen &screen = *_vm->_screen;
@ -860,9 +797,6 @@ void Scene::updateBackground() {
screen.resetDisplayBounds();
}
/**
* Check whether the passed area intersects with one of the scene's exits
*/
Exit *Scene::checkForExit(const Common::Rect &r) {
for (uint idx = 0; idx < _exits.size(); ++idx) {
if (_exits[idx]._bounds.intersects(r))
@ -872,11 +806,6 @@ Exit *Scene::checkForExit(const Common::Rect &r) {
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) {
// Iterate through the shapes
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
@ -911,14 +840,6 @@ void Scene::checkBgShapes(ImageFrame *frame, const Common::Point &pt) {
}
}
/**
* 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) {
Events &events = *_vm->_events;
Map &map = *_vm->_map;
@ -1131,9 +1052,6 @@ int Scene::startCAnim(int cAnimNum, int playRate) {
return 1;
}
/**
* Animate all objects and people.
*/
void Scene::doBgAnim() {
Events &events = *_vm->_events;
Inventory &inv = *_vm->_inventory;
@ -1461,10 +1379,6 @@ void Scene::doBgAnim() {
}
}
/**
* Attempts to find a background shape within the passed bounds. If found,
* it will return the shape number, or -1 on failure.
*/
int Scene::findBgShape(const Common::Rect &r) {
if (!_doBgAnimDone)
// New frame hasn't been drawn yet
@ -1485,10 +1399,6 @@ int Scene::findBgShape(const Common::Rect &r) {
return -1;
}
/**
* Checks to see if the given position in the scene belongs to a given zone type.
* If it is, the zone is activated and used just like a TAKL zone or aFLAG_SET zone.
*/
int Scene::checkForZones(const Common::Point &pt, int zoneType) {
int matches = 0;
@ -1508,9 +1418,6 @@ int Scene::checkForZones(const Common::Point &pt, int zoneType) {
return matches;
}
/**
* Check which zone the the given position is located in.
*/
int Scene::whichZone(const Common::Point &pt) {
for (uint idx = 0; idx < _zones.size(); ++idx) {
if (_zones[idx].contains(pt))
@ -1520,9 +1427,6 @@ int Scene::whichZone(const Common::Point &pt) {
return -1;
}
/**
* Returns the index of the closest zone to a given point.
*/
int Scene::closestZone(const Common::Point &pt) {
int dist = 1000;
int zone = -1;
@ -1542,9 +1446,6 @@ int Scene::closestZone(const Common::Point &pt) {
return zone;
}
/**
* Synchronize the data for a savegame
*/
void Scene::synchronize(Common::Serializer &s) {
if (s.isSaving())
saveSceneStatus();

View file

@ -46,6 +46,9 @@ struct BgFileHeader {
int _seqSize;
int _fill;
/**
* Load the data for the object
*/
void load(Common::SeekableReadStream &s);
};
@ -54,6 +57,9 @@ struct BgFileHeaderInfo {
int _maxFrames; // How many unique frames in object
Common::String _filename; // Filename of object
/**
* Load the data for the object
*/
void load(Common::SeekableReadStream &s);
};
@ -65,6 +71,9 @@ struct Exit {
Common::Point _people;
int _peopleDir;
/**
* Load the data for the object
*/
void load(Common::SeekableReadStream &s);
};
@ -73,6 +82,9 @@ struct SceneEntry {
int _startDir;
int _allow;
/**
* Load the data for the object
*/
void load(Common::SeekableReadStream &s);
};
@ -80,11 +92,17 @@ struct SceneSound {
Common::String _name;
int _priority;
/**
* Load the data for the object
*/
void load(Common::SeekableReadStream &s);
};
class ObjectArray : public Common::Array<Object> {
public:
/**
* Retuurn the index of the passed object in the array
*/
int indexOf(const Object &obj) const;
};
@ -96,16 +114,47 @@ private:
bool _lookHelp;
bool _loadingSavedGame;
/**
* Loads the data associated for a given scene. The .BGD file's format is:
* BGHEADER: Holds an index for the rest of the file
* STRUCTS: The objects for the scene
* IMAGES: The graphic information for the structures
*
* The _misc field of the structures contains the number of the graphic image
* that it should point to after loading; _misc is then set to 0.
*/
bool loadScene(const Common::String &filename);
/**
* Set objects to their current persistent state. This includes things such as
* opening or moving them
*/
void checkSceneStatus();
/**
* Checks scene objects against the player's inventory items. If there are any
* matching names, it means the given item has already been picked up, and should
* be hidden in the scene.
*/
void checkInventory();
/**
* Set up any entrance co-ordinates or entrance canimations, and then transition
* in the scene
*/
void transitionToScene();
/**
* 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 checkBgShapes(ImageFrame *frame, const Common::Point &pt);
/**
* Restores objects to the correct status. This ensures that things like being opened or moved
* will remain the same on future visits to the scene
*/
void saveSceneStatus();
public:
int _currentScene;
@ -143,32 +192,80 @@ public:
Scene(SherlockEngine *vm);
~Scene();
/**
* Handles loading the scene specified by _goToScene
*/
void selectScene();
/**
* Fres all the graphics and other dynamically allocated data for the scene
*/
void freeScene();
/**
* Check the scene's objects against the game flags. If false is passed,
* it means the scene has just been loaded. A value of true means that the scene
* is in use (ie. not just loaded)
*/
void checkSceneFlags(bool mode);
/**
* Check whether the passed area intersects with one of the scene's exits
*/
Exit *checkForExit(const Common::Rect &r);
/**
* 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 startCAnim(int cAnimNum, int playRate);
/**
* Scans through the object list to find one with a matching name, and will
* call toggleHidden with all matches found. Returns the numer of matches found
*/
int toggleObject(const Common::String &name);
/**
* Animate all objects and people.
*/
void doBgAnim();
void clearInfo();
/**
* Attempts to find a background shape within the passed bounds. If found,
* it will return the shape number, or -1 on failure.
*/
int findBgShape(const Common::Rect &r);
/**
* Checks to see if the given position in the scene belongs to a given zone type.
* If it is, the zone is activated and used just like a TAKL zone or aFLAG_SET zone.
*/
int checkForZones(const Common::Point &pt, int zoneType);
/**
* Check which zone the the given position is located in.
*/
int whichZone(const Common::Point &pt);
/**
* Returns the index of the closest zone to a given point.
*/
int closestZone(const Common::Point &pt);
/**
* Update the screen back buffer with all of the scene objects which need
* to be drawn
*/
void updateBackground();
/**
* Synchronize the data for a savegame
*/
void synchronize(Common::Serializer &s);
};

View file

@ -49,9 +49,6 @@ Screen::~Screen() {
delete _font;
}
/**
* Set the font to use for writing text on the screen
*/
void Screen::setFont(int fontNumb) {
// Interactive demo doesn't use fonts
if (!_vm->_interactiveFl)
@ -70,9 +67,6 @@ void Screen::setFont(int fontNumb) {
_fontHeight = MAX((uint16)_fontHeight, (*_font)[idx]._frame.h);
}
/**
* Handles updating any dirty areas of the screen Surface object to the physical screen
*/
void Screen::update() {
// Merge the dirty rects
mergeDirtyRects();
@ -91,23 +85,14 @@ void Screen::update() {
_dirtyRects.clear();
}
/**
* Return the currently active palette
*/
void Screen::getPalette(byte palette[PALETTE_SIZE]) {
g_system->getPaletteManager()->grabPalette(palette, 0, PALETTE_COUNT);
}
/**
* Set the palette
*/
void Screen::setPalette(const byte palette[PALETTE_SIZE]) {
g_system->getPaletteManager()->setPalette(palette, 0, PALETTE_COUNT);
}
/**
* Fades from the currently active palette to the passed palette
*/
int Screen::equalizePalette(const byte palette[PALETTE_SIZE]) {
int total = 0;
byte tempPalette[PALETTE_SIZE];
@ -132,9 +117,6 @@ int Screen::equalizePalette(const byte palette[PALETTE_SIZE]) {
return total;
}
/**
* Fade out the palette to black
*/
void Screen::fadeToBlack(int speed) {
byte tempPalette[PALETTE_SIZE];
Common::fill(&tempPalette[0], &tempPalette[PALETTE_SIZE], 0);
@ -147,9 +129,6 @@ void Screen::fadeToBlack(int speed) {
fillRect(Common::Rect(0, 0, this->w, this->h), 0);
}
/**
* Fade in a given palette
*/
void Screen::fadeIn(const byte palette[PALETTE_SIZE], int speed) {
int count = 50;
while (equalizePalette(palette) && --count) {
@ -159,18 +138,11 @@ void Screen::fadeIn(const byte palette[PALETTE_SIZE], int speed) {
setPalette(palette);
}
/**
* Adds a rectangle to the list of modified areas of the screen during the
* current frame
*/
void Screen::addDirtyRect(const Common::Rect &r) {
_dirtyRects.push_back(r);
assert(r.width() > 0 && r.height() > 0);
}
/**
* Merges together overlapping dirty areas of the screen
*/
void Screen::mergeDirtyRects() {
Common::List<Common::Rect>::iterator rOuter, rInner;
@ -195,9 +167,6 @@ void Screen::mergeDirtyRects() {
}
}
/**
* Returns the union of two dirty area rectangles
*/
bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2) {
destRect = src1;
destRect.extend(src2);
@ -205,9 +174,6 @@ bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, co
return !destRect.isEmpty();
}
/**
* Do a random pixel transition in from _backBuffer surface to the screen
*/
void Screen::randomTransition() {
Events &events = *_vm->_events;
const int TRANSITION_MULTIPLIER = 0x15a4e35;
@ -234,9 +200,6 @@ void Screen::randomTransition() {
blitFrom(*_backBuffer);
}
/**
* Transition to the surface from _backBuffer using a vertical transition
*/
void Screen::verticalTransition() {
Events &events = *_vm->_events;
@ -259,9 +222,6 @@ void Screen::verticalTransition() {
}
}
/**
* Copies a section of the second back buffer into the main back buffer
*/
void Screen::restoreBackground(const Common::Rect &r) {
if (r.width() > 0 && r.height() > 0) {
Common::Rect tempRect = r;
@ -272,16 +232,10 @@ void Screen::restoreBackground(const Common::Rect &r) {
}
}
/**
* Copies a given area to the screen
*/
void Screen::slamArea(int16 xp, int16 yp, int16 width, int16 height) {
slamRect(Common::Rect(xp, yp, xp + width, yp + height));
}
/**
* Copies a given area to the screen
*/
void Screen::slamRect(const Common::Rect &r) {
if (r.width() && r.height() > 0) {
Common::Rect tempRect = r;
@ -292,10 +246,6 @@ void Screen::slamRect(const Common::Rect &r) {
}
}
/**
* Copy an image from the back buffer to the screen, taking care of both the
* new area covered by the shape as well as the old area, which must be restored
*/
void Screen::flushImage(ImageFrame *frame, const Common::Point &pt,
int16 *xp, int16 *yp, int16 *width, int16 *height) {
Common::Point imgPos = pt + frame->_offset;
@ -322,10 +272,6 @@ void Screen::flushImage(ImageFrame *frame, const Common::Point &pt,
*height = newBounds.height();
}
/**
* Prints the text passed onto the back buffer at the given position and color.
* The string is then blitted to the screen
*/
void Screen::print(const Common::Point &pt, byte color, const char *formatStr, ...) {
// Create the string to display
va_list args;
@ -354,9 +300,6 @@ void Screen::print(const Common::Point &pt, byte color, const char *formatStr, .
slamRect(textBounds);
}
/**
* Print a strings onto the back buffer without blitting it to the screen
*/
void Screen::gPrint(const Common::Point &pt, byte color, const char *formatStr, ...) {
// Create the string to display
va_list args;
@ -368,10 +311,6 @@ void Screen::gPrint(const Common::Point &pt, byte color, const char *formatStr,
writeString(str, pt, color);
}
/**
* Returns the width of a string in pixels
*/
int Screen::stringWidth(const Common::String &str) {
int width = 0;
@ -381,9 +320,6 @@ int Screen::stringWidth(const Common::String &str) {
return width;
}
/**
* Returns the width of a character in pixels
*/
int Screen::charWidth(char c) {
if (c == ' ')
return 5;
@ -393,9 +329,6 @@ int Screen::charWidth(char c) {
return 0;
}
/**
* Draws the given string into the back buffer using the images stored in _font
*/
void Screen::writeString(const Common::String &str, const Common::Point &pt, byte color) {
Common::Point charPos = pt;
@ -411,17 +344,11 @@ void Screen::writeString(const Common::String &str, const Common::Point &pt, byt
}
}
/**
* Fills an area on the back buffer, and then copies it to the screen
*/
void Screen::vgaBar(const Common::Rect &r, int color) {
_backBuffer->fillRect(r, color);
slamRect(r);
}
/**
* Draws a button for use in the inventory, talk, and examine dialogs.
*/
void Screen::makeButton(const Common::Rect &bounds, int textX,
const Common::String &str) {
@ -437,10 +364,6 @@ void Screen::makeButton(const Common::Rect &bounds, int textX,
COMMAND_FOREGROUND, "%s", str.c_str() + 1);
}
/**
* Prints an interface command with the first letter highlighted to indicate
* what keyboard shortcut is associated with it
*/
void Screen::buttonPrint(const Common::Point &pt, byte color, bool slamIt,
const Common::String &str) {
int xStart = pt.x - stringWidth(str) / 2;
@ -463,9 +386,6 @@ void Screen::buttonPrint(const Common::Point &pt, byte color, bool slamIt,
}
}
/**
* Draw a panel in the back buffer with a raised area effect around the edges
*/
void Screen::makePanel(const Common::Rect &r) {
_backBuffer->fillRect(r, BUTTON_MIDDLE);
_backBuffer->hLine(r.left, r.top, r.right - 2, BUTTON_TOP);
@ -479,10 +399,6 @@ void Screen::makePanel(const Common::Rect &r) {
_backBuffer->hLine(r.left + 1, r.bottom - 2, r.right - 1, BUTTON_BOTTOM);
}
/**
* Draw a field in the back buffer with a raised area effect around the edges,
* suitable for text input.
*/
void Screen::makeField(const Common::Rect &r) {
_backBuffer->fillRect(r, BUTTON_MIDDLE);
_backBuffer->hLine(r.left, r.top, r.right - 1, BUTTON_BOTTOM);
@ -491,9 +407,6 @@ void Screen::makeField(const Common::Rect &r) {
_backBuffer->vLine(r.right - 1, r.top + 1, r.bottom - 2, BUTTON_TOP);
}
/**
* Sets the active back buffer pointer to a restricted sub-area of the first back buffer
*/
void Screen::setDisplayBounds(const Common::Rect &r) {
assert(r.left == 0 && r.top == 0);
_sceneSurface.setPixels(_backBuffer1.getPixels());
@ -503,24 +416,15 @@ void Screen::setDisplayBounds(const Common::Rect &r) {
_backBuffer = &_sceneSurface;
}
/**
* Resets the active buffer pointer to point back to the full first back buffer
*/
void Screen::resetDisplayBounds() {
_backBuffer = &_backBuffer1;
}
/**
* Return the size of the current display window
*/
Common::Rect Screen::getDisplayBounds() {
return (_backBuffer == &_sceneSurface) ? Common::Rect(0, 0, _sceneSurface.w, _sceneSurface.h) :
Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
}
/**
* Synchronize the data for a savegame
*/
void Screen::synchronize(Common::Serializer &s) {
int fontNumb = _fontNumber;
s.syncAsByte(fontNumb);

View file

@ -66,12 +66,25 @@ private:
int _fontHeight;
Surface _sceneSurface;
/**
* Merges together overlapping dirty areas of the screen
*/
void mergeDirtyRects();
/**
* Returns the union of two dirty area rectangles
*/
bool unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2);
/**
* Draws the given string into the back buffer using the images stored in _font
*/
void writeString(const Common::String &str, const Common::Point &pt, byte color);
protected:
/**
* Adds a rectangle to the list of modified areas of the screen during the
* current frame
*/
virtual void addDirtyRect(const Common::Rect &r);
public:
Surface _backBuffer1, _backBuffer2;
@ -83,54 +96,141 @@ public:
Screen(SherlockEngine *vm);
virtual ~Screen();
/**
* Set the font to use for writing text on the screen
*/
void setFont(int fontNumber);
/**
* Handles updating any dirty areas of the screen Surface object to the physical screen
*/
void update();
/**
* Return the currently active palette
*/
void getPalette(byte palette[PALETTE_SIZE]);
/**
* Set the palette
*/
void setPalette(const byte palette[PALETTE_SIZE]);
/**
* Fades from the currently active palette to the passed palette
*/
int equalizePalette(const byte palette[PALETTE_SIZE]);
/**
* Fade out the palette to black
*/
void fadeToBlack(int speed = 2);
/**
* Fade in a given palette
*/
void fadeIn(const byte palette[PALETTE_SIZE], int speed = 2);
/**
* Do a random pixel transition in from _backBuffer surface to the screen
*/
void randomTransition();
/**
* Transition to the surface from _backBuffer using a vertical transition
*/
void verticalTransition();
/**
* Prints the text passed onto the back buffer at the given position and color.
* The string is then blitted to the screen
*/
void print(const Common::Point &pt, byte color, const char *formatStr, ...);
/**
* Print a strings onto the back buffer without blitting it to the screen
*/
void gPrint(const Common::Point &pt, byte color, const char *formatStr, ...);
/**
* Copies a section of the second back buffer into the main back buffer
*/
void restoreBackground(const Common::Rect &r);
/**
* Copies a given area to the screen
*/
void slamArea(int16 xp, int16 yp, int16 width, int16 height);
/**
* Copies a given area to the screen
*/
void slamRect(const Common::Rect &r);
/**
* Copy an image from the back buffer to the screen, taking care of both the
* new area covered by the shape as well as the old area, which must be restored
*/
void flushImage(ImageFrame *frame, const Common::Point &pt,
int16 *xp, int16 *yp, int16 *width, int16 *height);
/**
* Returns the width of a string in pixels
*/
int stringWidth(const Common::String &str);
/**
* Returns the width of a character in pixels
*/
int charWidth(char c);
/**
* Fills an area on the back buffer, and then copies it to the screen
*/
void vgaBar(const Common::Rect &r, int color);
/**
* Draws a button for use in the inventory, talk, and examine dialogs.
*/
void makeButton(const Common::Rect &bounds, int textX, const Common::String &str);
/**
* Prints an interface command with the first letter highlighted to indicate
* what keyboard shortcut is associated with it
*/
void buttonPrint(const Common::Point &pt, byte color, bool slamIt, const Common::String &str);
/**
* Draw a panel in the back buffer with a raised area effect around the edges
*/
void makePanel(const Common::Rect &r);
/**
* Draw a field in the back buffer with a raised area effect around the edges,
* suitable for text input.
*/
void makeField(const Common::Rect &r);
/**
* Sets the active back buffer pointer to a restricted sub-area of the first back buffer
*/
void setDisplayBounds(const Common::Rect &r);
/**
* Resets the active buffer pointer to point back to the full first back buffer
*/
void resetDisplayBounds();
/**
* Return the size of the current display window
*/
Common::Rect getDisplayBounds();
int fontNumber() const { return _fontNumber; }
/**
* Synchronize the data for a savegame
*/
void synchronize(Common::Serializer &s);
};

View file

@ -52,9 +52,6 @@ static const char *const SETUP_NAMES[12] = {
/*----------------------------------------------------------------*/
/**
* Draws the interface for the settings window
*/
void Settings::drawInteface(bool flag) {
People &people = *_vm->_people;
Screen &screen = *_vm->_screen;
@ -135,9 +132,6 @@ void Settings::drawInteface(bool flag) {
}
}
/**
* Draws the buttons for the settings dialog
*/
int Settings::drawButtons(const Common::Point &pt, int _key) {
Events &events = *_vm->_events;
People &people = *_vm->_people;
@ -209,13 +203,6 @@ int Settings::drawButtons(const Common::Point &pt, int _key) {
return found;
}
/**
* Handles input when the settings window is being shown
* @remarks Whilst this would in theory be better in the Journal class, since it displays in
* the user interface, it uses so many internal UI fields, that it sort of made some sense
* to put it in the UserInterface class.
*/
void Settings::show(SherlockEngine *vm) {
Events &events = *vm->_events;
People &people = *vm->_people;

View file

@ -36,10 +36,22 @@ private:
Settings(SherlockEngine *vm) : _vm(vm) {}
/**
* Draws the interface for the settings window
*/
void drawInteface(bool flag);
/**
* Draws the buttons for the settings dialog
*/
int drawButtons(const Common::Point &pt, int key);
public:
/**
* Handles input when the settings window is being shown
* @remarks Whilst this would in theory be better in the Journal class, since it displays in
* the user interface, it uses so many internal UI fields, that it sort of made some sense
* to put it in the UserInterface class.
*/
static void show(SherlockEngine *vm);
};

View file

@ -69,9 +69,6 @@ SherlockEngine::~SherlockEngine() {
delete _res;
}
/**
* Does basic initialization of the game engine
*/
void SherlockEngine::initialize() {
initGraphics(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT, false);
@ -108,9 +105,6 @@ void SherlockEngine::initialize() {
loadConfig();
}
/**
* Main method for running the game
*/
Common::Error SherlockEngine::run() {
// Initialize the engine
initialize();
@ -160,9 +154,6 @@ Common::Error SherlockEngine::run() {
return Common::kNoError;
}
/**
* Main loop for displaying a scene and handling all that occurs within it
*/
void SherlockEngine::sceneLoop() {
while (!shouldQuit() && _scene->_goToScene == -1) {
// See if a script needs to be completed from either a goto room code,
@ -187,9 +178,6 @@ void SherlockEngine::sceneLoop() {
}
/**
* Handle all player input
*/
void SherlockEngine::handleInput() {
_canLoadSave = true;
_events->pollEventsAndWait();
@ -201,11 +189,6 @@ void SherlockEngine::handleInput() {
_ui->handleInput();
}
/**
* Read the state of a global flag
* @remarks If a negative value is specified, it will return the inverse value
* of the positive flag number
*/
bool SherlockEngine::readFlags(int flagNum) {
bool value = _flags[ABS(flagNum)];
if (flagNum < 0)
@ -214,19 +197,12 @@ bool SherlockEngine::readFlags(int flagNum) {
return value;
}
/**
* Sets a global flag to either true or false depending on whether the specified
* flag is positive or negative
*/
void SherlockEngine::setFlags(int flagNum) {
_flags[ABS(flagNum)] = flagNum >= 0;
_scene->checkSceneFlags(true);
}
/**
* Load game configuration esttings
*/
void SherlockEngine::loadConfig() {
// Load sound settings
syncSoundSettings();
@ -240,9 +216,6 @@ void SherlockEngine::loadConfig() {
_people->_portraitsOn = ConfMan.getBool("portraits_on");
}
/**
* Saves game configuration information
*/
void SherlockEngine::saveConfig() {
ConfMan.setBool("mute", !_sound->_digitized);
ConfMan.setBool("music_mute", !_sound->_music);
@ -257,9 +230,6 @@ void SherlockEngine::saveConfig() {
ConfMan.flushToDisk();
}
/**
* Called by the engine when sound settings are updated
*/
void SherlockEngine::syncSoundSettings() {
Engine::syncSoundSettings();
@ -267,39 +237,24 @@ void SherlockEngine::syncSoundSettings() {
_sound->syncSoundSettings();
}
/**
* Synchronize the data for a savegame
*/
void SherlockEngine::synchronize(Common::Serializer &s) {
for (uint idx = 0; idx < _flags.size(); ++idx)
s.syncAsByte(_flags[idx]);
}
/**
* Returns true if a savegame can be loaded
*/
bool SherlockEngine::canLoadGameStateCurrently() {
return _canLoadSave;
}
/**
* Returns true if the game can be saved
*/
bool SherlockEngine::canSaveGameStateCurrently() {
return _canLoadSave;
}
/**
* Called by the GMM to load a savegame
*/
Common::Error SherlockEngine::loadGameState(int slot) {
_saves->loadGame(slot);
return Common::kNoError;
}
/**
* Called by the GMM to save the game
*/
Common::Error SherlockEngine::saveGameState(int slot, const Common::String &desc) {
_saves->saveGame(slot, desc);
return Common::kNoError;

View file

@ -68,18 +68,33 @@ class Resource;
class SherlockEngine : public Engine {
private:
/**
* Main loop for displaying a scene and handling all that occurs within it
*/
void sceneLoop();
/**
* Handle all player input
*/
void handleInput();
/**
* Load game configuration esttings
*/
void loadConfig();
protected:
/**
* Does basic initialization of the game engine
*/
virtual void initialize();
virtual void showOpening() = 0;
virtual void startScene() {}
/**
* Returns a list of features the game itself supports
*/
virtual bool hasFeature(EngineFeature f) const;
public:
const SherlockGameDescription *_gameDescription;
@ -108,29 +123,77 @@ public:
SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
virtual ~SherlockEngine();
/**
* Main method for running the game
*/
virtual Common::Error run();
/**
* Returns true if a savegame can be loaded
*/
virtual bool canLoadGameStateCurrently();
/**
* Returns true if the game can be saved
*/
virtual bool canSaveGameStateCurrently();
/**
* Called by the GMM to load a savegame
*/
virtual Common::Error loadGameState(int slot);
/**
* Called by the GMM to save the game
*/
virtual Common::Error saveGameState(int slot, const Common::String &desc);
/**
* Called by the engine when sound settings are updated
*/
virtual void syncSoundSettings();
/**
* Returns whether the version is a demo
*/
virtual bool isDemo() const;
/**
* Returns the Id of the game
*/
GameType getGameID() const;
Common::Language getLanguage() const;
/**
* Returns the platform the game's datafiles are for
*/
Common::Platform getPlatform() const;
Common::String getGameFile(int fileType);
/**
* Return a random number
*/
int getRandomNumber(int limit) { return _randomSource.getRandomNumber(limit - 1); }
/**
* Read the state of a global flag
* @remarks If a negative value is specified, it will return the inverse value
* of the positive flag number
*/
bool readFlags(int flagNum);
/**
* Sets a global flag to either true or false depending on whether the specified
* flag is positive or negative
*/
void setFlags(int flagNum);
/**
* Saves game configuration information
*/
void saveConfig();
/**
* Synchronize the data for a savegame
*/
void synchronize(Common::Serializer &s);
};

View file

@ -76,9 +76,6 @@ Sound::Sound(SherlockEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) {
}
}
/**
* Saves sound-related settings
*/
void Sound::syncSoundSettings() {
_digitized = !ConfMan.getBool("mute");
_music = !ConfMan.getBool("mute") && !ConfMan.getBool("music_mute");

View file

@ -61,19 +61,61 @@ public:
public:
Sound(SherlockEngine *vm, Audio::Mixer *mixer);
/**
* Saves sound-related settings
*/
void syncSoundSettings();
/**
* Load a sound
*/
void loadSound(const Common::String &name, int priority);
/**
* Play the sound in the specified resource
*/
bool playSound(const Common::String &name, WaitType waitType, int priority = 100, const char *libraryFilename = nullptr);
/**
* Play a previously loaded sound
*/
void playLoadedSound(int bufNum, WaitType waitType);
/**
* Free any previously loaded sounds
*/
void freeLoadedSounds();
/**
* Stop playing any active sound
*/
void stopSound();
/**
* Load a specified song
*/
int loadSong(int songNumber);
/**
* Start playing a song
*/
void startSong();
/**
* Free any currently loaded song
*/
void freeSong();
/**
* Play the specified music resource
*/
void playMusic(const Common::String &name);
/**
* Stop playing the music
*/
void stopMusic();
void stopSndFuncPtr(int v1, int v2);
void waitTimerRoland(uint time);
void freeDigiSound();

View file

@ -39,10 +39,6 @@ Surface::~Surface() {
free();
}
/**
* Sets up an internal surface with the specified dimensions that will be automatically freed
* when the surface object is destroyed
*/
void Surface::create(uint16 width, uint16 height) {
if (_freePixels)
free();
@ -51,23 +47,14 @@ void Surface::create(uint16 width, uint16 height) {
_freePixels = true;
}
/**
* Copy a surface into this one
*/
void Surface::blitFrom(const Graphics::Surface &src) {
blitFrom(src, Common::Point(0, 0));
}
/**
* Draws a surface at a given position within this surface
*/
void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) {
blitFrom(src, pt, Common::Rect(0, 0, src.w, src.h));
}
/**
* Draws a sub-section of a surface at a given position within this surface
*/
void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt,
const Common::Rect &srcBounds) {
Common::Rect srcRect = srcBounds;
@ -80,17 +67,11 @@ void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt,
}
}
/**
* Draws an image frame at a given position within this surface with transparency
*/
void Surface::transBlitFrom(const ImageFrame &src, const Common::Point &pt,
bool flipped, int overrideColor) {
transBlitFrom(src._frame, pt + src._offset, flipped, overrideColor);
}
/**
* Draws a surface at a given position within this surface with transparency
*/
void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt,
bool flipped, int overrideColor) {
Common::Rect drawRect(0, 0, src.w, src.h);
@ -125,24 +106,15 @@ void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &p
}
}
/**
* Fill a given area of the surface with a given color
*/
void Surface::fillRect(int x1, int y1, int x2, int y2, byte color) {
fillRect(Common::Rect(x1, y1, x2, y2), color);
}
/**
* Fill a given area of the surface with a given color
*/
void Surface::fillRect(const Common::Rect &r, byte color) {
Graphics::Surface::fillRect(r, color);
addDirtyRect(r);
}
/**
* Clips the given source bounds so the passed destBounds will be entirely on-screen
*/
bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) {
if (destBounds.left >= this->w || destBounds.top >= this->h ||
destBounds.right <= 0 || destBounds.bottom <= 0)
@ -172,9 +144,6 @@ bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) {
return true;
}
/**
* Clear the screen
*/
void Surface::clear() {
fillRect(Common::Rect(0, 0, this->w, this->h), 0);
}

View file

@ -33,6 +33,9 @@ class Surface : public Graphics::Surface {
private:
bool _freePixels;
/**
* Clips the given source bounds so the passed destBounds will be entirely on-screen
*/
bool clip(Common::Rect &srcBounds, Common::Rect &destBounds);
protected:
virtual void addDirtyRect(const Common::Rect &r) {}
@ -41,19 +44,53 @@ public:
Surface();
virtual ~Surface();
/**
* Sets up an internal surface with the specified dimensions that will be automatically freed
* when the surface object is destroyed
*/
void create(uint16 width, uint16 height);
/**
* Copy a surface into this one
*/
void blitFrom(const Graphics::Surface &src);
/**
* Draws a surface at a given position within this surface
*/
void blitFrom(const Graphics::Surface &src, const Common::Point &pt);
/**
* Draws a sub-section of a surface at a given position within this surface
*/
void blitFrom(const Graphics::Surface &src, const Common::Point &pt,
const Common::Rect &srcBounds);
/**
* Draws an image frame at a given position within this surface with transparency
*/
void transBlitFrom(const ImageFrame &src, const Common::Point &pt,
bool flipped = false, int overrideColor = 0);
/**
* Draws a surface at a given position within this surface with transparency
*/
void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt,
bool flipped = false, int overrideColor = 0);
/**
* Fill a given area of the surface with a given color
*/
void fillRect(int x1, int y1, int x2, int y2, byte color);
/**
* Fill a given area of the surface with a given color
*/
void fillRect(const Common::Rect &r, byte color);
/**
* Clear the screen
*/
void clear();
};

View file

@ -36,9 +36,6 @@ SequenceEntry::SequenceEntry() {
/*----------------------------------------------------------------*/
/**
* Load the data for a single statement within a talk file
*/
void Statement::synchronize(Common::SeekableReadStream &s) {
int length;
@ -108,9 +105,6 @@ Talk::Talk(SherlockEngine *vm) : _vm(vm) {
_scriptSaveIndex = -1;
}
/**
* Sets talk sequences
*/
void Talk::setSequences(const byte *talkSequences, const byte *stillSequences, int maxPeople) {
for (int idx = 0; idx < maxPeople; ++idx) {
STILL_SEQUENCES.push_back(TalkSequences(stillSequences));
@ -120,14 +114,6 @@ void Talk::setSequences(const byte *talkSequences, const byte *stillSequences, i
}
}
/**
* Called whenever a conversation or item script needs to be run. For standard conversations,
* it opens up a description window similar to how 'talk' does, but shows a 'reply' directly
* instead of waiting for a statement option.
* @remarks It seems that at some point, all item scripts were set up to use this as well.
* In their case, the conversation display is simply suppressed, and control is passed on to
* doScript to implement whatever action is required.
*/
void Talk::talkTo(const Common::String &filename) {
Events &events = *_vm->_events;
Inventory &inv = *_vm->_inventory;
@ -450,12 +436,6 @@ void Talk::talkTo(const Common::String &filename) {
events.setCursor(ARROW);
}
/**
* Main method for handling conversations when a character to talk to has been
* selected. It will make Holmes walk to the person to talk to, draws the
* interface window for the conversation and passes on control to give the
* player a list of options to make a selection from
*/
void Talk::talk(int objNum) {
Events &events = *_vm->_events;
People &people = *_vm->_people;
@ -549,17 +529,10 @@ void Talk::talk(int objNum) {
}
}
/**
* Clear loaded talk data
*/
void Talk::freeTalkVars() {
_statements.clear();
}
/**
* Opens the talk file 'talk.tlk' and searches the index for the specified
* conversation. If found, the data for that conversation is loaded
*/
void Talk::loadTalkFile(const Common::String &filename) {
Resources &res = *_vm->_res;
Sound &sound = *_vm->_sound;
@ -596,9 +569,6 @@ void Talk::loadTalkFile(const Common::String &filename) {
setTalkMap();
}
/**
* Remove any voice commands from a loaded statement list
*/
void Talk::stripVoiceCommands() {
for (uint sIdx = 0; sIdx < _statements.size(); ++sIdx) {
Statement &statement = _statements[sIdx];
@ -622,9 +592,6 @@ void Talk::stripVoiceCommands() {
}
}
/**
* Form a table of the display indexes for statements
*/
void Talk::setTalkMap() {
int statementNum = 0;
@ -642,9 +609,6 @@ void Talk::setTalkMap() {
}
}
/**
* Draws the interface for conversation display
*/
void Talk::drawInterface() {
Screen &screen = *_vm->_screen;
Surface &bb = *screen._backBuffer;
@ -673,10 +637,6 @@ void Talk::drawInterface() {
}
}
/**
* Display a list of statements in a window at the bottom of the screen that the
* player can select from.
*/
bool Talk::displayTalk(bool slamIt) {
Screen &screen = *_vm->_screen;
int yp = CONTROLS_Y + 14;
@ -761,9 +721,6 @@ bool Talk::displayTalk(bool slamIt) {
return done;
}
/**
* Prints a single conversation option in the interface window
*/
int Talk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt) {
Screen &screen = *_vm->_screen;
int idx = lineNum;
@ -852,17 +809,10 @@ int Talk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt
return lineY;
}
/**
* Clears the stack of pending object sequences associated with speakers in the scene
*/
void Talk::clearSequences() {
_sequenceStack.clear();
}
/**
* Pulls a background object sequence from the sequence stack and restore's the
* object's sequence
*/
void Talk::pullSequence() {
Scene &scene = *_vm->_scene;
@ -885,10 +835,6 @@ void Talk::pullSequence() {
}
}
/**
* Push the sequence of a background object that's an NPC that needs to be
* saved onto the sequence stack.
*/
void Talk::pushSequence(int speaker) {
People &people = *_vm->_people;
Scene &scene = *_vm->_scene;
@ -918,9 +864,6 @@ void Talk::pushSequence(int speaker) {
error("script stack overflow");
}
/**
* Change the sequence of the scene background object associated with the current speaker.
*/
void Talk::setSequence(int speaker) {
People &people = *_vm->_people;
Scene &scene = *_vm->_scene;
@ -950,10 +893,6 @@ void Talk::setSequence(int speaker) {
}
}
/**
* Change the sequence of a background object corresponding to a given speaker.
* The new sequence will display the character as "listening"
*/
void Talk::setStillSeq(int speaker) {
People &people = *_vm->_people;
Scene &scene = *_vm->_scene;
@ -983,10 +922,6 @@ void Talk::setStillSeq(int speaker) {
}
}
/**
* Parses a reply for control codes and display text. The found text is printed within
* the text window, handles delays, animations, and animating portraits.
*/
void Talk::doScript(const Common::String &script) {
Animation &anim = *_vm->_animation;
Events &events = *_vm->_events;
@ -1631,10 +1566,6 @@ void Talk::doScript(const Common::String &script) {
}
}
/**
* When the talk window has been displayed, waits a period of time proportional to
* the amount of text that's been displayed
*/
int Talk::waitForMore(int delay) {
Events &events = *_vm->_events;
People &people = *_vm->_people;
@ -1714,9 +1645,6 @@ int Talk::waitForMore(int delay) {
return key2;
}
/**
* Pops an entry off of the script stack
*/
void Talk::popStack() {
if (!_scriptStack.empty()) {
ScriptStackEntry scriptEntry = _scriptStack.pop();
@ -1727,9 +1655,6 @@ void Talk::popStack() {
}
}
/**
* Synchronize the data for a savegame
*/
void Talk::synchronize(Common::Serializer &s) {
for (int idx = 0; idx < MAX_TALK_FILES; ++idx) {
TalkHistoryEntry &he = _talkHistory[idx];

View file

@ -99,6 +99,9 @@ struct Statement {
int _talkMap;
Common::Rect _talkPos;
/**
* Load the data for a single statement within a talk file
*/
void synchronize(Common::SeekableReadStream &s);
};
@ -141,15 +144,37 @@ private:
int _talkToFlag;
int _scriptSaveIndex;
private:
/**
* Remove any voice commands from a loaded statement list
*/
void stripVoiceCommands();
/**
* Form a table of the display indexes for statements
*/
void setTalkMap();
/**
* Display a list of statements in a window at the bottom of the screen that the
* player can select from.
*/
bool displayTalk(bool slamIt);
/**
* Prints a single conversation option in the interface window
*/
int talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt);
/**
* Parses a reply for control codes and display text. The found text is printed within
* the text window, handles delays, animations, and animating portraits.
*/
void doScript(const Common::String &script);
/**
* When the talk window has been displayed, waits a period of time proportional to
* the amount of text that's been displayed
*/
int waitForMore(int delay);
public:
bool _talkToAbort;
@ -161,30 +186,90 @@ public:
int _converseNum;
public:
Talk(SherlockEngine *vm);
/**
* Sets talk sequences
*/
void setSequences(const byte *talkSequences, const byte *stillSequences,
int maxPeople);
Statement &operator[](int idx) { return _statements[idx]; }
/**
* Called whenever a conversation or item script needs to be run. For standard conversations,
* it opens up a description window similar to how 'talk' does, but shows a 'reply' directly
* instead of waiting for a statement option.
* @remarks It seems that at some point, all item scripts were set up to use this as well.
* In their case, the conversation display is simply suppressed, and control is passed on to
* doScript to implement whatever action is required.
*/
void talkTo(const Common::String &filename);
/**
* Main method for handling conversations when a character to talk to has been
* selected. It will make Holmes walk to the person to talk to, draws the
* interface window for the conversation and passes on control to give the
* player a list of options to make a selection from
*/
void talk(int objNum);
/**
* Clear loaded talk data
*/
void freeTalkVars();
/**
* Draws the interface for conversation display
*/
void drawInterface();
/**
* Opens the talk file 'talk.tlk' and searches the index for the specified
* conversation. If found, the data for that conversation is loaded
*/
void loadTalkFile(const Common::String &filename);
/**
* Change the sequence of a background object corresponding to a given speaker.
* The new sequence will display the character as "listening"
*/
void setStillSeq(int speaker);
/**
* Clears the stack of pending object sequences associated with speakers in the scene
*/
void clearSequences();
/**
* Pulls a background object sequence from the sequence stack and restore's the
* object's sequence
*/
void pullSequence();
/**
* Push the sequence of a background object that's an NPC that needs to be
* saved onto the sequence stack.
*/
void pushSequence(int speaker);
/**
* Change the sequence of the scene background object associated with the current speaker.
*/
void setSequence(int speaker);
/**
* Returns true if the script stack is empty
*/
bool isSequencesEmpty() const { return _scriptStack.empty(); }
/**
* Pops an entry off of the script stack
*/
void popStack();
/**
* Synchronize the data for a savegame
*/
void synchronize(Common::Serializer &s);
};

View file

@ -122,18 +122,12 @@ UserInterface::~UserInterface() {
delete _controlPanel;
}
/**
* Resets the user interface
*/
void UserInterface::reset() {
_oldKey = -1;
_help = _oldHelp = -1;
_oldTemp = _temp = -1;
}
/**
* Draw the user interface onto the screen's back buffers
*/
void UserInterface::drawInterface(int bufferNum) {
Screen &screen = *_vm->_screen;
@ -145,9 +139,6 @@ void UserInterface::drawInterface(int bufferNum) {
screen._backBuffer2.fillRect(0, INFO_LINE, SHERLOCK_SCREEN_WIDTH, INFO_LINE + 10, INFO_BLACK);
}
/**
* Main input handler for the user interface
*/
void UserInterface::handleInput() {
Events &events = *_vm->_events;
Inventory &inv = *_vm->_inventory;
@ -403,9 +394,6 @@ void UserInterface::handleInput() {
}
}
/**
* Draws the image for a user interface button in the down/pressed state.
*/
void UserInterface::depressButton(int num) {
Screen &screen = *_vm->_screen;
Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]);
@ -415,10 +403,6 @@ void UserInterface::depressButton(int num) {
screen.slamArea(pt.x, pt.y, pt.x + s.w, pt.y + s.h);
}
/**
* Draws the image for the given user interface button in the up
* (not selected) position
*/
void UserInterface::restoreButton(int num) {
Screen &screen = *_vm->_screen;
Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]);
@ -434,10 +418,6 @@ void UserInterface::restoreButton(int num) {
}
}
/**
* If he mouse button is pressed, then calls depressButton to draw the button
* as pressed; if not, it will show it as released with a call to "restoreButton".
*/
void UserInterface::pushButton(int num) {
Events &events = *_vm->_events;
_oldKey = -1;
@ -455,11 +435,6 @@ void UserInterface::pushButton(int num) {
restoreButton(num);
}
/**
* By the time this method has been called, the graphics for the button change
* have already been drawn. This simply takes care of switching the mode around
* accordingly
*/
void UserInterface::toggleButton(int num) {
Screen &screen = *_vm->_screen;
@ -488,9 +463,6 @@ void UserInterface::toggleButton(int num) {
}
}
/**
* Clears the info line of the screen
*/
void UserInterface::clearInfo() {
if (_infoFlag) {
_vm->_screen->vgaBar(Common::Rect(16, INFO_LINE, SHERLOCK_SCREEN_WIDTH - 19,
@ -500,9 +472,6 @@ void UserInterface::clearInfo() {
}
}
/**
* Clear any active text window
*/
void UserInterface::clearWindow() {
if (_windowOpen) {
_vm->_screen->vgaBar(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2,
@ -510,9 +479,6 @@ void UserInterface::clearWindow() {
}
}
/**
* Handles counting down whilst checking for input, then clears the info line.
*/
void UserInterface::whileMenuCounter() {
if (!(--_menuCounter) || _vm->_events->checkInput()) {
_menuCounter = 0;
@ -521,10 +487,6 @@ void UserInterface::whileMenuCounter() {
}
}
/**
* Creates a text window and uses it to display the in-depth description
* of the highlighted object
*/
void UserInterface::examine() {
Events &events = *_vm->_events;
Inventory &inv = *_vm->_inventory;
@ -576,9 +538,6 @@ void UserInterface::examine() {
}
}
/**
* Print the name of an object in the scene
*/
void UserInterface::lookScreen(const Common::Point &pt) {
Events &events = *_vm->_events;
Inventory &inv = *_vm->_inventory;
@ -692,9 +651,6 @@ void UserInterface::lookScreen(const Common::Point &pt) {
}
}
/**
* Gets the item in the inventory the mouse is on and display's it's description
*/
void UserInterface::lookInv() {
Events &events = *_vm->_events;
Inventory &inv = *_vm->_inventory;
@ -720,9 +676,6 @@ void UserInterface::lookInv() {
}
}
/**
* Handles input when the file list window is being displayed
*/
void UserInterface::doEnvControl() {
Events &events = *_vm->_events;
SaveManager &saves = *_vm->_saves;
@ -1026,9 +979,6 @@ void UserInterface::doEnvControl() {
}
}
/**
* Handle input whilst the inventory is active
*/
void UserInterface::doInvControl() {
Events &events = *_vm->_events;
Inventory &inv = *_vm->_inventory;
@ -1253,9 +1203,6 @@ void UserInterface::doInvControl() {
}
}
/**
* Handles waiting whilst an object's description window is open.
*/
void UserInterface::doLookControl() {
Events &events = *_vm->_events;
Inventory &inv = *_vm->_inventory;
@ -1317,9 +1264,6 @@ void UserInterface::doLookControl() {
}
}
/**
* Handles input until one of the user interface buttons/commands is selected
*/
void UserInterface::doMainControl() {
Events &events = *_vm->_events;
Inventory &inv = *_vm->_inventory;
@ -1458,9 +1402,6 @@ void UserInterface::doMainControl() {
}
}
/**
* Handles the input for the MOVE, OPEN, and CLOSE commands
*/
void UserInterface::doMiscControl(int allowed) {
Events &events = *_vm->_events;
Scene &scene = *_vm->_scene;
@ -1510,9 +1451,6 @@ void UserInterface::doMiscControl(int allowed) {
}
}
/**
* Handles input for picking up items
*/
void UserInterface::doPickControl() {
Events &events = *_vm->_events;
Scene &scene = *_vm->_scene;
@ -1536,10 +1474,6 @@ void UserInterface::doPickControl() {
}
}
/**
* Handles input when in talk mode. It highlights the buttons and available statements,
* and handles allowing the user to click on them
*/
void UserInterface::doTalkControl() {
Events &events = *_vm->_events;
Journal &journal = *_vm->_journal;
@ -1790,12 +1724,6 @@ void UserInterface::doTalkControl() {
}
}
/**
* Handles events when the Journal is active.
* @remarks Whilst this would in theory be better in the Journal class, since it displays in
* the user interface, it uses so many internal UI fields, that it sort of made some sense
* to put it in the UserInterface class.
*/
void UserInterface::journalControl() {
Events &events = *_vm->_events;
Journal &journal = *_vm->_journal;
@ -1844,9 +1772,6 @@ void UserInterface::journalControl() {
screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
}
/**
* Print the description of an object
*/
void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) {
Events &events = *_vm->_events;
Inventory &inv = *_vm->_inventory;
@ -2015,16 +1940,10 @@ void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) {
}
}
/**
* Print the previously selected object's decription
*/
void UserInterface::printObjectDesc() {
printObjectDesc(_cAnimStr, true);
}
/**
* Displays a passed window by gradually scrolling it vertically on-screen
*/
void UserInterface::summonWindow(const Surface &bgSurface, bool slideUp) {
Events &events = *_vm->_events;
Screen &screen = *_vm->_screen;
@ -2065,9 +1984,6 @@ void UserInterface::summonWindow(const Surface &bgSurface, bool slideUp) {
_windowOpen = true;
}
/**
* Slide the window stored in the back buffer onto the screen
*/
void UserInterface::summonWindow(bool slideUp, int height) {
Screen &screen = *_vm->_screen;
@ -2085,10 +2001,6 @@ void UserInterface::summonWindow(bool slideUp, int height) {
summonWindow(tempSurface, slideUp);
}
/**
* Close a currently open window
* @param flag 0 = slide old window down, 1 = slide prior UI back up
*/
void UserInterface::banishWindow(bool slideUp) {
Events &events = *_vm->_events;
Screen &screen = *_vm->_screen;
@ -2155,9 +2067,6 @@ void UserInterface::banishWindow(bool slideUp) {
_menuMode = STD_MODE;
}
/**
* Checks to see whether a USE action is valid on the given object
*/
void UserInterface::checkUseAction(const UseType *use, const Common::String &invName,
const char *const messages[], int objNum, int giveMode) {
Events &events = *_vm->_events;
@ -2251,9 +2160,6 @@ void UserInterface::checkUseAction(const UseType *use, const Common::String &inv
events.setCursor(ARROW);
}
/**
* Called for OPEN, CLOSE, and MOVE actions are being done
*/
void UserInterface::checkAction(ActionType &action, const char *const messages[], int objNum) {
Events &events = *_vm->_events;
People &people = *_vm->_people;

View file

@ -90,29 +90,93 @@ private:
int _find;
int _oldUse;
private:
/**
* Draws the image for a user interface button in the down/pressed state.
*/
void depressButton(int num);
/**
* If he mouse button is pressed, then calls depressButton to draw the button
* as pressed; if not, it will show it as released with a call to "restoreButton".
*/
void pushButton(int num);
/**
* By the time this method has been called, the graphics for the button change
* have already been drawn. This simply takes care of switching the mode around
* accordingly
*/
void toggleButton(int num);
/**
* Creates a text window and uses it to display the in-depth description
* of the highlighted object
*/
void examine();
/**
* Print the name of an object in the scene
*/
void lookScreen(const Common::Point &pt);
/**
* Gets the item in the inventory the mouse is on and display's it's description
*/
void lookInv();
/**
* Handles input when the file list window is being displayed
*/
void doEnvControl();
/**
* Handle input whilst the inventory is active
*/
void doInvControl();
/**
* Handles waiting whilst an object's description window is open.
*/
void doLookControl();
/**
* Handles input until one of the user interface buttons/commands is selected
*/
void doMainControl();
/**
* Handles the input for the MOVE, OPEN, and CLOSE commands
*/
void doMiscControl(int allowed);
/**
* Handles input for picking up items
*/
void doPickControl();
/**
* Handles input when in talk mode. It highlights the buttons and available statements,
* and handles allowing the user to click on them
*/
void doTalkControl();
/**
* Handles events when the Journal is active.
* @remarks Whilst this would in theory be better in the Journal class, since it displays in
* the user interface, it uses so many internal UI fields, that it sort of made some sense
* to put it in the UserInterface class.
*/
void journalControl();
/**
* Checks to see whether a USE action is valid on the given object
*/
void checkUseAction(const UseType *use, const Common::String &invName, const char *const messages[],
int objNum, int giveMode);
/**
* Called for OPEN, CLOSE, and MOVE actions are being done
*/
void checkAction(ActionType &action, const char *const messages[], int objNum);
public:
MenuMode _menuMode;
@ -128,24 +192,66 @@ public:
UserInterface(SherlockEngine *vm);
~UserInterface();
/**
* Resets the user interface
*/
void reset();
/**
* Draw the user interface onto the screen's back buffers
*/
void drawInterface(int bufferNum = 3);
/**
* Main input handler for the user interface
*/
void handleInput();
/**
* Clears the info line of the screen
*/
void clearInfo();
/**
* Clear any active text window
*/
void clearWindow();
/**
* Handles counting down whilst checking for input, then clears the info line.
*/
void whileMenuCounter();
/**
* Print the description of an object
*/
void printObjectDesc(const Common::String &str, bool firstTime);
/**
* Print the previously selected object's decription
*/
void printObjectDesc();
/**
* Displays a passed window by gradually scrolling it vertically on-screen
*/
void summonWindow(const Surface &bgSurface, bool slideUp = true);
/**
* Slide the window stored in the back buffer onto the screen
*/
void summonWindow(bool slideUp = true, int height = CONTROLS_Y);
/**
* Close a currently open window
* @param flag 0 = slide old window down, 1 = slide prior UI back up
*/
void banishWindow(bool slideUp = true);
/**
* Draws the image for the given user interface button in the up
* (not selected) position
*/
void restoreButton(int num);
};