aboutsummaryrefslogtreecommitdiff
path: root/engines/sherlock/tattoo/widget_hangman.cpp
diff options
context:
space:
mode:
authorPaul Gilbert2015-08-02 17:40:53 -0400
committerPaul Gilbert2015-08-02 17:40:53 -0400
commitfd849ee58c8fdc3856bb199a0e97777581e60f7e (patch)
treef6f3cb70394e77c90434fca7a04daee4e4dafde4 /engines/sherlock/tattoo/widget_hangman.cpp
parent1ae250f53b3dbd09ebf71e9f6eedc1e8d28d2e28 (diff)
downloadscummvm-rg350-fd849ee58c8fdc3856bb199a0e97777581e60f7e.tar.gz
scummvm-rg350-fd849ee58c8fdc3856bb199a0e97777581e60f7e.tar.bz2
scummvm-rg350-fd849ee58c8fdc3856bb199a0e97777581e60f7e.zip
SHERLOCK: RT: Refactoring and cleanup for Foolscap puzzle
Diffstat (limited to 'engines/sherlock/tattoo/widget_hangman.cpp')
-rw-r--r--engines/sherlock/tattoo/widget_hangman.cpp394
1 files changed, 214 insertions, 180 deletions
diff --git a/engines/sherlock/tattoo/widget_hangman.cpp b/engines/sherlock/tattoo/widget_hangman.cpp
index 28410636f3..f41c5e43f0 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");
+ }
}
}