[Scummvm-cvs-logs] scummvm master -> fd849ee58c8fdc3856bb199a0e97777581e60f7e

dreammaster dreammaster at scummvm.org
Sun Aug 2 23:41:55 CEST 2015


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
fd849ee58c SHERLOCK: RT: Refactoring and cleanup for Foolscap puzzle


Commit: fd849ee58c8fdc3856bb199a0e97777581e60f7e
    https://github.com/scummvm/scummvm/commit/fd849ee58c8fdc3856bb199a0e97777581e60f7e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2015-08-02T17:40:53-04:00

Commit Message:
SHERLOCK: RT: Refactoring and cleanup for Foolscap puzzle

Changed paths:
    engines/sherlock/talk.cpp
    engines/sherlock/tattoo/widget_hangman.cpp
    engines/sherlock/tattoo/widget_hangman.h
    engines/sherlock/user_interface.h



diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp
index e901280..eddc508 100644
--- a/engines/sherlock/talk.cpp
+++ b/engines/sherlock/talk.cpp
@@ -928,6 +928,7 @@ int Talk::waitForMore(int delay) {
 			events._released = true;
 		} else {
 			// See if there's been a button press
+			events.pollEventsAndWait();
 			events.setButtonState();
 
 			if (events.kbHit()) {
diff --git a/engines/sherlock/tattoo/widget_hangman.cpp b/engines/sherlock/tattoo/widget_hangman.cpp
index 2841063..f41c5e4 100644
--- a/engines/sherlock/tattoo/widget_hangman.cpp
+++ b/engines/sherlock/tattoo/widget_hangman.cpp
@@ -21,237 +21,271 @@
  */
 
 #include "sherlock/tattoo/widget_hangman.h"
+#include "sherlock/tattoo/tattoo_fixed_text.h"
+#include "sherlock/tattoo/tattoo_scene.h"
+#include "sherlock/tattoo/tattoo_user_interface.h"
 #include "sherlock/tattoo/tattoo.h"
 
 namespace Sherlock {
 
 namespace Tattoo {
 
+WidgetHangman::WidgetHangman(TattooEngine *vm) : WidgetBase(vm) {
+	for (int idx = 0; idx < 3; ++idx)
+		Common::fill(&_answers[idx][0], &_answers[idx][10], 0);
+	_images = nullptr;
+	_numWide = 0;
+	_spacing = 0;
+	_blinkFlag = false;
+	_blinkCounter = 0;
+	_lineNum = _charNum = 0;
+	_solved = false;
+}
+
+WidgetHangman::~WidgetHangman() {
+	delete _images;
+}
+
 void WidgetHangman::show() {
-	Events &events = *_vm->_events;
-	Scene &scene = *_vm->_scene;
 	Screen &screen = *_vm->_screen;
-	Talk &talk = *_vm->_talk;
-	char answers[3][10];
-	Common::Point lines[3];
-	const char *solutions[3];
-	int numWide, spacing;
-	ImageFile *paper;
-	Common::Point cursorPos;
-	byte cursorColor = 254;
-	bool solved = false;
-	bool done = false;
-	bool flag = false;
-	size_t i = 0;
+	TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
 
 	switch (_vm->getLanguage()) {
 	case Common::FR_FRA:
-		lines[0] = Common::Point(34, 210);
-		lines[1] = Common::Point(72, 242);
-		lines[2] = Common::Point(34, 276);
-		numWide = 8;
-		spacing = 19;
-		paper = new ImageFile("paperf.vgs");
+		_lines[0] = Common::Point(34, 210);
+		_lines[1] = Common::Point(72, 242);
+		_lines[2] = Common::Point(34, 276);
+		_numWide = 8;
+		_spacing = 19;
+		_images = new ImageFile("paperf.vgs");
 		break;
 
 	case Common::DE_DEU:
-		lines[0] = Common::Point(44, 73);
-		lines[1] = Common::Point(56, 169);
-		lines[2] = Common::Point(47, 256);
-		numWide = 7;
-		spacing = 19;
-		paper = new ImageFile("paperg.vgs");
+		_lines[0] = Common::Point(44, 73);
+		_lines[1] = Common::Point(56, 169);
+		_lines[2] = Common::Point(47, 256);
+		_numWide = 7;
+		_spacing = 19;
+		_images = new ImageFile("paperg.vgs");
 		break;
 
 	default:
 		// English
-		lines[0] = Common::Point(65, 84);
-		lines[1] = Common::Point(65, 159);
-		lines[2] = Common::Point(75, 234);
-		numWide = 5;
-		spacing = 20;
-		paper = new ImageFile("paper.vgs");
+		_lines[0] = Common::Point(65, 84);
+		_lines[1] = Common::Point(65, 159);
+		_lines[2] = Common::Point(75, 234);
+		_numWide = 5;
+		_spacing = 20;
+		_images = new ImageFile("paper.vgs");
 		break;
 	}
-	
-	ImageFrame &paperFrame = (*paper)[0];
-	Common::Rect paperBounds(paperFrame._width, paperFrame._height);
-	paperBounds.moveTo((screen.w() - paperFrame._width) / 2, (screen.h() - paperFrame._height) / 2);
 
-	for (int line = 0; line<3; ++line) {
-		lines[line].x += paperBounds.left;
-		lines[line].y += paperBounds.top;
-
-		for (i = 0; i <= (size_t)numWide; ++i)
-			answers[line][i] = 0;
-	}
-
-	screen._backBuffer1.blitFrom(paperFrame, Common::Point(paperBounds.left + screen._currentScroll.x, 0));
+	_solved = false;
+	_blinkFlag = false;
+	_blinkCounter = 0;
+	_lineNum = _charNum = 0;
+	_cursorPos = Common::Point(_lines[0].x + 8 - screen.widestChar() / 2, _lines[0].y - screen.fontHeight() - 2);
+
+	// Set up window bounds
+	ImageFrame &paperFrame = (*_images)[0];
+	_bounds = Common::Rect(paperFrame._width, paperFrame._height);
+	_bounds.moveTo(screen._currentScroll.x + (SHERLOCK_SCREEN_WIDTH - paperFrame._width) / 2,
+		(SHERLOCK_SCREEN_HEIGHT - paperFrame._height) / 2);
+
+	// Clear answer data and set correct solution strings
+	for (int idx = 0; idx < 3; ++idx)
+		Common::fill(&_answers[idx][0], &_answers[idx][10], 0);
+	_solutions[0] = FIXED(Apply);
+	_solutions[1] = FIXED(Water);
+	_solutions[2] = FIXED(Heat);
+
+	// Set up the window background
+	_surface.create(_bounds.width(), _bounds.height());
+	_surface.blitFrom(paperFrame, Common::Point(0, 0));
 
 	// If they have already solved the puzzle, put the answer on the graphic
 	if (_vm->readFlags(299)) {
+		Common::Point cursorPos;
 		for (int line = 0; line < 3; ++line) {
-			cursorPos.y = lines[line].y - screen.fontHeight() - 2;
+			cursorPos.y = _lines[_lineNum].y - screen.fontHeight() - 2;
 
-			for (i = 0; i < strlen(solutions[line]); ++i) {
-				cursorPos.x = lines[line].x + 8 - screen.widestChar() / 2 + i * spacing;
-				screen.gPrint(Common::Point(cursorPos.x + screen.widestChar() / 2 - 
-					screen.charWidth(solutions[line][i]) / 2, cursorPos.y), 0, "%c", solutions[line][i]);
+			for (uint idx = 0; idx < strlen(_solutions[_lineNum]); ++idx) {
+				cursorPos.x = _lines[_lineNum].x + 8 - screen.widestChar() / 2 + idx * _spacing;
+				screen.gPrint(Common::Point(cursorPos.x + screen.widestChar() / 2 -
+					screen.charWidth(_solutions[_lineNum][idx]) / 2, cursorPos.y), 0, "%c", _solutions[_lineNum][idx]);
 			}
 		}
 	}
 
-	screen.slamRect(paperBounds);
-	cursorPos = Common::Point(lines[0].x + 8 - screen.widestChar() / 2, lines[0].y - screen.fontHeight() - 2);
-	int line = 0;
+	// Show the window
+	summonWindow();
+	ui._menuMode = FOOLSCAP_MODE;
+} 
+
+void WidgetHangman::handleEvents() {
+	Events &events = *_vm->_events;
+	Screen &screen = *_vm->_screen;
+	TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+	Common::Point mousePos = events.mousePos();
+	byte cursorColor = 254;
+
+	if (events._firstPress && !_bounds.contains(mousePos))
+		_outsideMenu = true;
 
 	// If they have not solved the puzzle, let them solve it here
 	if (!_vm->readFlags(299)) {
-		do {
-			while (!events.kbHit()) {
-				// See if a key or a mouse button is pressed
-				events.pollEventsAndWait();
-				events.setButtonState();
-
-				flag = !flag;
-				if (flag) {
-					screen._backBuffer1.fillRect(Common::Rect(cursorPos.x + screen._currentScroll.x, cursorPos.y, 
-						cursorPos.x + screen.widestChar() + screen._currentScroll.x - 1, cursorPos.y + screen.fontHeight() - 1), cursorColor);
-					if (answers[line][i])
-						screen.gPrint(Common::Point(cursorPos.x + screen.widestChar() / 2 - screen.charWidth(answers[line][i]) / 2, 
-							cursorPos.y), 0, "%c", answers[line][i]);
-					screen.slamArea(cursorPos.x, cursorPos.y, screen.widestChar(), screen.fontHeight());
+		if (!ui._keyState.keycode) {
+			if (--_blinkCounter < 0) {
+				_blinkCounter = 3;
+				_blinkFlag = !_blinkFlag;
+
+				if (_blinkFlag) {
+					// Draw the caret
+					_surface.fillRect(Common::Rect(_cursorPos.x, _cursorPos.y, _cursorPos.x + screen.widestChar() - 1,
+						_cursorPos.y + screen.fontHeight() - 1), cursorColor);
+
+					if (_answers[_lineNum][_charNum]) {
+						Common::String str = Common::String::format("%c", _answers[_lineNum][_charNum]);
+						_surface.writeString(str, Common::Point(_cursorPos.x + screen.widestChar() / 2
+							- screen.charWidth(_answers[_lineNum][_charNum]) / 2, _cursorPos.y), 0);
+					}
 				} else {
-					screen.setDisplayBounds(Common::Rect(cursorPos.x + screen._currentScroll.x, cursorPos.y, 
-						cursorPos.x + screen.widestChar() + screen._currentScroll.x, cursorPos.y + screen.fontHeight()));
-					screen._backBuffer->blitFrom(paperFrame, Common::Point(paperBounds.left + screen._currentScroll.x, paperBounds.top));
-					screen.resetDisplayBounds();
-
-					if (answers[line][i])
-						screen.gPrint(Common::Point(cursorPos.x + screen.widestChar() / 2 - screen.charWidth(answers[line][i]) / 2, 
-							cursorPos.y), 0, "%c", answers[line][i]);
-					screen.slamArea(cursorPos.x, cursorPos.y, screen.widestChar(), screen.fontHeight());
+					// Restore background
+					restoreChar();
+
+					// Draw the character at that position if there is one
+					if (_answers[_lineNum][_charNum]) {
+						Common::String str = Common::String::format("%c", _answers[_lineNum][_charNum]);
+						_surface.writeString(str, Common::Point(_cursorPos.x + screen.widestChar() / 2
+							- screen.charWidth(_answers[_lineNum][_charNum]) / 2, _cursorPos.y), 0);
+					}
 				}
-
-				if (!events.kbHit())
-					events.wait(2);
 			}
+		} else {
+			// Handle keyboard events
+			handleKeyboardEvents();
+		}
+	}
 
-			if (events.kbHit()) {
-				Common::KeyState keyState = events.getKey();
+	if ((events._released || events._rightReleased) && _outsideMenu && !_bounds.contains(mousePos)) {
+		// Clicked outside window to close it
+		events.clearEvents();
+		close();
+	}
+}
 
-				if (((toupper(keyState.ascii) >= 'A') && (toupper(keyState.ascii) <= 'Z')) ||
-					((keyState.ascii >= 128) && ((keyState.ascii <= 168) || (keyState.ascii == 225)))) {
-					answers[line][i] = keyState.ascii;
-					keyState.keycode = Common::KEYCODE_RIGHT;
-				}
+void WidgetHangman::handleKeyboardEvents() {
+	Screen &screen = *_vm->_screen;
+	TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+	Common::KeyState keyState = ui._keyState;
+
+	if (((toupper(keyState.ascii) >= 'A') && (toupper(keyState.ascii) <= 'Z')) ||
+		((keyState.ascii >= 128) && ((keyState.ascii <= 168) || (keyState.ascii == 225)))) {
+		// Visible key pressed, set it and set the keycode to move the caret to the right
+		_answers[_lineNum][_charNum] = keyState.ascii;
+		keyState.keycode = Common::KEYCODE_RIGHT;
+	}
 
-				screen.setDisplayBounds(Common::Rect(cursorPos.x + screen._currentScroll.x, cursorPos.y, 
-					cursorPos.x + screen.widestChar() + screen._currentScroll.x, cursorPos.y + screen.fontHeight()));
-				screen._backBuffer->blitFrom(paperFrame, Common::Point(paperBounds.left + screen._currentScroll.x, paperBounds.top));
-				screen.resetDisplayBounds();
-
-				if (answers[line][i])
-					screen.gPrint(Common::Point(cursorPos.x + screen.widestChar() / 2 - screen.charWidth(answers[line][i]) / 2,
-						cursorPos.y), 0, "%c", answers[line][i]);
-				screen.slamArea(cursorPos.x, cursorPos.y, screen.widestChar(), screen.fontHeight());
-
-				switch (keyState.keycode) {
-				case Common::KEYCODE_ESCAPE:
-					done = true;
-					break;
-
-				case Common::KEYCODE_UP:
-					if (line) {
-						line--;
-						if (i >= strlen(solutions[line]))
-							i = strlen(solutions[line]) - 1;
-					}
-					break;
+	// Restore background
+	restoreChar();
 
-				case Common::KEYCODE_DOWN:
-					if (line < 2) {
-						++line;
-						if (i >= strlen(solutions[line]))
-							i = strlen(solutions[line]) - 1;
-					}
-					break;
-
-				case Common::KEYCODE_BACKSPACE:
-				case Common::KEYCODE_LEFT:
-					if (i)
-						--i;
-					else if (line) {
-						--line;
-						
-						i = strlen(solutions[line]) - 1;
-					}
+	if (_answers[_lineNum][_charNum]) {
+		Common::String str = Common::String::format("%c", _answers[_lineNum][_charNum]);
+		_surface.writeString(str, Common::Point(_cursorPos.x + screen.widestChar() / 2
+			- screen.charWidth(_answers[_lineNum][_charNum]) / 2, _cursorPos.y), 0);
+	}
 
-					if (keyState.keycode == Common::KEYCODE_BACKSPACE)
-						answers[line][i] = ' ';
-					break;
+	switch (keyState.keycode) {
+	case Common::KEYCODE_ESCAPE:
+		close();
+		break;
 
-				case Common::KEYCODE_RIGHT:
-					if (i < strlen(solutions[line]) - 1)
-						i++;
-					else if (line < 2) {
-						++line;
-						i = 0;
-					}
-					break;
+	case Common::KEYCODE_UP:
+		if (_lineNum) {
+			--_lineNum;
+			if (_charNum >= (int)strlen(_solutions[_lineNum]))
+				_charNum = (int)strlen(_solutions[_lineNum]) - 1;
+		}
+		break;
 
-				case Common::KEYCODE_DELETE:
-					answers[line][i] = ' ';
-					break;
+	case Common::KEYCODE_DOWN:
+		if (_lineNum < 2) {
+			++_lineNum;
+			if (_charNum >= (int)strlen(_solutions[_lineNum]))
+				_charNum = (int)strlen(_solutions[_lineNum]) - 1;
+		}
+		break;
 
-				default:
-					break;
-				}
-			}
+	case Common::KEYCODE_BACKSPACE:
+	case Common::KEYCODE_LEFT:
+		if (_charNum)
+			--_charNum;
+		else if (_lineNum) {
+			--_lineNum;
 
-			cursorPos.x = lines[line].x + 8 - screen.widestChar() / 2 + i * spacing;
-			cursorPos.y = lines[line].y - screen.fontHeight() - 2;
+			_charNum = strlen(_solutions[_lineNum]) - 1;
+		}
 
-			// See if all of their anwers are correct
-			if (!scumm_stricmp(answers[0], solutions[0]) && !scumm_stricmp(answers[1], solutions[1]) && 
-					!scumm_stricmp(answers[2], solutions[2])) {
-				done = true;
-				solved = true;
-			}
-		} while (!done && !_vm->shouldQuit());
-	} else {
-		// They have already solved the puzzle, so just display the solution and wait for a mouse or key click
-		do {
-			events.pollEventsAndWait();
-			events.setButtonState();
-
-			if ((events.kbHit()) || (events._released) || (events._rightReleased)) {
-				done = true;
-				events.clearEvents();
-			}
-		} while (!done && !_vm->shouldQuit());
+		if (keyState.keycode == Common::KEYCODE_BACKSPACE)
+			_answers[_lineNum][_charNum] = ' ';
+		break;
+
+	case Common::KEYCODE_RIGHT:
+		if (_charNum < (int)strlen(_solutions[_lineNum]) - 1)
+			++_charNum;
+		else if (_lineNum < 2) {
+			++_lineNum;
+			_charNum = 0;
+		}
+		break;
+
+	case Common::KEYCODE_DELETE:
+		_answers[_lineNum][_charNum] = ' ';
+		break;
+
+	default:
+		break;
+	}
+
+	_cursorPos.x = _lines[_lineNum].x + 8 - screen.widestChar() / 2 + _charNum * _spacing;
+	_cursorPos.y = _lines[_lineNum].y - screen.fontHeight() - 2;
+
+	// See if all of their anwers are correct
+	if (!scumm_stricmp(_answers[0], _solutions[0]) && !scumm_stricmp(_answers[1], _solutions[1])
+			&& !scumm_stricmp(_answers[2], _solutions[2])) {
+		_solved;
+		close();
 	}
+}
 
-	delete paper;
-	screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(paperBounds.left + screen._currentScroll.x, paperBounds.top),
-		Common::Rect(paperBounds.left + screen._currentScroll.x, paperBounds.top,
-		paperBounds.right + screen._currentScroll.x, paperBounds.bottom));
-	scene.doBgAnim();
+void WidgetHangman::restoreChar() {
+	Screen &screen = *_vm->_screen;
+	ImageFrame &bgFrame = (*_images)[0];
+	_surface.blitFrom(bgFrame, _cursorPos, Common::Rect(_cursorPos.x, _cursorPos.y,
+		_cursorPos.x + screen.widestChar(), _cursorPos.y + screen.fontHeight()));
+}
 
-	screen.slamArea(paperBounds.left + screen._currentScroll.x, paperBounds.top,
-		paperBounds.width(), paperBounds.height());
+void WidgetHangman::close() {
+	TattooScene &scene = *(TattooScene *)_vm->_scene;
+	Talk &talk = *_vm->_talk;
+	TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+	delete _images;
+	_images = nullptr;
+
+	// Close the window
+	banishWindow();
+	ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
 
 	// Don't call the talk files if the puzzle has already been solved
-	if (_vm->readFlags(299))
-		return;
-
-	// If they solved the puzzle correctly, set the solved flag and run the appropriate talk scripts
-	if (solved) {
-		talk.talkTo("SLVE12S.TLK");
-		talk.talkTo("WATS12X.TLK");
-		_vm->setFlags(299);
-	} else {
-		talk.talkTo("HOLM12X.TLK");
+	if (!_vm->readFlags(299)) {
+		// Run the appropriate script depending on whether or not they solved the puzzle correctly
+		if (_solved) {
+			talk.talkTo("SLVE12S.TLK");
+			talk.talkTo("WATS12X.TLK");
+			_vm->setFlags(299);
+		} else {
+			talk.talkTo("HOLM12X.TLK");
+		}
 	}
 }
 
diff --git a/engines/sherlock/tattoo/widget_hangman.h b/engines/sherlock/tattoo/widget_hangman.h
index daa5987..c653f93 100644
--- a/engines/sherlock/tattoo/widget_hangman.h
+++ b/engines/sherlock/tattoo/widget_hangman.h
@@ -23,22 +23,56 @@
 #ifndef SHERLOCK_TATTOO_HANGMAN_H
 #define SHERLOCK_TATTOO_HANGMAN_H
 
+#include "sherlock/tattoo/widget_base.h"
+#include "sherlock/image_file.h"
+
 namespace Sherlock {
 
 namespace Tattoo {
 
 class TattooEngine;
 
-class WidgetHangman {
+class WidgetHangman: public WidgetBase {
 private:
-	TattooEngine *_vm;
+	ImageFile *_images;
+	Common::Point _lines[3];
+	char _answers[3][10];
+	const char *_solutions[3];
+	int _numWide;
+	int _spacing;
+	Common::Point _cursorPos;
+	int _blinkCounter;
+	bool _blinkFlag;
+	int _lineNum, _charNum;
+	bool _solved;
+
+	/**
+	 * Handle keyboard events
+	 */
+	void handleKeyboardEvents();
+
+	/**
+	 * Restore the background for the current line/horiz position
+	 */
+	void restoreChar();
 public:
-	WidgetHangman(TattooEngine *vm) : _vm(vm) {}
+	WidgetHangman(TattooEngine *vm);
+	virtual ~WidgetHangman();
 
 	/**
 	 * Show the hangman puzzle
 	 */
 	void show();
+
+	/**
+	 * Close the window
+	 */
+	void close();
+
+	/**
+	* Handle events whilst the widget is on-screen
+	*/
+	virtual void handleEvents();
 };
 
 } // End of namespace Tattoo
diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h
index b6734fb..799912f 100644
--- a/engines/sherlock/user_interface.h
+++ b/engines/sherlock/user_interface.h
@@ -55,7 +55,8 @@ enum MenuMode {
 	MESSAGE_MODE	= 21,
 	VERB_MODE		= 22,
 	OPTION_MODE		= 23,
-	QUIT_MODE		= 24
+	QUIT_MODE		= 24,
+	FOOLSCAP_MODE	= 25
 };
 
 class UserInterface {






More information about the Scummvm-git-logs mailing list