diff options
Diffstat (limited to 'engines/avalanche/help.cpp')
-rw-r--r-- | engines/avalanche/help.cpp | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/engines/avalanche/help.cpp b/engines/avalanche/help.cpp new file mode 100644 index 0000000000..4d08e3d58b --- /dev/null +++ b/engines/avalanche/help.cpp @@ -0,0 +1,270 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* +* This code is based on the original source code of Lord Avalot d'Argent version 1.3. +* Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman. +*/ + +/* Original name: HELPER The help system unit. */ + +#include "avalanche/avalanche.h" +#include "avalanche/help.h" + +#include "common/scummsys.h" + +namespace Avalanche { + +Help::Help(AvalancheEngine *vm) { + _vm = vm; + + for (int i = 0; i < 10; i++) { + _buttons[i]._trigger = Common::KEYCODE_INVALID; + _buttons[i]._whither = 0; + } + _highlightWas = 0; + _buttonNum = 0; + _holdLeft = false; +} + +/** + * Loads and draws the chosen page of the help. + * @remarks Originally called 'getme' + */ +void Help::switchPage(byte which) { + // Help icons are 80x20. + + _highlightWas = 177; // Forget where the highlight was. + + Common::File file; + + if (!file.open("help.avd")) + error("AVALANCHE: Help: File not found: help.avd"); + + file.seek(which * 2); + uint16 offset = file.readUint16LE(); + file.seek(offset); + + Common::String title = getLine(file); + + _vm->_graphics->drawFilledRectangle(Common::Rect(0, 0, 640, 200), kColorBlue); + _vm->_graphics->drawFilledRectangle(Common::Rect(8, 40, 450, 200), kColorWhite); + + byte index = file.readByte(); + _vm->_graphics->helpDrawButton(-177, index); + + // Plot the title: + _vm->_graphics->drawNormalText(title, _vm->_font, 8, 629 - 8 * title.size(), 26, kColorBlack); + _vm->_graphics->drawNormalText(title, _vm->_font, 8, 630 - 8 * title.size(), 25, kColorCyan); + + _vm->_graphics->helpDrawBigText("help!", 549, 1, kColorBlack); + _vm->_graphics->helpDrawBigText("help!", 550, 0, kColorCyan); + + byte y = 0; + do { + Common::String line = getLine(file); + if (!line.empty()) { + if (line.compareTo(Common::String('!')) == 0) // End of the help text is signalled with a '!'. + break; + if (line[0] == '\\') { + line.deleteChar(0); + _vm->_graphics->drawNormalText(line, _vm->_font, 8, 16, 41 + y * 10, kColorRed); + } + else + _vm->_graphics->drawNormalText(line, _vm->_font, 8, 16, 41 + y * 10, kColorBlack); + } + y++; + } while (true); + + // We are now at the end of the text. Next we must read the icons: + y = 0; + _buttonNum = 0; + while (!file.eos()) { + int trigger = file.readByte(); + + if (trigger == 177) + break; + switch (trigger) { + case 254: // Escape + trigger = 27; + break; + case 214: // PageUp + trigger = 280; + break; + case 216: // PageDown + trigger = 281; + break; + default: // A - Z + // The characters are stored in the file in uppercase, but we need the lowercase versions for KeyCode: + trigger = tolower(trigger); + break; + } + + _buttons[y]._trigger = Common::KeyCode(trigger); + index = file.readByte(); + if (_buttons[y]._trigger != Common::KEYCODE_INVALID) + _vm->_graphics->helpDrawButton(13 + (y + 1) * 27, index); + _buttons[y]._whither = file.readByte(); // This is the position to jump to. + + Common::String text = ""; + switch (_buttons[y]._trigger) { + case Common::KEYCODE_ESCAPE: + text = Common::String("Esc"); + break; + case Common::KEYCODE_PAGEUP: + text = Common::String(24); + break; + case Common::KEYCODE_PAGEDOWN: + text = Common::String(25); + break; + default: + text = Common::String(toupper(_buttons[y]._trigger)); + break; + } + + _vm->_graphics->helpDrawBigText(text, 589 - (text.size() * 8), 18 + (y + 1) * 27, kColorBlack); + _vm->_graphics->helpDrawBigText(text, 590 - (text.size() * 8), 17 + (y + 1) * 27, kColorCyan); + + y++; + _buttonNum++; + } + + _vm->_graphics->refreshScreen(); + + file.close(); +} + +Common::String Help::getLine(Common::File &file) { + Common::String line; + byte length = file.readByte(); + for (int i = 0; i < length; i++) { + char c = file.readByte(); + line += (c ^ 177); + } + return line; +} + +bool Help::handleMouse(const Common::Event &event) { + Common::Point mousePos; + mousePos.x = event.mouse.x; + mousePos.y = event.mouse.y / 2; + + int index = -1; + + if (event.type == Common::EVENT_LBUTTONUP) { // Clicked *somewhere*... + _holdLeft = false; + + if ((mousePos.x < 470) || (mousePos.x > 550) || (((mousePos.y - 13) % 27) > 20)) + index = -1; + else // Clicked on a button. + index = ((mousePos.y - 13) / 27) - 1; + } else { // LBUTTONDOWN or MOUSEMOVE + int highlightIs = 0; + + // Decide which button we are hovering the cursor over: + if ((mousePos.x > 470) && (mousePos.x <= 550) && (((mousePos.y - 13) % 27) <= 20)) { // No click, so highlight. + highlightIs = (mousePos.y - 13) / 27 - 1; + if ((highlightIs < 0) || (5 < highlightIs)) + highlightIs = 177; // In case of silly values. + } else + highlightIs = 177; + + Color highlightColor = kColorLightblue; + // If we clicked on a button or we are holding down the button, we have to highlight it with cyan: + if (((highlightIs != 177) && (event.type == Common::EVENT_LBUTTONDOWN)) || _holdLeft) { + _holdLeft = true; + highlightColor = kColorLightcyan; + } + + // Erase the previous highlight only if it's needed: + if (_highlightWas != highlightIs) + _vm->_graphics->helpDrawHighlight(_highlightWas, kColorBlue); + + // Highlight the current one with the proper color: + if ((highlightIs != 177) && (_buttons[highlightIs]._trigger != Common::KEYCODE_INVALID)) { + _highlightWas = highlightIs; + _vm->_graphics->helpDrawHighlight(highlightIs, highlightColor); + } + } + + if ((index >= 0) && (_buttons[index]._trigger != Common::KEYCODE_INVALID)) { + if (_buttons[index]._trigger == Common::KEYCODE_ESCAPE) + return true; + else { + _vm->fadeOut(); + switchPage(_buttons[index]._whither); + _vm->fadeIn(); + return false; + } + } + + return false; +} + +bool Help::handleKeyboard(const Common::Event &event) { + if (event.kbd.keycode == Common::KEYCODE_ESCAPE) + return true; + + for (int i = 0; i < _buttonNum; i++) { + if (_buttons[i]._trigger == event.kbd.keycode) { + _vm->fadeOut(); + switchPage(_buttons[i]._whither); + _vm->fadeIn(); + return false; + } + } + + return false; +} + +/** + * @remarks Originally called 'boot_help' + */ +void Help::run() { + _vm->_graphics->saveScreen(); + _vm->fadeOut(); + switchPage(0); + _vm->fadeIn(); + + _vm->_graphics->loadMouse(kCurHelp); + + // Originally it was the body of 'continue_help': + bool close = false; + while (!_vm->shouldQuit() && !close) { + Common::Event event; + _vm->getEvent(event); + if (event.type == Common::EVENT_KEYDOWN) + close = handleKeyboard(event); + else if ((event.type == Common::EVENT_LBUTTONDOWN) || (event.type == Common::EVENT_LBUTTONUP) || (event.type == Common::EVENT_MOUSEMOVE)) + close = handleMouse(event); + + _vm->_graphics->refreshScreen(); + } + // End of 'continue_help'. + + _vm->fadeOut(); + _vm->_graphics->restoreScreen(); + _vm->_graphics->removeBackup(); + _vm->fadeIn(); +} + +} // End of namespace Avalanche |