diff options
author | Vincent Bénony | 2016-01-06 16:20:23 +0100 |
---|---|---|
committer | Vincent Bénony | 2016-01-06 16:20:23 +0100 |
commit | efdb5679ce6304dbc854afbbc511e633d7513338 (patch) | |
tree | e680a240e5f6018fc3a4cce53b50060caa22a929 /engines/lab/special.cpp | |
parent | 4687ff6d6d2863cc95c8137543ecf9c39bc01723 (diff) | |
parent | b72c02bad44749a1355acefdb198e36b2e772575 (diff) | |
download | scummvm-rg350-efdb5679ce6304dbc854afbbc511e633d7513338.tar.gz scummvm-rg350-efdb5679ce6304dbc854afbbc511e633d7513338.tar.bz2 scummvm-rg350-efdb5679ce6304dbc854afbbc511e633d7513338.zip |
IOS: Merge branch 'master' into ios-fix
Diffstat (limited to 'engines/lab/special.cpp')
-rw-r--r-- | engines/lab/special.cpp | 469 |
1 files changed, 469 insertions, 0 deletions
diff --git a/engines/lab/special.cpp b/engines/lab/special.cpp new file mode 100644 index 0000000000..43d6056125 --- /dev/null +++ b/engines/lab/special.cpp @@ -0,0 +1,469 @@ +/* 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 Labyrinth of Time code with assistance of + * + * Copyright (c) 1993 Terra Nova Development + * Copyright (c) 2004 The Wyrmkeep Entertainment Co. + * + */ + +#include "lab/lab.h" + +#include "lab/anim.h" +#include "lab/dispman.h" +#include "lab/eventman.h" +#include "lab/image.h" +#include "lab/labsets.h" +#include "lab/music.h" +#include "lab/processroom.h" +#include "lab/resource.h" +#include "lab/utils.h" + +namespace Lab { + +void LabEngine::doNotes() { + TextFont *noteFont = _resource->getFont("F:Note.fon"); + Common::String noteText = _resource->getText("Lab:Rooms/Notes"); + + Common::Rect textRect = Common::Rect(_utils->vgaScaleX(25) + _utils->svgaCord(15), _utils->vgaScaleY(50), _utils->vgaScaleX(295) - _utils->svgaCord(15), _utils->vgaScaleY(148)); + _graphics->flowText(noteFont, -2 + _utils->svgaCord(1), 0, 0, false, false, true, true, textRect, noteText.c_str()); + _graphics->setPalette(_anim->_diffPalette, 256); + _graphics->freeFont(¬eFont); +} + +void LabEngine::doWestPaper() { + TextFont *paperFont = _resource->getFont("F:News22.fon"); + Common::String paperText = _resource->getText("Lab:Rooms/Date"); + + Common::Rect textRect = Common::Rect(_utils->vgaScaleX(57), _utils->vgaScaleY(77) + _utils->svgaCord(2), _utils->vgaScaleX(262), _utils->vgaScaleY(91)); + _graphics->flowText(paperFont, 0, 0, 0, false, true, false, true, textRect, paperText.c_str()); + _graphics->freeFont(&paperFont); + + paperFont = _resource->getFont("F:News32.fon"); + paperText = _resource->getText("Lab:Rooms/Headline"); + + int fileLen = paperText.size() - 1; + textRect = Common::Rect(_utils->vgaScaleX(57), _utils->vgaScaleY(86) - _utils->svgaCord(2), _utils->vgaScaleX(262), _utils->vgaScaleY(118)); + int charsPrinted = _graphics->flowText(paperFont, -8, 0, 0, false, true, false, true, textRect, paperText.c_str()); + + uint16 y; + + if (charsPrinted < fileLen) { + y = 130 - _utils->svgaCord(5); + textRect = Common::Rect(_utils->vgaScaleX(57), _utils->vgaScaleY(86) - _utils->svgaCord(2), _utils->vgaScaleX(262), _utils->vgaScaleY(132)); + _graphics->flowText(paperFont, -8 - _utils->svgaCord(1), 0, 0, false, true, false, true, textRect, paperText.c_str()); + } else + y = 115 - _utils->svgaCord(5); + + _graphics->freeFont(&paperFont); + + paperFont = _resource->getFont("F:Note.fon"); + paperText = _resource->getText("Lab:Rooms/Col1"); + _graphics->flowText(paperFont, -4, 0, 0, false, false, false, true, _utils->vgaRectScale(45, y, 158, 148), paperText.c_str()); + + paperText = _resource->getText("Lab:Rooms/Col2"); + _graphics->flowText(paperFont, -4, 0, 0, false, false, false, true, _utils->vgaRectScale(162, y, 275, 148), paperText.c_str()); + + _graphics->freeFont(&paperFont); + _graphics->setPalette(_anim->_diffPalette, 256); +} + +void LabEngine::loadJournalData() { + if (_journalFont) + _graphics->freeFont(&_journalFont); + + _journalFont = _resource->getFont("F:Journal.fon"); + updateEvents(); + + Common::String filename = "Lab:Rooms/j"; + + bool bridge = _conditions->in(kCondBridge0) || _conditions->in(kCondBridge1); + bool dirty = _conditions->in(kCondDirty); + bool news = !_conditions->in(kCondNoNews); + bool clean = !_conditions->in(kCondNoClean); + + if (bridge && clean && news) + filename += '8'; + else if (clean && news) + filename += '9'; + else if (bridge && clean) + filename += '6'; + else if (clean) + filename += '7'; + else if (bridge && dirty && news) + filename += '4'; + else if (dirty && news) + filename += '5'; + else if (bridge && dirty) + filename += '2'; + else if (dirty) + filename += '3'; + else if (bridge) + filename += '1'; + else + filename += '0'; + + _journalText = _resource->getText(filename); + _journalTextTitle = _resource->getText("Lab:Rooms/jt"); + + Common::File *journalFile = _resource->openDataFile("P:JImage"); + _journalButtonList.push_back(_event->createButton( 80, _utils->vgaScaleY(162) + _utils->svgaCord(1), 0, Common::KEYCODE_LEFT, new Image(journalFile, this), new Image(journalFile, this))); // back + _journalButtonList.push_back(_event->createButton(194, _utils->vgaScaleY(162) + _utils->svgaCord(1), 2, Common::KEYCODE_RIGHT, new Image(journalFile, this), new Image(journalFile, this))); // forward + _journalButtonList.push_back(_event->createButton(144, _utils->vgaScaleY(164) - _utils->svgaCord(1), 1, Common::KEYCODE_ESCAPE, new Image(journalFile, this), new Image(journalFile, this))); // cancel + delete journalFile; + + _anim->_noPalChange = true; + _journalBackImage->setData(new byte[_graphics->_screenBytesPerPage]); + _graphics->readPict("P:Journal.pic", true, false, _journalBackImage->_imageData); + _anim->_noPalChange = false; + + // Keep a copy of the blank journal + _blankJournal = new byte[_graphics->_screenBytesPerPage]; + memcpy(_blankJournal, _journalBackImage->_imageData, _graphics->_screenBytesPerPage); +} + +void LabEngine::drawJournalText() { + uint16 drawingToPage = 1; + const char *curText = _journalText.c_str(); + + assert((_journalPage & 1) == 0); + + while (drawingToPage < _journalPage) { + updateEvents(); + + // flowText without output + curText += _graphics->flowText(_journalFont, -2, 2, 0, false, false, false, false, _utils->vgaRectScale(52, 32, 152, 148), curText); + + _lastPage = (*curText == 0); + + if (_lastPage) { + // Reset _journalPage to this page, in case it was set too high + _journalPage = (drawingToPage / 2) * 2; + break; + } + + drawingToPage++; + } + + if (_journalPage == 0) { + // draw title page centered + _graphics->flowText(_journalFont, -2, 2, 0, false, true, true, true, _utils->vgaRectScale(52, 32, 152, 148), _journalTextTitle.c_str(), _journalBackImage); + } else { + curText += _graphics->flowText(_journalFont, -2, 2, 0, false, false, false, true, _utils->vgaRectScale(52, 32, 152, 148), curText, _journalBackImage); + } + + updateEvents(); + curText += _graphics->flowText(_journalFont, -2, 2, 0, false, false, false, true, _utils->vgaRectScale(171, 32, 271, 148), curText, _journalBackImage); + + _lastPage = (*curText == 0); +} + +void LabEngine::turnPage(bool fromLeft) { + if (fromLeft) { + for (int i = 0; i < _graphics->_screenWidth; i += 8) { + updateEvents(); + waitTOF(); + _journalBackImage->blitBitmap(i, 0, nullptr, i, 0, 8, _graphics->_screenHeight, false); + } + } else { + for (int i = (_graphics->_screenWidth - 8); i > 0; i -= 8) { + updateEvents(); + waitTOF(); + _journalBackImage->blitBitmap(i, 0, nullptr, i, 0, 8, _graphics->_screenHeight, false); + } + } +} + +void LabEngine::drawJournal(uint16 wipenum, bool needFade) { + _event->mouseHide(); + updateEvents(); + drawJournalText(); + _graphics->loadBackPict("P:Journal.pic", _highPalette); + + if (wipenum == 0) + _journalBackImage->blitBitmap(0, 0, nullptr, 0, 0, _graphics->_screenWidth, _graphics->_screenHeight, false); + else + turnPage((wipenum == 1)); + + _event->toggleButton(_event->getButton(0), 15, (_journalPage > 0)); // back button + _event->toggleButton(_event->getButton(2), 15, (!_lastPage)); // forward button + + if (needFade) + _graphics->fade(true); + + // Reset the journal background, so that all the text that has been blitted on it is erased + memcpy(_journalBackImage->_imageData, _blankJournal, _graphics->_screenBytesPerPage); + + eatMessages(); + _event->mouseShow(); +} + +void LabEngine::processJournal() { + while (1) { + // Make sure we check the music at least after every message + updateEvents(); + IntuiMessage *msg = _event->getMsg(); + if (shouldQuit()) { + _quitLab = true; + return; + } + + if (!msg) + updateEvents(); + else { + MessageClass msgClass = msg->_msgClass; + + if ((msgClass == kMessageRightClick) || + ((msgClass == kMessageRawKey) && (msg->_code == Common::KEYCODE_ESCAPE))) + return; + else if (msgClass == kMessageButtonUp) { + uint16 buttonId = msg->_code; + if (buttonId == 0) { + if (_journalPage >= 2) { + _journalPage -= 2; + drawJournal(1, false); + } + } else if (buttonId == 1) { + return; + } else if (buttonId == 2) { + if (!_lastPage) { + _journalPage += 2; + drawJournal(2, false); + } + } + } + } + } +} + +void LabEngine::doJournal() { + _graphics->blackAllScreen(); + _lastPage = false; + + _journalBackImage->_width = _graphics->_screenWidth; + _journalBackImage->_height = _graphics->_screenHeight; + _journalBackImage->setData(nullptr, true); + + updateEvents(); + loadJournalData(); + _event->attachButtonList(&_journalButtonList); + drawJournal(0, true); + _event->mouseShow(); + processJournal(); + _event->attachButtonList(nullptr); + _graphics->fade(false); + _event->mouseHide(); + + delete[] _blankJournal; + _blankJournal = nullptr; + _journalBackImage->setData(nullptr, true); + + _event->freeButtonList(&_journalButtonList); + _graphics->freeFont(&_journalFont); + + _graphics->rectFill(0, 0, _graphics->_screenWidth - 1, _graphics->_screenHeight - 1, 0); + _graphics->blackScreen(); +} + +void LabEngine::drawMonText(const char *text, TextFont *monitorFont, Common::Rect textRect, bool isinteractive) { + uint16 drawingToPage = 0, yspacing = 0; + int charsDrawn = 0; + const char *curText = text; + + _event->mouseHide(); + + if (*text == '%') { + text++; + uint16 numlines = (*text - '0') * 10; + text++; + numlines += (*text - '0'); + text += 2; + + uint16 fheight = _graphics->textHeight(monitorFont); + textRect.left = _monitorButton->_width + _utils->vgaScaleX(3); + _monitorButtonHeight = _monitorButton->_height + _utils->vgaScaleY(3); + + if (_monitorButtonHeight > fheight) + yspacing = _monitorButtonHeight - fheight; + else + _monitorButtonHeight = fheight; + + _graphics->rectFill(0, 0, _graphics->_screenWidth - 1, textRect.bottom, 0); + + for (int i = 0; i < numlines; i++) + _monitorButton->drawImage(0, i * _monitorButtonHeight); + } else if (isinteractive) { + _graphics->rectFill(0, 0, _graphics->_screenWidth - 1, textRect.bottom, 0); + } else { + _graphics->rectFill(textRect, 0); + } + + while (drawingToPage < _monitorPage) { + updateEvents(); + curText = text + charsDrawn; + charsDrawn += _graphics->flowText(monitorFont, yspacing, 0, 0, false, false, false, false, textRect, curText); + _lastPage = (*curText == 0); + + if (_lastPage) + _monitorPage = drawingToPage; + else + drawingToPage++; + } + + curText = text + charsDrawn; + _lastPage = (*curText == 0); + _graphics->flowText(monitorFont, yspacing, 2, 0, false, false, false, true, textRect, curText); + _event->mouseShow(); +} + +void LabEngine::processMonitor(const char *ntext, TextFont *monitorFont, bool isInteractive, Common::Rect textRect) { + Common::String startFileName = _monitorTextFilename; + const CloseData *startClosePtr = _closeDataPtr, *lastClosePtr[10]; + uint16 depth = 0; + + lastClosePtr[0] = _closeDataPtr; + + while (1) { + if (isInteractive) { + if (!_closeDataPtr) + _closeDataPtr = startClosePtr; + + Common::String filename; + if (_closeDataPtr == startClosePtr) + filename = startFileName; + else + filename = _closeDataPtr->_graphicName; + + if (filename != _monitorTextFilename) { + _monitorPage = 0; + _monitorTextFilename = filename; + + Common::String text = _resource->getText(_monitorTextFilename); + _graphics->fade(false); + drawMonText(text.c_str(), monitorFont, textRect, isInteractive); + _graphics->fade(true); + } + } + + // Make sure we check the music at least after every message + updateEvents(); + IntuiMessage *msg = _event->getMsg(); + if (shouldQuit()) { + _quitLab = true; + return; + } + + if (!msg) + updateEvents(); + else { + MessageClass msgClass = msg->_msgClass; + + if ((msgClass == kMessageRightClick) || + ((msgClass == kMessageRawKey) && (msg->_code == Common::KEYCODE_ESCAPE))) + return; + + if (msgClass == kMessageLeftClick) { + int16 mouseX = msg->_mouse.x; + int16 mouseY = msg->_mouse.y; + + if ((mouseY >= _utils->vgaScaleY(171)) && (mouseY <= _utils->vgaScaleY(200))) { + if (mouseX <= _utils->vgaScaleX(31)) + return; + + if (mouseX <= _utils->vgaScaleX(59)) { + if (isInteractive) { + _monitorPage = 0; + + if (depth) { + depth--; + _closeDataPtr = lastClosePtr[depth]; + } + } else if (_monitorPage > 0) { + _monitorPage = 0; + drawMonText(ntext, monitorFont, textRect, isInteractive); + } + } else if (mouseX < _utils->vgaScaleX(259)) { + return; + } else if (mouseX <= _utils->vgaScaleX(289)) { + if (!_lastPage) { + _monitorPage += 1; + drawMonText(ntext, monitorFont, textRect, isInteractive); + } + } else if (_monitorPage >= 1) { + // mouseX is greater than 290 (scaled) + _monitorPage -= 1; + drawMonText(ntext, monitorFont, textRect, isInteractive); + } + } else if (isInteractive) { + const CloseData *tmpClosePtr = _closeDataPtr; + mouseY = 64 + (mouseY / _monitorButtonHeight) * 42; + mouseX = 101; + setCurrentClose(Common::Point(mouseX, mouseY), &_closeDataPtr, false); + + if (tmpClosePtr != _closeDataPtr) { + lastClosePtr[depth] = tmpClosePtr; + depth++; + } + } + } + } + } +} + +void LabEngine::doMonitor(const Common::String background, const Common::String textfile, bool isinteractive, Common::Rect textRect) { + Common::Rect scaledRect = _utils->vgaRectScale(textRect.left, textRect.top, textRect.right, textRect.bottom); + _monitorTextFilename = textfile; + + _graphics->blackAllScreen(); + _graphics->readPict("P:Mon/Monitor.1"); + _graphics->readPict("P:Mon/NWD1"); + _graphics->readPict("P:Mon/NWD2"); + _graphics->readPict("P:Mon/NWD3"); + _graphics->blackAllScreen(); + + _monitorPage = 0; + _lastPage = false; + _graphics->_fadePalette = _highPalette; + + TextFont *monitorFont = _resource->getFont("F:Map.fon"); + Common::File *buttonFile = _resource->openDataFile("P:MonImage"); + _monitorButton = new Image(buttonFile, this); + delete buttonFile; + + Common::String ntext = _resource->getText(textfile); + _graphics->loadBackPict(background, _highPalette); + drawMonText(ntext.c_str(), monitorFont, scaledRect, isinteractive); + _event->mouseShow(); + _graphics->fade(true); + processMonitor(ntext.c_str(), monitorFont, isinteractive, scaledRect); + _graphics->fade(false); + _event->mouseHide(); + _graphics->freeFont(&monitorFont); + + _graphics->rectFill(0, 0, _graphics->_screenWidth - 1, _graphics->_screenHeight - 1, 0); + _graphics->blackAllScreen(); + _graphics->freePict(); +} + +} // End of namespace Lab |