diff options
author | Paul Gilbert | 2015-03-26 21:40:24 -0400 |
---|---|---|
committer | Paul Gilbert | 2015-03-26 21:40:24 -0400 |
commit | 5e45abcca4b76955cc0ebcfa54a1b9f9be12bfa0 (patch) | |
tree | 71a94f2d967c5ca51d76073f46a427ecfe96bd3c /engines/sherlock | |
parent | 0f52dcc561fbe05816452d2a20b3f09f6cd9e0fa (diff) | |
download | scummvm-rg350-5e45abcca4b76955cc0ebcfa54a1b9f9be12bfa0.tar.gz scummvm-rg350-5e45abcca4b76955cc0ebcfa54a1b9f9be12bfa0.tar.bz2 scummvm-rg350-5e45abcca4b76955cc0ebcfa54a1b9f9be12bfa0.zip |
SHERLOCK: Implemented printObjectDesc
Diffstat (limited to 'engines/sherlock')
-rw-r--r-- | engines/sherlock/inventory.cpp | 6 | ||||
-rw-r--r-- | engines/sherlock/inventory.h | 4 | ||||
-rw-r--r-- | engines/sherlock/objects.cpp | 10 | ||||
-rw-r--r-- | engines/sherlock/objects.h | 6 | ||||
-rw-r--r-- | engines/sherlock/scene.cpp | 53 | ||||
-rw-r--r-- | engines/sherlock/scene.h | 6 | ||||
-rw-r--r-- | engines/sherlock/screen.cpp | 22 | ||||
-rw-r--r-- | engines/sherlock/screen.h | 16 | ||||
-rw-r--r-- | engines/sherlock/user_interface.cpp | 252 | ||||
-rw-r--r-- | engines/sherlock/user_interface.h | 16 |
10 files changed, 316 insertions, 75 deletions
diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp index 2a277a6331..e103213eb5 100644 --- a/engines/sherlock/inventory.cpp +++ b/engines/sherlock/inventory.cpp @@ -36,7 +36,7 @@ Inventory::~Inventory() { freeGraphics(); } -void Inventory::freeInventory() { +void Inventory::freeInv() { freeGraphics(); _names.clear(); @@ -116,4 +116,8 @@ int Inventory::findInv(const Common::String &name) { return result; } +void Inventory::putInv(int slamit) { + // TODO +} + } // End of namespace Sherlock diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h index e561f0318a..01a325e382 100644 --- a/engines/sherlock/inventory.h +++ b/engines/sherlock/inventory.h @@ -54,13 +54,15 @@ public: Inventory(SherlockEngine *vm); ~Inventory(); - void freeInventory(); + void freeInv(); void loadInv(); void loadGraphics(); int findInv(const Common::String &name); + + void putInv(int slamit); }; } // End of namespace Sherlock diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index 7e72eff1e9..39a9cf8014 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -404,11 +404,11 @@ void Object::setVm(SherlockEngine *vm) { * Load the object data from the passed stream */ void Object::synchronize(Common::SeekableReadStream &s) { - char buffer[12]; + char buffer[41]; s.read(buffer, 12); _name = Common::String(buffer); - - s.read(_description, 41); + s.read(buffer, 41); + _description = Common::String(buffer); _examine.clear(); _sequences = nullptr; @@ -851,14 +851,14 @@ int Object::checkNameForCodes(const Common::String &name, Common::StringArray *m int messageNum = atoi(name.c_str() + 1); ui._infoFlag++; ui.clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, INFO_BACKGROUND, + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, (*messages)[messageNum].c_str()); ui._menuCounter = 25; } else if (name.hasPrefix("@")) { // Message attached to canimation ui._infoFlag++; ui.clearInfo(); - screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, INFO_BACKGROUND, + screen.print(Common::Point(0, INFO_LINE + 1), INFO_FOREGROUND, "%s", name.c_str() + 1); printed = true; ui._menuCounter = 25; diff --git a/engines/sherlock/objects.h b/engines/sherlock/objects.h index 4944681ab3..26ad1d3900 100644 --- a/engines/sherlock/objects.h +++ b/engines/sherlock/objects.h @@ -123,8 +123,8 @@ public: }; struct ActionType { - char _cAnimNum; - char _cAnimSpeed; // if high bit set, play in reverse + int8 _cAnimNum; + uint8 _cAnimSpeed; // if high bit set, play in reverse Common::String _names[4]; void synchronize(Common::SeekableReadStream &s); @@ -155,7 +155,7 @@ public: static void setVm(SherlockEngine *vm); public: Common::String _name; // Name - char _description[41]; // Description lines + Common::String _description; // Description lines Common::String _examine; // Examine in-depth description int _sequenceOffset; uint8 *_sequences; // Holds animation sequences diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 0cb6d7721b..6442538794 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -162,7 +162,7 @@ void Scene::selectScene() { */ void Scene::freeScene() { _vm->_talk->freeTalkVars(); - _vm->_inventory->freeInventory(); + _vm->_inventory->freeInv(); _vm->_sound->freeSong(); _vm->_sound->freeLoadedSounds(); @@ -849,6 +849,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { People &people = *_vm->_people; Resources &res = *_vm->_res; Talk &talk = *_vm->_talk; + UserInterface &ui = *_vm->_ui; Common::Point tpPos, walkPos; int tpDir, walkDir; int tFrames = 0; @@ -993,7 +994,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) { while (--frames) { if (frames == pauseFrame) - printObjDesc(_cAnimStr, true); + ui.printObjectDesc(); doBgAnim(); @@ -1049,54 +1050,6 @@ int Scene::startCAnim(int cAnimNum, int playRate) { } /** - * Print the description of an object - */ -void Scene::printObjDesc(const Common::String &str, bool firstTime) { - /* TODO - - Events &events = *_vm->_events; - Screen &screen = *_vm->_screen; - Talk &talk = *_vm->_talk; - int savedSelector; - - if (str.hasPrefix("_")) { - _lookScriptFlag = true; - events.setCursor(MAGNIFY); - savedSelector = _selector; - talk.talkTo(str.c_str() + 1); - _lookScriptFlag = false; - - if (talk._talkToAbort) { - events.setCursor(ARROW); - return; - } - - // Check if looking at an inventory object - if (!_invLookFlag) { - // See if this look was called by a right button click or not - if (!_lookHelp) { - // If it wasn't a right button click, then we need depress - // the look button before we close the window. So save a copy of the - // menu area, and draw the controls onto it - Surface tempSurface((*_controls)[0]._frame->w, (*_controls)[0]._frame->h); - tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0), - Common::Rect(MENU_POINTS[0][0], MENU_POINTS[0][1], - MENU_POINTS[0][0] + tempSurface.w, MENU_POINTS[0][1] + tempSurface.h)); - screen._backBuffer2.transBlitFrom((*_controls)[0]._frame, - Common::Point(MENU_POINTS[0][0], MENU_POINTS[0][1])); - - banishWindow(1); - events.setCursor(MAGNIFY); - - } - } - } - - // TODO - */ -} - -/** * Animate all objects and people. */ void Scene::doBgAnim() { diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h index 1b3a730179..27313e34af 100644 --- a/engines/sherlock/scene.h +++ b/engines/sherlock/scene.h @@ -96,10 +96,7 @@ class Scene { private: SherlockEngine *_vm; Common::String _rrmName; - int _cAnimFramePause; - Common::String _cAnimStr; InvMode _invMode; - bool _lookScriptFlag; int _selector; bool _invLookFlag; bool _lookHelp; @@ -154,6 +151,7 @@ public: int _animating; bool _doBgAnimDone; int _tempFadeStyle; + int _cAnimFramePause; public: Scene(SherlockEngine *vm); ~Scene(); @@ -166,8 +164,6 @@ public: Exit *checkForExit(const Common::Rect &r); - void printObjDesc(const Common::String &str, bool firstTime); - int startCAnim(int cAnimNum, int playRate); int toggleObject(const Common::String &name); diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 098d43e827..646802094f 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -309,7 +309,7 @@ void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, * 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, int fgColor, int bgColor, const char *format, ...) { +void Screen::print(const Common::Point &pt, int color, const char *format, ...) { // Create the string to display char buffer[100]; va_list args; @@ -334,13 +334,31 @@ void Screen::print(const Common::Point &pt, int fgColor, int bgColor, const char textBounds.moveTo(textBounds.left, SHERLOCK_SCREEN_HEIGHT - _fontHeight); // Write out the string at the given position - writeString(str, Common::Point(textBounds.left, textBounds.top), fgColor); + writeString(str, Common::Point(textBounds.left, textBounds.top), color); // Copy the affected area to the screen slamRect(textBounds); } /** + * Print a strings onto the back buffer without blitting it to the screen + */ +void Screen::gPrint(const Common::Point &pt, int color, const char *format, ...) { + // Create the string to display + char buffer[100]; + va_list args; + + va_start(args, format); + vsprintf(buffer, format, args); + va_end(args); + Common::String str(buffer); + + // Print the text + writeString(str, pt, color); +} + + +/** * Returns the width of a string in pixels */ int Screen::stringWidth(const Common::String &str) { diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 239067b1cc..45a50e7e85 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -35,10 +35,15 @@ namespace Sherlock { #define PALETTE_COUNT 256 #define VGA_COLOR_TRANS(x) ((x) * 255 / 63) -#define INFO_BLACK 1 -#define INFO_FOREGROUND 11 -#define INFO_BACKGROUND 1 - +enum { + INFO_BLACK = 1, + INFO_FOREGROUND = 11, + INFO_BACKGROUND = 1, + BORDER_COLOR = 237, + INV_FOREGROUND = 14, + INV_BACKGROUND = 1, + COM_FOREGROUND = 15 +}; class SherlockEngine; @@ -85,7 +90,8 @@ public: void verticalTransition(); - void print(const Common::Point &pt, int fgColor, int bgColor, const char *format, ...); + void print(const Common::Point &pt, int color, const char *format, ...); + void gPrint(const Common::Point &pt, int color, const char *format, ...); void restoreBackground(const Common::Rect &r); diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index df3ac9352c..b0388b4e29 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -54,6 +54,8 @@ const int INVENTORY_POINTS[8][3] = { }; const char COMMANDS[13] = "LMTPOCIUGJFS"; +const char *const PRESS_KEY_FOR_MORE = "Press any Key for More."; +const char *const PRESS_KEY_TO_CONTINUE = "Press any Key to Continue."; /*----------------------------------------------------------------*/ @@ -74,6 +76,11 @@ UserInterface::UserInterface(SherlockEngine *vm) : _vm(vm) { _keyboardInput = false; _invMode = 0; _pause = false; + _cNum = 0; + _selector = _oldSelector = -1; + _windowBounds = Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH - 1, + SHERLOCK_SCREEN_HEIGHT - 1); + _windowStyle = 0; _controls = new ImageFile("menu.all"); } @@ -183,8 +190,7 @@ void UserInterface::handleInput() { if (_help != -1 && (scene._bgShapes[_bgFound]._description[0] != 32 && scene._bgShapes[_bgFound]._description[0])) screen.print(Common::Point(0, INFO_LINE + 1), - INFO_FOREGROUND, INFO_BACKGROUND, "%s", - scene._bgShapes[_bgFound]._description); + INFO_FOREGROUND, scene._bgShapes[_bgFound]._description.c_str()); _oldBgFound = _bgFound; } @@ -457,8 +463,53 @@ void UserInterface::whileMenuCounter() { } } +/** + * Creates a text window and uses it to display the in-depth description + * of the highlighted object + */ void UserInterface::examine() { - // TODO + Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; + People &people = *_vm->_people; + Scene &scene = *_vm->_scene; + Talk &talk = *_vm->_talk; + Common::Point pt = events.mousePos(); + int canimSpeed; + + if (pt.y < (CONTROLS_Y + 9)) { + Object &obj = scene._bgShapes[_bgFound]; + + if (obj._lookcAnim != 0) { + canimSpeed = ((obj._lookcAnim & 0xe0) >> 5) + 1; + scene._cAnimFramePause = obj._lookFrames; + _cAnimStr = obj._examine; + _cNum = (obj._lookcAnim & 0x1f) - 1; + + scene.startCAnim(_cNum, canimSpeed); + } else if (obj._lookPosition.y != 0) { + // Need to walk to the object to be examined + people.walkToCoords(obj._lookPosition, obj._lookFacing); + } + + if (talk._talkToAbort) { + _cAnimStr = obj._examine; + if (obj._lookFlag) + _vm->setFlags(obj._lookFlag); + } + } else { + // Looking at an inventory item + _cAnimStr = inv[_selector]._examine; + if (inv[_selector]._lookFlag) + _vm->setFlags(inv[_selector]._lookFlag); + } + + if (!talk._talkToAbort) { + if (!scene._cAnimFramePause) + printObjectDesc(_cAnimStr, true); + else + // description was already printed in startCAnimation + scene._cAnimFramePause = 0; + } } void UserInterface::lookScreen(const Common::Point &pt) { @@ -497,4 +548,199 @@ void UserInterface::doTalkControl() { // TODO } + +/** +* Print the description of an object +*/ +void UserInterface::printObjectDesc(const Common::String &str, bool firstTime) { + Events &events = *_vm->_events; + Inventory &inv = *_vm->_inventory; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + int savedSelector; + + if (str.hasPrefix("_")) { + _lookScriptFlag = true; + events.setCursor(MAGNIFY); + savedSelector = _selector; + talk.talkTo(str.c_str() + 1); + _lookScriptFlag = false; + + if (talk._talkToAbort) { + events.setCursor(ARROW); + return; + } + + // Check if looking at an inventory object + if (!_invLookFlag) { + // See if this look was called by a right button click or not + if (!_lookHelp) { + // If it wasn't a right button click, then we need depress + // the look button before we close the window. So save a copy of the + // menu area, and draw the controls onto it + Surface tempSurface((*_controls)[0]._frame.w, (*_controls)[0]._frame.h); + Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]); + + tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0), + Common::Rect(pt.x, pt.y, pt.x + tempSurface.w, pt.y + tempSurface.h)); + screen._backBuffer2.transBlitFrom((*_controls)[0]._frame, pt); + + banishWindow(1); + events.setCursor(MAGNIFY); + _windowBounds.top = CONTROLS_Y1; + _key = _oldKey = COMMANDS[LOOK_MODE - 1]; + _temp = _oldTemp = 0; + _menuMode = LOOK_MODE; + events.clearEvents(); + + screen._backBuffer2.blitFrom(tempSurface, pt); + } else { + events.setCursor(ARROW); + banishWindow(true); + _windowBounds.top = CONTROLS_Y1; + _key = _oldKey = -1; + _temp = _oldTemp = 0; + _menuMode = STD_MODE; + _lookHelp = 0; + events.clearEvents(); + } + } else { + // Looking at an inventory object + _selector = _oldSelector = savedSelector; + + // Reload the inventory graphics and draw the inventory + inv.loadInv(); + inv.putInv(2); + inv.freeInv(); + banishWindow(1); + + _windowBounds.top = CONTROLS_Y1; + _key = _oldKey = COMMANDS[INV_MODE - 1]; + _temp = _oldTemp = 0; + events.clearEvents(); + + _invLookFlag = 0; + _menuMode = INV_MODE; + _windowOpen = true; + } + + return; + } + + if (firstTime) { + // Only draw the border on the first call + _infoFlag = true; + clearInfo(); + + screen.bar(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, + CONTROLS_Y1 + 10), BORDER_COLOR); + screen.bar(Common::Rect(0, CONTROLS_Y + 10, 1, SHERLOCK_SCREEN_HEIGHT - 1), + BORDER_COLOR); + screen.bar(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y + 10, + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + screen.bar(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 1, SHERLOCK_SCREEN_WIDTH, + SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR); + } + + // Clear background + screen.bar(Common::Rect(2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH - 2, + SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND); + + _windowBounds.top = CONTROLS_Y; + events.clearEvents(); + + bool endOfStr = false; + const char *msgP = str.c_str(); + for (int lineNum = 0; lineNum < 5 && !endOfStr; ++lineNum) { + int width = 0; + const char *lineStartP = msgP; + + // Determine how much can be displayed on the line + do { + width += screen.charWidth(*msgP++); + } while (width < 300 && *msgP); + + if (*msgP) + --msgP; + else + endOfStr = true; + + // If the line needs to be wrapped, scan backwards to find + // the end of the previous word as a splitting point + if (width >= 300) { + while (*msgP != ' ') + --msgP; + endOfStr = false; + } + + // Print out the line + Common::String line(lineStartP, msgP); + screen.gPrint(Common::Point(16, CONTROLS_Y + 12 + lineNum * 9), + INV_FOREGROUND, line.c_str()); + } + + // Handle display depending on whether all the message was shown + if (!endOfStr) { + makeButton(Common::Rect(46, CONTROLS_Y, 272, CONTROLS_Y + 10), + (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(PRESS_KEY_FOR_MORE)) / 2, + PRESS_KEY_FOR_MORE); + screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - + screen.stringWidth(PRESS_KEY_FOR_MORE)) / 2, CONTROLS_Y), + COM_FOREGROUND, "P"); + _descStr = msgP; + } else { + makeButton(Common::Rect(46, CONTROLS_Y, 272, CONTROLS_Y + 10), + (SHERLOCK_SCREEN_WIDTH - screen.stringWidth(PRESS_KEY_TO_CONTINUE)) / 2, + PRESS_KEY_FOR_MORE); + screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - + screen.stringWidth(PRESS_KEY_TO_CONTINUE)) / 2, CONTROLS_Y), + COM_FOREGROUND, "P"); + _descStr = ""; + } + + if (firstTime) { + if (!_windowStyle) { + screen.slamRect(Common::Rect(0, CONTROLS_Y, + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + } + else { + Surface tempSurface(SHERLOCK_SCREEN_WIDTH, + (SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y) + 10); + Common::Rect r(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); + + tempSurface.blitFrom(screen._backBuffer, Common::Point(0, CONTROLS_Y), r); + screen._backBuffer.blitFrom(screen._backBuffer2, + Common::Point(0, CONTROLS_Y), r); + + summonWindow(); + } + + _selector = _oldSelector = -1; + _windowOpen = true; + } else { + screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, + SHERLOCK_SCREEN_HEIGHT)); + } +} + +/** +* Print the previously selected object's decription +*/ +void UserInterface::printObjectDesc() { + printObjectDesc(_cAnimStr, true); +} + +void UserInterface::banishWindow(bool flag) { + // TODO +} + +void UserInterface::makeButton(const Common::Rect &bounds, int textX, + const Common::String &str) { + // TODO +} + +void UserInterface::summonWindow() { + // TODO +} + } // End of namespace Sherlock diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index d2ef8942c3..98f6cd21ea 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -64,6 +64,13 @@ private: bool _keyboardInput; int _invMode; bool _pause; + int _cNum; + int _selector, _oldSelector; + Common::String _cAnimStr; + bool _lookScriptFlag; + Common::Rect _windowBounds; + Common::String _descStr; + int _windowStyle; private: void depressButton(int num); @@ -86,6 +93,12 @@ private: void doMiscControl(int allowed); void doPickControl(); void doTalkControl(); + + void banishWindow(bool flag); + + void makeButton(const Common::Rect &bounds, int textX, const Common::String &str); + + void summonWindow(); public: MenuMode _menuMode; int _menuCounter; @@ -102,6 +115,9 @@ public: void clearInfo(); void whileMenuCounter(); + + void printObjectDesc(const Common::String &str, bool firstTime); + void printObjectDesc(); }; } // End of namespace Sherlock |