aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sherlock/inventory.cpp6
-rw-r--r--engines/sherlock/inventory.h4
-rw-r--r--engines/sherlock/objects.cpp10
-rw-r--r--engines/sherlock/objects.h6
-rw-r--r--engines/sherlock/scene.cpp53
-rw-r--r--engines/sherlock/scene.h6
-rw-r--r--engines/sherlock/screen.cpp22
-rw-r--r--engines/sherlock/screen.h16
-rw-r--r--engines/sherlock/user_interface.cpp252
-rw-r--r--engines/sherlock/user_interface.h16
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