diff options
Diffstat (limited to 'engines/tsage')
47 files changed, 38777 insertions, 0 deletions
diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp new file mode 100644 index 0000000000..260308a784 --- /dev/null +++ b/engines/tsage/converse.cpp @@ -0,0 +1,943 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/converse.cpp $ + * $Id: converse.cpp 230 2011-02-12 06:57:31Z dreammaster $ + * + */ + +#include "common/str-array.h" + +#include "tsage/tsage.h" +#include "tsage/globals.h" +#include "tsage/staticres.h" + +namespace tSage { + +#define STRIP_WORD_DELAY 30 + + +SequenceManager::SequenceManager(): Action() { + Common::set_to(&_objectList[0], &_objectList[6], (SceneObject *)NULL); + _sequenceData.clear(); + _field24 = 0; + _sequenceOffset = 0; + _resNum = 0; + _field26 = 0; + _objectIndex = 0; + _keepActive = false; + setup(); +} + +void SequenceManager::setup() { + _sequenceOffset = 0; + _objectIndex = 0; + _sceneObject = _objectList[0]; +} + +void SequenceManager::synchronise(Serialiser &s) { + s.syncAsSint32LE(_resNum); + s.syncAsSint32LE(_sequenceOffset); + s.syncAsByte(_keepActive); + s.syncAsSint32LE(_field24); + s.syncAsSint32LE(_field26); + + s.syncAsSint32LE(_objectIndex); + SYNC_POINTER(_sceneObject); + for (int i = 0; i < 6; ++i) + SYNC_POINTER(_objectList[i]); + + int seqSize = _sequenceData.size(); + s.syncAsUint32LE(seqSize); + if (s.isLoading()) + _sequenceData.resize(seqSize); + if (seqSize > 0) + s.syncBytes(&_sequenceData[0], seqSize); +} + +void SequenceManager::remove() { + if ((!_sequenceData.empty()) && !_keepActive) { + _sequenceData.clear(); + } + + if (_globals->_sceneObjects->contains(&_sceneText)) + _sceneText.remove(); + + Common::set_to(&_objectList[0], &_objectList[6], (SceneObject *)NULL); + Action::remove(); +} + +void SequenceManager::signal() { + if (_globals->_sceneObjects->contains(&_sceneText)) + _sceneText.hide(); + + bool continueFlag = true; + while (continueFlag) { + if (_sequenceOffset >=_sequenceData.size()) { + // Reached the end of the sequence + if (!_keepActive) + remove(); + break; + } + + uint16 idx = static_cast<uint16>(getNextValue() - 32000); + if (idx > 34) + continue; + + int16 v1, v2, v3; + switch (idx) { + case 0: + // Stop sequence + continueFlag = false; + break; + case 1: + _sceneObject->animate(ANIM_MODE_1, NULL); + break; + case 2: + _sceneObject->animate(ANIM_MODE_2, NULL); + break; + case 3: + _sceneObject->animate(ANIM_MODE_3); + break; + case 4: + v1 = getNextValue(); + v2 = getNextValue(); + _sceneObject->animate(ANIM_MODE_8, v1, v2 ? this : NULL); + break; + case 5: + v1 = getNextValue(); + v2 = getNextValue(); + _sceneObject->animate(ANIM_MODE_7, v1, v2 ? this : NULL); + break; + case 6: + v2 = getNextValue(); + _sceneObject->animate(ANIM_MODE_5, v2 ? this : NULL); + break; + case 7: + v2 = getNextValue(); + _sceneObject->animate(ANIM_MODE_6, v2 ? this : NULL); + break; + case 8: + v1 = getNextValue(); + v3 = getNextValue(); + v2 = getNextValue(); + _sceneObject->animate(ANIM_MODE_4, v1, v3, v2 ? this : NULL); + break; + case 9: + v1 = getNextValue(); + v3 = getNextValue(); + v2 = getNextValue(); + _globals->_sceneManager._scene->_sceneBounds.moveTo(v3, v2); + _globals->_sceneManager._scene->loadScene(v1); + break; + case 10: { + int resNum= getNextValue(); + int lineNum = getNextValue(); + int colour = getNextValue(); + int xp = getNextValue(); + int yp = getNextValue(); + int width = getNextValue(); + setMessage(resNum, lineNum, colour, Common::Point(xp, yp), width); + break; + } + case 11: + v1 = getNextValue(); + v2 = getNextValue(); + setAction(globalManager(), v2 ? this : NULL, v1, _objectList[0], _objectList[1], _objectList[2], _objectList[3], NULL); + break; + case 12: + v1 = getNextValue(); + setDelay(v1); + break; + case 13: { + v1 = getNextValue(); + v3 = getNextValue(); + v2 = getNextValue(); + NpcMover *mover = new NpcMover(); + Common::Point destPos(v1, v3); + _sceneObject->addMover(mover, &destPos, v2 ? this : NULL); + break; + } + case 14: + v1 = getNextValue(); + _sceneObject->_numFrames = v1; + break; + case 15: + v1 = getNextValue(); + _sceneObject->_field7A = v1; + break; + case 16: + v1 = getNextValue(); + v2 = getNextValue(); + _sceneObject->_moveDiff = Common::Point(v1, v2); + break; + case 17: + _sceneObject->hide(); + break; + case 18: + _sceneObject->show(); + break; + case 19: + v1 = getNextValue(); + _sceneObject->setVisage(v1); + break; + case 20: + v1 = getNextValue(); + _sceneObject->setStrip(v1); + break; + case 21: + v1 = getNextValue(); + _sceneObject->setFrame(v1); + break; + case 22: + v1 = getNextValue(); + _sceneObject->setPriority2(v1); + break; + case 23: + v1 = getNextValue(); + _sceneObject->changeZoom(v1); + break; + case 24: + v1 = getNextValue(); + v2 = getNextValue(); + v3 = getNextValue(); + _sceneObject->setPosition(Common::Point(v1, v2), v3); + break; + case 25: { + int yStart = getNextValue(); + int minPercent = getNextValue(); + int yEnd = getNextValue(); + int maxPercent = getNextValue(); + _globals->_sceneManager._scene->setZoomPercents(yStart, minPercent, yEnd, maxPercent); + break; + } + case 26: + v1 = getNextValue(); + v2 = getNextValue(); + _soundHandler.startSound(v1, v2 ? this : NULL, 127); + break; + case 27: { + v1 = getNextValue(); + v3 = getNextValue(); + v2 = getNextValue(); + PlayerMover *mover = new PlayerMover(); + Common::Point destPos(v1, v3); + _sceneObject->addMover(mover, &destPos, v2 ? this : NULL); + break; + } + case 28: + _objectIndex = getNextValue(); + _sceneObject = _objectList[_objectIndex]; + assert(_sceneObject); + break; + case 29: + _sceneObject->animate(ANIM_MODE_NONE); + break; + case 30: + v1 = getNextValue(); + _globals->_scrollFollower = (v1 == -1) ? NULL : _objectList[v1]; + break; + case 31: + _sceneObject->setObjectWrapper(new SceneObjectWrapper()); + break; + case 32: + _sceneObject->setObjectWrapper(NULL); + break; + case 33: + v1 = getNextValue(); + if (_keepActive) + setDelay(1); + else { + _sceneText.remove(); + _globals->_sceneManager._scene->_stripManager.start(v1, this); + } + break; + case 34: { + v1 = getNextValue(); + v2 = getNextValue(); + int objIndex1 = getNextValue(); + int objIndex2 = getNextValue(); + int objIndex3 = getNextValue(); + int objIndex4 = getNextValue(); + int objIndex5 = getNextValue(); + + setAction(globalManager(), v2 ? this : NULL, v1, _objectList[objIndex1], _objectList[objIndex2], + _objectList[objIndex3], _objectList[objIndex4], _objectList[objIndex5]); + break; + } + default: + error("SequenceManager::signal - Unknown action %d at offset %xh", idx, _sequenceOffset - 2); + break; + } + } +} + +void SequenceManager::process(Event &event) { + if (((event.eventType == EVENT_BUTTON_DOWN) || (event.eventType == EVENT_KEYPRESS)) && + !event.handled && _globals->_sceneObjects->contains(&_sceneText)) { + // Remove the text item + _sceneText.remove(); + } else { + Action::process(event); + } +} + + +void SequenceManager::attached(EventHandler *newOwner, EventHandler *fmt, va_list va) { + // Get the sequence number to use + _resNum = va_arg(va, int); + + byte *seqData = _vm->_dataManager->getResource(RES_SEQUENCE, _resNum, 0); + uint seqSize = _vm->_memoryManager.getSize(seqData); + + _sequenceData.resize(seqSize); + Common::copy(seqData, seqData + seqSize, &_sequenceData[0]); + + DEALLOCATE(seqData); + + Common::set_to(&_objectList[0], &_objectList[6], (SceneObject *)NULL); + for (int idx = 0; idx < 6; ++idx) { + _objectList[idx] = va_arg(va, SceneObject *); + if (!_objectList[idx]) + break; + } + + setup(); + Action::attached(newOwner, fmt, NULL); +} + +/** + * Returns the next Id in the sequence + */ +uint16 SequenceManager::getNextValue() { + uint16 result = READ_LE_UINT16(&_sequenceData[0] + _sequenceOffset); + _sequenceOffset += 2; + return result; +} + +void SequenceManager::setMessage(int resNum, int lineNum, int colour, const Common::Point &pt, int width) { + _sceneText._colour1 = colour; + _sceneText._colour2 = 0; + _sceneText._colour3 = 0; + _sceneText._fontNumber = 2; + _sceneText._width = width; + + // Get the display message + Common::String msg = _vm->_dataManager->getMessage(resNum, lineNum); + + // Get the needed rect, and move it to the desired position + Rect textRect; + _globals->gfxManager().getStringBounds(msg.c_str(), textRect, width); + Rect sceneBounds = _globals->_sceneManager._scene->_sceneBounds; + sceneBounds.collapse(4, 2); + textRect.moveTo(pt); + textRect.contain(sceneBounds); + + // Set the text message + _sceneText.setup(msg); + _sceneText.setPosition(Common::Point(textRect.left, textRect.top)); + _sceneText.setPriority2(255); + _sceneText.show(); + + // Set the delay based on the number of words + int numWords = 0; + const char *msgP = msg.c_str(); + while (*msgP) { + if (*msgP++ == ' ') + ++numWords; + } + + setDelay(numWords * 18 + 120); +} + +SequenceManager *SequenceManager::globalManager() { + return &_globals->_sequenceManager; +} + +/*--------------------------------------------------------------------------*/ + +ConversationChoiceDialog::ConversationChoiceDialog() { + _stdColour = 23; + _highlightColour = _globals->_scenePalette._colours.background; + _fontNumber = 1; +} + +int ConversationChoiceDialog::execute(const Common::StringArray &choiceList) { + _gfxManager._font.setFontNumber(_fontNumber); + + _bounds = Rect(20, 0, 20, 0); + _choiceList.clear(); + + // Set up the list of choices + int yp = 0; + for (uint idx = 0; idx < choiceList.size(); ++idx) { + Rect tempRect; + _gfxManager._font.getStringBounds(choiceList[idx].c_str(), tempRect, 265); + tempRect.moveTo(25, yp + 10); + + _choiceList.push_back(ChoiceEntry(choiceList[idx], tempRect)); + yp += tempRect.height() + 5; + _bounds.extend(tempRect); + } + _selectedIndex = _choiceList.size(); + + // Set the position for the dialog + _bounds.bottom -= 10; + yp = 180 - _bounds.height(); + _bounds.translate(0, yp); + _bounds.right = _bounds.left + 280; + + // Draw the dialog + draw(); + _globals->_events.showCursor(); + + // Event handling loop + Event event; + while (!_vm->getEventManager()->shouldQuit()) { + while (!_globals->_events.getEvent(event, EVENT_KEYPRESS | EVENT_BUTTON_DOWN | EVENT_MOUSE_MOVE) && + !_vm->getEventManager()->shouldQuit()) + ; + if (_vm->getEventManager()->shouldQuit()) + break; + + if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode >= Common::KEYCODE_1) && + (event.kbd.keycode <= (Common::KEYCODE_0 + (int)_choiceList.size()))) { + // Selected an option by number + _selectedIndex = event.kbd.keycode - Common::KEYCODE_1; + break; + } else if ((_selectedIndex != _choiceList.size()) && ((event.eventType == EVENT_BUTTON_DOWN) || + (event.eventType == EVENT_BUTTON_UP))) { + // Item selected + break; + } else { + // Check if any item is highlighted + event.mousePos.x -= _gfxManager._bounds.left; + event.mousePos.y -= _gfxManager._bounds.top; + + uint idx = 0; + while ((idx < _choiceList.size()) && !_choiceList[idx]._bounds.contains(event.mousePos.x, event.mousePos.y)) + ++idx; + + if (idx != _selectedIndex) { + if (_selectedIndex != _choiceList.size()) { + // De-highlight previously selected item + _gfxManager._font._colours.foreground = _stdColour; + _gfxManager._font.writeLines(_choiceList[_selectedIndex]._msg.c_str(), + _choiceList[_selectedIndex]._bounds, ALIGN_LEFT); + } + + _selectedIndex = idx; + + if (_selectedIndex != _choiceList.size()) { + // Highlight the new item + _gfxManager._font._colours.foreground = _highlightColour; + _gfxManager._font.writeLines(_choiceList[idx]._msg.c_str(), _choiceList[idx]._bounds, ALIGN_LEFT); + } + + } + } + } + + // Remove the dialog + remove(); + + return _selectedIndex; +} + +void ConversationChoiceDialog::draw() { + // Make a backup copy of the area the dialog will occupy + Rect tempRect = _bounds; + tempRect.collapse(-10, -10); + _savedArea = Surface_getArea(_globals->_gfxManagerInstance.getSurface(), tempRect); + + // Fill in the contents of the entire dialog + _gfxManager._bounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + drawFrame(); + + _gfxManager._bounds = tempRect; + _gfxManager._font._colours.foreground = _stdColour; + _gfxManager.activate(); + + // Loop through writing the conversation choices + for (uint idx = 0; idx < _choiceList.size(); ++idx) { + Common::String strNum = Common::String::format("%d", idx + 1); + + // Write the choice number + _gfxManager._font.setPosition(13, _choiceList[idx]._bounds.top); + _gfxManager._font.writeString(strNum.c_str()); + + _gfxManager._font.writeLines(_choiceList[idx]._msg.c_str(), _choiceList[idx]._bounds, ALIGN_LEFT); + } + + _gfxManager.deactivate(); +} + +/*--------------------------------------------------------------------------*/ + +void Obj44::load(const byte *dataP) { + _id = READ_LE_UINT16(dataP); + for (int idx = 0; idx < OBJ44_LIST_SIZE; ++idx) + _field2[idx] = READ_LE_UINT16(dataP + 2 + idx * 2); + + const byte *listP = dataP + 0x10; + for (int idx = 0; idx < OBJ44_LIST_SIZE; ++idx, listP += 10) { + _list[idx]._id = READ_LE_UINT16(listP); + _list[idx]._scriptOffset = READ_LE_UINT16(listP + 2); + } + + _speakerOffset = READ_LE_UINT16(dataP + 0x42); +} + +void Obj44::synchronise(Serialiser &s) { + s.syncAsSint32LE(_id); + for (int i = 0; i < OBJ44_LIST_SIZE; ++i) + s.syncAsSint32LE(_field2[i]); + for (int i = 0; i < OBJ44_LIST_SIZE; ++i) + _list[OBJ44_LIST_SIZE].synchronise(s); + s.syncAsUint32LE(_speakerOffset); +} + +/*--------------------------------------------------------------------------*/ + +StripManager::StripManager() { + _callbackObject = NULL; + _activeSpeaker = NULL; + reset(); +} + +StripManager::~StripManager() { +} + +void StripManager::start(int stripNum, EventHandler *owner, StripCallback *callback) { + reset(); + + _stripNum = stripNum; + _callbackObject = callback; + _sceneNumber = _globals->_sceneManager._sceneNumber; + _sceneBounds = _globals->_sceneManager._scene->_sceneBounds; + _script.clear(); + + assert(owner); + owner->setAction(this, owner); +} + +void StripManager::reset() { + _actionIndex = 0; + _delayFrames = 0; + _owner = NULL; + _fmt = NULL; + _field2E6 = false; + _stripNum = -1; + _obj44Index = 0; + _field2E8 = 0; + _field20 = 0; + _activeSpeaker = NULL; + _textShown = false; + _callbackObject = NULL; + + _obj44List.clear(); + if (!_script.empty()) { + _script.clear(); + } +} + +void StripManager::load() { + // Get the script + byte *script = _vm->_dataManager->getResource(RES_STRIP, _stripNum, 2); + uint scriptSize = _vm->_memoryManager.getSize(script); + + _script.resize(scriptSize); + Common::copy(script, script + scriptSize, &_script[0]); + + DEALLOCATE(script); + + // Get the object list + byte *obj44List = _vm->_dataManager->getResource(RES_STRIP, _stripNum, 1); + int dataSize = _vm->_memoryManager.getSize(obj44List); + assert((dataSize % 0x44) == 0); + + byte *dataP = obj44List; + for (int idx = 0; idx < (dataSize / 0x44); ++idx, dataP += 0x44) { + Obj44 obj; + obj.load(dataP); + _obj44List.push_back(obj); + } + + DEALLOCATE(obj44List); +} + +void StripManager::synchronise(Serialiser &s) { + s.syncAsSint32LE(_stripNum); + s.syncAsSint32LE(_obj44Index); + s.syncAsSint32LE(_field20); + s.syncAsSint32LE(_sceneNumber); + _sceneBounds.synchronise(s); + SYNC_POINTER(_activeSpeaker); + s.syncAsByte(_textShown); + s.syncAsByte(_field2E6); + s.syncAsSint32LE(_field2E8); + + // Synchronise the item list + int arrSize = _obj44List.size(); + s.syncAsUint16LE(arrSize); + if (s.isLoading()) + _obj44List.resize(arrSize); + for (int i = 0; i < arrSize; ++i) + _obj44List[i].synchronise(s); + + // Synhcronise script data + int scriptSize = _script.size(); + s.syncAsUint16LE(scriptSize); + if (s.isLoading()) + _script.resize(scriptSize); + if (scriptSize > 0) + s.syncBytes(&_script[0], scriptSize); + + // Add speaker list + arrSize = _speakerList.size(); + s.syncAsUint16LE(arrSize); + if (s.isLoading()) + _speakerList.resize(arrSize); + for (int i = 0; i < arrSize; ++i) + SYNC_POINTER(_speakerList[i]); + + SYNC_POINTER(_callbackObject); +} + +void StripManager::remove() { + if (_textShown) { + if (_activeSpeaker) + _activeSpeaker->removeText(); + _textShown = false; + } + + if (_activeSpeaker) + _activeSpeaker->remove(); + + if (_sceneNumber != _globals->_sceneManager._scene->_sceneNumber) { + _globals->_sceneManager._scene->_sceneBounds = _sceneBounds; + _globals->_sceneManager._scene->loadScene(_sceneNumber); + } + + Action::remove(); +} + +void StripManager::signal() { + if (_textShown) { + _activeSpeaker->removeText(); + _textShown = false; + } + + if (_obj44Index < 0) { + EventHandler *owner = _fmt; + int stripNum = ABS(_obj44Index); + remove(); + + start(stripNum, owner); + return; + } else if (_obj44Index == 10000) { + // Reached end of strip + remove(); + return; + } + + // Run strip + + if (_obj44List.size() == 0) + // Load the data for the strip + load(); + + Obj44 &obj44 = _obj44List[_obj44Index]; + _field2E8 = obj44._id; + Common::StringArray choiceList; + + // Build up a list of script entries + int idx; + for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) { + if (!obj44._list[idx]._id) + break; + + // Get the next one + choiceList.push_back((const char *)&_script[0] + obj44._list[idx]._scriptOffset); + } + + int strIndex = 0; + if (choiceList.size() > 1) + // Get the user to select a conversation option + strIndex = _choiceDialog.execute(choiceList); + + if ((choiceList.size() != 1) && !_field2E6) + _delayFrames = 1; + else { + Speaker *speakerP = getSpeaker((const char *)&_script[0] + obj44._speakerOffset); + if (!speakerP) + error("Speaker not found. Screenplay: %s %d", (const char *)&_script[0] + obj44._speakerOffset, _stripNum); + + if (speakerP != _activeSpeaker) { + if (_activeSpeaker) + _activeSpeaker->remove(); + _activeSpeaker = speakerP; + + if ((_activeSpeaker->_newSceneNumber == -1) && (_globals->_sceneManager._scene->_sceneNumber != _sceneNumber)) { + _globals->_sceneManager._scene->_sceneBounds = _sceneBounds; + _globals->_sceneManager._scene->loadScene(_sceneNumber); + } + + _activeSpeaker->proc12(this); + } + + if (_callbackObject) { + for (idx = 0; idx < OBJ44_LIST_SIZE; ++idx) { + if (!obj44._field2[idx]) + break; + + _callbackObject->stripCallback(obj44._field2[idx]); + } + } + + _textShown = true; + _activeSpeaker->setText(choiceList[strIndex]); + } + + _obj44Index = getNewIndex(obj44._list[strIndex]._id); + if (_obj44Index == 10001) { + MessageDialog::show("Strip Failure: Node not found", OK_BTN_STRING); + _obj44Index = 0; + } +} + +void StripManager::process(Event &event) { + Action::process(event); + if (event.handled) + return; + + if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) { + if (_obj44Index != 10000) { + int currIndex = _obj44Index; + while (!_obj44List[_obj44Index + 1]._id) { + _obj44Index = getNewIndex(_obj44List[_obj44Index]._id); + if ((_obj44Index < 0) || (_obj44Index == 10000)) + break; + currIndex = _obj44Index; + } + + _field2E8 = _obj44List[currIndex]._id; + } + + // Signal the end of the strip + _delayFrames = 0; + event.handled = true; + signal(); + } else if (event.eventType & (EVENT_BUTTON_DOWN | EVENT_KEYPRESS)) { + // Move to next sequence in the strip + _delayFrames = 0; + event.handled = true; + signal(); + } +} + +void StripManager::addSpeaker(Speaker *speaker) { + assert(_speakerList.size() < 100); + _speakerList.push_back(speaker); +} + +Speaker *StripManager::getSpeaker(const char *speakerName) { + for (uint idx = 0; idx < _speakerList.size(); ++idx) { + if (!strcmp(_speakerList[idx]->_speakerName.c_str(), speakerName)) + return _speakerList[idx]; + } + + return NULL; +} + +int StripManager::getNewIndex(int id) { + if (id == 10000) + return id; + + for (uint idx = 0; idx < _obj44List.size(); ++idx) { + if (_obj44List[idx]._id == id) { + return (id == 0) ? 10001 : idx; + } + } + + return 10001; +} + +/*--------------------------------------------------------------------------*/ + +Speaker::Speaker(): EventHandler() { + _newSceneNumber = -1; + _hideObjects = true; + _field18 = 0; + _textWidth = 140; + _textPos = Common::Point(10, 20); + _fontNumber = 2; + _textMode = ALIGN_LEFT; + _colour1 = _colour2 = _colour3 = _globals->_scenePalette._colours.foreground; + _action = NULL; + _speakerName = "SPEAKER"; +} + +void Speaker::synchronise(Serialiser &s) { + _fieldA.synchronise(s); + SYNC_POINTER(_field18); + s.syncString(_speakerName); + s.syncAsSint32LE(_newSceneNumber); + s.syncAsSint32LE(_oldSceneNumber); + _sceneBounds.synchronise(s); + s.syncAsSint32LE(_textWidth); + s.syncAsSint16LE(_textPos.x); s.syncAsSint16LE(_textPos.y); + s.syncAsSint32LE(_fontNumber); + SYNC_ENUM(_textMode, TextAlign); + s.syncAsSint16LE(_colour1); + s.syncAsSint16LE(_colour2); + s.syncAsSint16LE(_colour3); + s.syncAsByte(_hideObjects); +} + +void Speaker::remove() { + if (_hideObjects) + SceneObjectList::deactivate(); +} + +void Speaker::proc12(Action *action) { + _action = action; + if (_newSceneNumber != -1) { + _oldSceneNumber = _globals->_sceneManager._sceneNumber; + _sceneBounds = _globals->_sceneManager._scene->_sceneBounds; + _globals->_sceneManager._scene->loadScene(_newSceneNumber); + } + + if (_hideObjects) + // Activate the object list for display + _objectList.activate(); + + // Draw the speaker objects without any fading + FadeMode fadeMode = _globals->_sceneManager._fadeMode; + _globals->_sceneManager._fadeMode = FADEMODE_IMMEDIATE; + _globals->_sceneObjects->draw(); + _globals->_sceneManager._fadeMode = fadeMode; +} + +void Speaker::setText(const Common::String &msg) { + _globals->_sceneObjects->draw(); + + _sceneText._colour1 = _colour1; + _sceneText._colour2 = _colour2; + _sceneText._colour3 = _colour3; + _sceneText._width = _textWidth; + _sceneText._fontNumber = _fontNumber; + _sceneText._textMode = _textMode; + _sceneText.setup(msg); + _sceneText.setPosition(_textPos); + _sceneText.setPriority2(256); + + // Count the number of words (by spaces) in the string + const char *msgP = msg.c_str(); + int spaceCount = 0; + while (*msgP) { + if (*msgP++ == ' ') + ++spaceCount; + } + + int numFrames = spaceCount * STRIP_WORD_DELAY + 120; + if (_action) + _action->setDelay(numFrames); +} + +void Speaker::removeText() { + _sceneText.remove(); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerGameText::SpeakerGameText(): Speaker() { + _speakerName = "GAMETEXT"; + _textPos = Common::Point(40, 40); + _textMode = ALIGN_CENTRE; + _colour1 = 7; + _textWidth = 230; + _hideObjects = false; +} + +/*--------------------------------------------------------------------------*/ + +ScreenSpeaker::ScreenSpeaker(): Speaker() { + _npc = NULL; + _textMode = ALIGN_CENTRE; +} + +void ScreenSpeaker::setText(const Common::String &msg) { + GfxManager gfxMan; + gfxMan.activate(); + gfxMan._font.setFontNumber(_fontNumber); + Rect textRect; + + _globals->gfxManager().getStringBounds(msg.c_str(), textRect, _textWidth); + if (_npc) { + textRect.centre(_npc->_position.x, _npc->_bounds.top - (textRect.height() / 2 + 10)); + } else { + textRect.centre(_globals->_sceneManager._scene->_sceneBounds.left + + (_globals->_sceneManager._scene->_sceneBounds.width() / 2), + _globals->_sceneManager._scene->_sceneBounds.top); + } + + Rect rect2 = _globals->_sceneManager._scene->_sceneBounds; + rect2.collapse(10, 6); + textRect.contain(rect2); + + _textPos.x = textRect.left; + _textPos.y = textRect.top; + Speaker::setText(msg); + + gfxMan.deactivate(); +} + +/*--------------------------------------------------------------------------*/ + +void SpeakerAction::signal() { + switch (_actionIndex++) { + case 0: + setDelay(_globals->_randomSource.getRandomNumber(60) + 60); + break; + case 1: + static_cast<SceneObject *>(_owner)->setFrame(1); + static_cast<SceneObject *>(_owner)->animate(ANIM_MODE_5, this, NULL); + break; + case 2: + setDelay(_globals->_randomSource.getRandomNumber(10)); + _actionIndex = 0; + break; + default: + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void AnimatedSpeaker::removeText() { + Speaker::removeText(); + _object1.remove(); + _object2.remove(); + + _objectList.draw(); +} + +} // end of namespace tSage diff --git a/engines/tsage/converse.h b/engines/tsage/converse.h new file mode 100644 index 0000000000..6159b2f782 --- /dev/null +++ b/engines/tsage/converse.h @@ -0,0 +1,229 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/converse.h $ + * $Id: converse.h 230 2011-02-12 06:57:31Z dreammaster $ + * + */ + +#ifndef TSAGE_CONVERSE_H +#define TSAGE_CONVERSE_H + +#include "tsage/core.h" +#include "tsage/dialogs.h" + +namespace tSage { + +class StripCallback: public Action { +public: + virtual void stripCallback(int v) = 0; +}; + +class SequenceManager: public Action { +private: + void setup(); + uint16 getNextValue(); + void setMessage(int resNum, int lineNum, int colour, const Common::Point &pt, int width); + SequenceManager *globalManager(); +public: + SceneText _sceneText; + int _resNum; + uint _sequenceOffset; + bool _keepActive; + int _field24; + int _field26; + Common::Array<byte> _sequenceData; + int _objectIndex; + SceneObject *_sceneObject; + SceneObject *_objectList[6]; + SoundHandler _soundHandler; +public: + SequenceManager(); + + virtual Common::String getClassName() { return "SequenceManager"; } + virtual void synchronise(Serialiser &s); + virtual void remove(); + virtual void signal(); + virtual void process(Event &event); + virtual void attached(EventHandler *newOwner, EventHandler *fmt, va_list va); +}; + + +class Speaker: public EventHandler { +public: + Rect _fieldA; + Action *_field18; + Common::String _speakerName; + int _newSceneNumber; + int _oldSceneNumber; + SceneObjectList _objectList; + Rect _sceneBounds; + SceneText _sceneText; + int _textWidth; + Common::Point _textPos; + int _fontNumber; + TextAlign _textMode; + int _colour1, _colour2, _colour3; + bool _hideObjects; +public: + Speaker(); + + virtual Common::String getClassName() { return "Speaker"; } + virtual void synchronise(Serialiser &s); + virtual void remove(); + virtual void proc12(Action *action); + virtual void setText(const Common::String &msg); + virtual void removeText(); + + void setTextPos(const Common::Point &pt) { _textPos = pt; } +}; + +class SpeakerGameText: public Speaker { +public: + SpeakerGameText(); + + virtual Common::String getClassName() { return "SpeakerGameText"; } +}; + +class ScreenSpeaker: public Speaker { +public: + SceneItem *_npc; +public: + ScreenSpeaker(); + + virtual Common::String getClassName() { return "ScreenSpeaker"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerAction: public Action { +public: + virtual void signal(); + + virtual Common::String getClassName() { return "SpeakerAction"; } +}; + +class AnimatedSpeaker: public Speaker { +public: + SceneObject _object1; + SceneObject _object2; + SpeakerAction _speakerAction; +public: + virtual Common::String getClassName() { return "AnimatedSpeaker"; } + virtual void removeText(); +}; + +class ChoiceEntry { +public: + Common::String _msg; + Rect _bounds; + + ChoiceEntry() {} + ChoiceEntry(const Common::String &msg, const Rect &bounds) { + _msg = msg; + _bounds = bounds; + } +}; + +class ConversationChoiceDialog: public ModalDialog { +public: + int _stdColour; + int _highlightColour; + int _fontNumber; + int _savedFgColour; + int _savedFontNumber; + Common::Array<ChoiceEntry> _choiceList; + uint _selectedIndex; +public: + ConversationChoiceDialog(); + + void setColours(int stdColour, int highlightColour) { + _stdColour = stdColour; + _highlightColour = highlightColour; + } + void setFontNumber(int fontNum) { _fontNumber = fontNum; } + int execute(const Common::StringArray &choiceList); + + virtual void draw(); +}; + +class Obj0A: public Serialisable { +public: + int _id; + uint _scriptOffset; + + virtual void synchronise(Serialiser &s) { + s.syncAsSint32LE(_id); + s.syncAsUint32LE(_scriptOffset); + } +}; + +#define OBJ44_LIST_SIZE 5 + +class Obj44: public Serialisable { +public: + int _id; + int _field2[OBJ44_LIST_SIZE]; + Obj0A _list[OBJ44_LIST_SIZE]; + uint _speakerOffset; +public: + void load(const byte *dataP); + virtual void synchronise(Serialiser &s); +}; + +class StripManager: public Action { +private: + void reset(); + void load(); + Speaker *getSpeaker(const char *speakerName); + int getNewIndex(int newId); +public: + int _stripNum; + int _obj44Index; + int _field20; + int _sceneNumber; + Rect _sceneBounds; + ConversationChoiceDialog _choiceDialog; + Common::Array<Speaker *> _speakerList; + StripCallback *_callbackObject; + Speaker *_activeSpeaker; + bool _textShown; + bool _field2E6; + int _field2E8; + Common::Array<Obj44> _obj44List; + Common::Array<byte> _script; +public: + StripManager(); + virtual ~StripManager(); + + virtual void synchronise(Serialiser &s); + virtual void remove(); + virtual void signal(); + virtual void process(Event &event); + + void start(int stripNum, EventHandler *owner, StripCallback *callback = NULL); + void setCallback(StripCallback *callback) { _callbackObject = callback; } + void setColours(int stdColour, int highlightColour) { _choiceDialog.setColours(stdColour, highlightColour); } + void setFontNumber(int fontNum) { _choiceDialog.setFontNumber(fontNum); } + void addSpeaker(Speaker *speaker); +}; + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp new file mode 100644 index 0000000000..5ccb48f05b --- /dev/null +++ b/engines/tsage/core.cpp @@ -0,0 +1,3732 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/core.cpp $ + * $Id: core.cpp 229 2011-02-12 06:50:14Z dreammaster $ + * + */ + +#include "common/system.h" +#include "common/config-manager.h" +#include "common/translation.h" +#include "engines/engine.h" +#include "gui/saveload.h" +#include "tsage/tsage.h" +#include "tsage/core.h" +#include "tsage/dialogs.h" +#include "tsage/events.h" +#include "tsage/scenes.h" +#include "tsage/staticres.h" +#include "tsage/globals.h" + +namespace tSage { + +// The engine uses ScumMVM screen buffering, so all logic is hardcoded to use pane buffer 0 +#define CURRENT_PANENUM 0 + +/*--------------------------------------------------------------------------*/ + +InvObject::InvObject(int sceneNumber, int rlbNum, int cursorNum, CursorType cursorId, const Common::String description): + _sceneNumber(sceneNumber), _rlbNum(rlbNum), _cursorNum(cursorNum), _cursorId(cursorId), + _description(description) { + _displayResNum = 3; + _iconResNum = 5; + + // Decode the image for the inventory item to get it's display bounds + uint size; + byte *imgData = _vm->_dataManager->getSubResource(_displayResNum, _rlbNum, _cursorNum, &size); + GfxSurface s = surfaceFromRes(imgData); + _bounds = s.getBounds(); + + DEALLOCATE(imgData); +} + +void InvObject::setCursor() { + _globals->_events._currentCursor = _cursorId; + + if (_iconResNum != -1) { + GfxSurface s = surfaceFromRes(_iconResNum, _rlbNum, _cursorNum); + + Graphics::Surface src = s.lockSurface(); + _globals->_events.setCursor(src, s._transColour, s._centroid, _cursorId); + } +} + +/*--------------------------------------------------------------------------*/ + +InvObjectList::InvObjectList(): + _stunner(2280, 1, 2, OBJECT_STUNNER, "This is your stunner."), + _scanner(1, 1, 3, OBJECT_SCANNER, "A combination scanner comm unit."), + _stasisBox(5200, 1, 4, OBJECT_STASIS_BOX, "A stasis box."), + _infoDisk(40, 1, 1, OBJECT_INFODISK, "The infodisk you took from the assassin."), + _stasisNegator(0, 2, 2, OBJECT_STASIS_NEGATOR, "The stasis field negator."), + _keyDevice(4250, 1, 6, OBJECT_KEY_DEVICE, "A magnetic key device."), + _medkit(2280, 1, 7, OBJECT_MEDKIT, "Your medkit."), + _ladder(4100, 1, 8, OBJECT_LADDER, "The chief's ladder."), + _rope(4150, 1, 9, OBJECT_ROPE, "The chief's rope."), + _key(7700, 1, 11, OBJECT_KEY, "A key."), + _translator(7700, 1, 13, OBJECT_TRANSLATOR, "The dolphin translator box."), + _ale(2150, 1, 10, OBJECT_ALE, "A bottle of ale."), + _paper(7700, 1, 12, OBJECT_PAPER, "A slip of paper with the numbers 2,4, and 3 written on it."), + _waldos(0, 1, 14, OBJECT_WALDOS, "A pair of waldos from the ruined probe."), + _stasisBox2(8100, 1, 4, OBJECT_STASIS_BOX2, "A stasis box."), + _ring(8100, 2, 5, OBJECT_RING, "This is a signet ring sent to you by Louis Wu."), + _cloak(9850, 2, 6, OBJECT_CLOAK, "A fine silk cloak."), + _tunic(9450, 2, 7, OBJECT_TUNIC, "The patriarch's soiled tunic."), + _candle(9500, 2, 8, OBJECT_CANDLE, "A tallow candle."), + _straw(9400, 2, 9, OBJECT_STRAW, "Clean, dry straw."), + _scimitar(9850, 1, 18, OBJECT_SCIMITAR, "A scimitar from the Patriarch's closet."), + _sword(9850, 1, 17, OBJECT_SWORD, "A short sword from the Patriarch's closet."), + _helmet(9500, 2, 4, OBJECT_HELMET, "Some type of helmet."), + _items(4300, 2, 10, OBJECT_ITEMS, "Two interesting items from the Tnuctipun vessel."), + _concentrator(4300, 2, 11, OBJECT_CONCENTRATOR, "The Tnuctipun anti-matter concentrator contained in a stasis field."), + _nullifier(5200, 2, 12, OBJECT_NULLIFIER, "A purported neural wave nullifier."), + _peg(4045, 2, 16, OBJECT_PEG, "A peg with a symbol."), + _vial(5100, 2, 17, OBJECT_VIAL, "A vial of the bat creatures anti-pheromone drug."), + _jacket(9850, 3, 1, OBJECT_JACKET, "A natty padded jacket."), + _tunic2(9850, 3, 2, OBJECT_TUNIC2, "A very hairy tunic."), + _bone(5300, 3, 5, OBJECT_BONE, "A very sharp bone."), + _jar(7700, 3, 4, OBJECT_JAR, "An jar filled with a green substance."), + _emptyJar(7700, 3, 3, OBJECT_EMPTY_JAR, "An empty jar.") { + + // Add the items to the list + _itemList.push_back(&_stunner); + _itemList.push_back(&_scanner); + _itemList.push_back(&_stasisBox); + _itemList.push_back(&_infoDisk); + _itemList.push_back(&_stasisNegator); + _itemList.push_back(&_keyDevice); + _itemList.push_back(&_medkit); + _itemList.push_back(&_ladder); + _itemList.push_back(&_rope); + _itemList.push_back(&_key); + _itemList.push_back(&_translator); + _itemList.push_back(&_ale); + _itemList.push_back(&_paper); + _itemList.push_back(&_waldos); + _itemList.push_back(&_stasisBox2); + _itemList.push_back(&_ring); + _itemList.push_back(&_cloak); + _itemList.push_back(&_tunic); + _itemList.push_back(&_candle); + _itemList.push_back(&_straw); + _itemList.push_back(&_scimitar); + _itemList.push_back(&_sword); + _itemList.push_back(&_helmet); + _itemList.push_back(&_items); + _itemList.push_back(&_concentrator); + _itemList.push_back(&_nullifier); + _itemList.push_back(&_peg); + _itemList.push_back(&_vial); + _itemList.push_back(&_jacket); + _itemList.push_back(&_tunic2); + _itemList.push_back(&_bone); + _itemList.push_back(&_jar); + _itemList.push_back(&_emptyJar); + + _selectedItem = NULL; +} + +void InvObjectList::synchronise(Serialiser &s) { + SavedObject::synchronise(s); + SYNC_POINTER(_selectedItem); +} + +/*--------------------------------------------------------------------------*/ + +void EventHandler::dispatch() { + if (_action) _action->dispatch(); +} + +void EventHandler::setAction(Action *action, EventHandler *fmt, ...) { + if (_action) { + _action->_fmt = NULL; + _action->remove(); + } + + _action = action; + if (action) { + va_list va; + va_start(va, fmt); + _action->attached(this, fmt, va); + va_end(va); + } +} + +/*--------------------------------------------------------------------------*/ + +Action::Action() { + _actionIndex = 0; + _owner = NULL; + _fmt = NULL; +} + +void Action::synchronise(Serialiser &s) { + EventHandler::synchronise(s); + if (s.isLoading()) + remove(); + + SYNC_POINTER(_owner); + s.syncAsSint32LE(_actionIndex); + s.syncAsSint32LE(_delayFrames); + s.syncAsUint32LE(_startFrame); + s.syncAsSint16LE(_field16); + SYNC_POINTER(_fmt); +} + +void Action::remove() { + if (_action) + _action->remove(); + + if (_owner) { + _owner->_action = NULL; + _owner = NULL; + } else { + _globals->_sceneManager.removeAction(this); + } + + _field16 = 0; + if (_fmt) + _fmt->signal(); +} + +void Action::process(Event &event) { + if (_action) + _action->process(event); +} + +void Action::dispatch() { + if (_action) + _action->dispatch(); + + if (_delayFrames) { + uint32 frameNumber = _globals->_events.getFrameNumber(); + + if (frameNumber >= _startFrame) { + _delayFrames -= frameNumber - _startFrame; + _startFrame = frameNumber; + if (_delayFrames <= 0) { + _delayFrames = 0; + signal(); + } + } + } +} + +void Action::attached(EventHandler *newOwner, EventHandler *fmt, va_list va) { + _actionIndex = 0; + _delayFrames = 0; + _startFrame = _globals->_events.getFrameNumber(); + _owner = newOwner; + _fmt = fmt; + _field16 = 1; + signal(); +} + +void Action::setDelay(int numFrames) { + _delayFrames = numFrames; + _startFrame = _globals->_events.getFrameNumber(); +} + +/*--------------------------------------------------------------------------*/ + +ObjectMover::~ObjectMover() { + if (_sceneObject->_mover == this) + _sceneObject->_mover = NULL; +} + +void ObjectMover::synchronise(Serialiser &s) { + EventHandler::synchronise(s); + + s.syncAsSint16LE(_destPosition.x); s.syncAsSint16LE(_destPosition.y); + s.syncAsSint16LE(_moveDelta.x); s.syncAsSint16LE(_moveDelta.y); + s.syncAsSint16LE(_moveSign.x); s.syncAsSint16LE(_moveSign.y); + s.syncAsSint32LE(_minorDiff); + s.syncAsSint32LE(_majorDiff); + s.syncAsSint32LE(_field1A); + SYNC_POINTER(_action); + SYNC_POINTER(_sceneObject); +} + +void ObjectMover::remove() { + if (_sceneObject->_mover == this) + _sceneObject->_mover = NULL; + + delete this; +} + +void ObjectMover::dispatch() { + Common::Point currPos = _sceneObject->_position; + int yDiff = _sceneObject->_yDiff; + + if (dontMove()) + return; + + _sceneObject->_regionIndex = 0; + if (_moveDelta.x >= _moveDelta.y) { + int xAmount = _moveSign.x * _sceneObject->_moveDiff.x * _sceneObject->_percent / 100; + if (!xAmount) + xAmount = _moveSign.x; + currPos.x += xAmount; + + int yAmount = ABS(_destPosition.y - currPos.y); + int yChange = _majorDiff / ABS(xAmount); + int ySign; + + if (!yChange) + ySign = _moveSign.y; + else { + int v = yAmount / yChange; + _field1A += yAmount % yChange; + if (_field1A >= yChange) { + ++v; + _field1A -= yChange; + } + + ySign = _moveSign.y * v; + } + + currPos.y += ySign; + _majorDiff -= ABS(xAmount); + + } else { + int yAmount = _moveSign.y * _sceneObject->_moveDiff.y * _sceneObject->_percent / 100; + if (!yAmount) + yAmount = _moveSign.y; + currPos.y += yAmount; + + int xAmount = ABS(_destPosition.x - currPos.x); + int xChange = _majorDiff / ABS(yAmount); + int xSign; + + if (!xChange) + xSign = _moveSign.x; + else { + int v = xAmount / xChange; + _field1A += xAmount % xChange; + if (_field1A >= xChange) { + ++v; + _field1A -= xChange; + } + + xSign = _moveSign.x * v; + } + + currPos.x += xSign; + _majorDiff -= ABS(yAmount); + } + + _sceneObject->_regionIndex = _sceneObject->checkRegion(currPos); + if (!_sceneObject->_regionIndex) { + _sceneObject->setPosition(currPos, yDiff); + _sceneObject->getHorizBounds(); + + if (dontMove()) { + _sceneObject->_position = _destPosition; + endMove(); + } + } else { + endMove(); + } +} + +void ObjectMover::setup(const Common::Point &destPos) { + _sceneObject->calcAngle(destPos); + + if ((_sceneObject->_objectWrapper) && !(_sceneObject->_flags & OBJFLAG_SUPPRESS_DISPATCH)) + _sceneObject->_objectWrapper->dispatch(); + + // Get the difference + int diffX = destPos.x - _sceneObject->_position.x; + int diffY = destPos.y - _sceneObject->_position.y; + int xSign = (diffX < 0) ? -1 : (diffX > 0 ? 1 : 0); + int ySign = (diffY < 0) ? -1 : (diffY > 0 ? 1 : 0); + diffX = ABS(diffX); + diffY = ABS(diffY); + + if (diffX < diffY) { + _minorDiff = diffX / 2; + _majorDiff = diffY; + } else { + _minorDiff = diffY / 2; + _majorDiff = diffX; + } + + // Set the destination position + _destPosition = destPos; + _moveDelta = Common::Point(diffX, diffY); + _moveSign = Common::Point(xSign, ySign); + _field1A = 0; + + if (!diffX && !diffY) + // Object is already at the correct destination + endMove(); +} + +bool ObjectMover::dontMove() const { + return (_majorDiff <= 0); +} + +void ObjectMover::endMove() { + EventHandler *actionP = _action; + remove(); + + if (actionP) + actionP->signal(); +} + +/*--------------------------------------------------------------------------*/ + +ObjectMover2::ObjectMover2(): ObjectMover() { + _destObject = NULL; +} + +void ObjectMover2::synchronise(Serialiser &s) { + ObjectMover::synchronise(s); + + SYNC_POINTER(_destObject); + s.syncAsSint32LE(_minArea); + s.syncAsSint32LE(_maxArea); +} + +void ObjectMover2::dispatch() { + int area = _sceneObject->getSpliceArea(_destObject); + if (area > _maxArea) { + // Setup again for the new destination + setup(_destObject->_position); + ObjectMover::dispatch(); + } else if (area >= _minArea) { + // Keep dispatching + ObjectMover::dispatch(); + } else { + // Within minimum, so end move + endMove(); + } +} + +void ObjectMover2::startMove(SceneObject *sceneObj, va_list va) { + // Set up fields + _sceneObject = sceneObj; + + _minArea = va_arg(va, int); + _maxArea = va_arg(va, int); + _destObject = va_arg(va, SceneObject *); + + setup(_destObject->_position); +} + +void ObjectMover2::endMove() { + _sceneObject->_regionIndex = 0x40; +} + +/*--------------------------------------------------------------------------*/ + +void ObjectMover3::dispatch() { + int area = _sceneObject->getSpliceArea(_destObject); + if (area <= _minArea) { + endMove(); + } else { + setup(_destObject->_position); + ObjectMover::dispatch(); + } +} + +void ObjectMover3::startMove(SceneObject *sceneObj, va_list va) { + _sceneObject = sceneObj; + _destObject = va_arg(va, SceneObject *); + _minArea = va_arg(va, int); + _action = va_arg(va, Action *); + + setup(_destObject->_position); +} + +void ObjectMover3::endMove() { + ObjectMover::endMove(); +} + +/*--------------------------------------------------------------------------*/ + +void NpcMover::startMove(SceneObject *sceneObj, va_list va) { + _sceneObject = sceneObj; + + Common::Point *destPos = va_arg(va, Common::Point *); + _action = va_arg(va, Action *); + + setup(*destPos); +} + +/*--------------------------------------------------------------------------*/ + +void PlayerMover::synchronise(Serialiser &s) { + NpcMover::synchronise(s); + + s.syncAsSint16LE(_finalDest.x); s.syncAsSint16LE(_finalDest.y); + s.syncAsSint32LE(_routeIndex); + + for (int i = 0; i < MAX_ROUTE_SIZE; ++i) { + s.syncAsSint16LE(_routeList[i].x); s.syncAsSint16LE(_routeList[i].y); + } +} + +void PlayerMover::startMove(SceneObject *sceneObj, va_list va) { + _sceneObject = sceneObj; + Common::Point *pt = va_arg(va, Common::Point *); + _finalDest = *pt; + _action = va_arg(va, Action *); + + setDest(_finalDest); +} + +void PlayerMover::endMove() { + while (++_routeIndex != 0) { + if ((_routeList[_routeIndex].x == ROUTE_END_VAL) || + (_routeList[_routeIndex].y == ROUTE_END_VAL) || + (_sceneObject->_regionIndex)) { + // Movement route is completely finished + ObjectMover::endMove(); + return; + } + + if ((_routeList[_routeIndex].x != _sceneObject->_position.x) || + (_routeList[_routeIndex].y != _sceneObject->_position.y)) + break; + } + + // Set up the new interim destination along the route + _globals->_walkRegions._routeEnds.moveSrc = _globals->_walkRegions._routeEnds.moveDest; + _globals->_walkRegions._routeEnds.moveDest = _routeList[_routeIndex]; + setup(_routeList[_routeIndex]); + dispatch(); +} + +void PlayerMover::setDest(const Common::Point &destPos) { + _routeList[0] = _sceneObject->_position; + + if (_globals->_walkRegions._resNum == -1) { + // Scene has no walk regions defined, so player can walk anywhere directly + _routeList[0] = destPos; + _routeList[1] = Common::Point(ROUTE_END_VAL, ROUTE_END_VAL); + } else { + // Figure out a path to the destination (or as close as possible to it) + pathfind(_routeList, _sceneObject->_position, destPos, _globals->_walkRegions._routeEnds); + } + + _routeIndex = 0; + _globals->_walkRegions._routeEnds.moveSrc = _sceneObject->_position; + _globals->_walkRegions._routeEnds.moveDest = _routeList[0]; + setup(_routeList[0]); +} + +#define REGION_LIST_SIZE 20 + +void PlayerMover::pathfind(Common::Point *routeList, Common::Point srcPos, Common::Point destPos, RouteEnds routeEnds) { + List<int> regionIndexes; + RouteEnds tempRouteEnds; + int routeRegions[REGION_LIST_SIZE]; + Common::Point objPos; + + // Get the region the source is in + int srcRegion = _globals->_walkRegions.indexOf(srcPos); + if (srcRegion == -1) { + srcRegion = findClosestRegion(srcPos, regionIndexes); + } + + // Main loop for building up the path + routeRegions[0] = 0; + while (!routeRegions[0]) { + // Check the destination region + int destRegion = _globals->_walkRegions.indexOf(destPos, ®ionIndexes); + + if ((srcRegion == -1) && (destRegion == -1)) { + // Both source and destination are outside walkable areas + } else if (srcRegion == -1) { + // Source is outside walkable areas + tempRouteEnds = routeEnds; + objPos = _sceneObject->_position; + + Common::Point newPos; + findLinePoint(&tempRouteEnds, &objPos, 1, &newPos); + int srcId = _globals->_walkRegions.indexOf(newPos); + + if (srcId == -1) { + tempRouteEnds.moveDest = tempRouteEnds.moveSrc; + tempRouteEnds.moveSrc = routeEnds.moveDest; + + findLinePoint(&tempRouteEnds, &objPos, 1, &newPos); + srcRegion = _globals->_walkRegions.indexOf(newPos); + + if (srcRegion == -1) + srcRegion = checkMover(srcPos, destPos); + } + + } else if (destRegion == -1) { + // Destination is outside walkable areas + destRegion = findClosestRegion(destPos, regionIndexes); + if (destRegion == -1) { + // No further route found, so end it + *routeList++ = srcPos; + break; + } else { + _finalDest = destPos; + } + } + + if (srcRegion == destRegion) { + *routeList++ = (srcRegion == -1) ? srcPos : destPos; + break; + } + + int var6; + proc1(routeRegions, srcRegion, destRegion, var6); + + if (!routeRegions[0]) { + regionIndexes.push_back(destRegion); + continue; + } + + _globals->_walkRegions._field18[0]._pt1 = srcPos; + _globals->_walkRegions._field18[0]._pt2 = srcPos; + _globals->_walkRegions._field18[1]._pt1 = destPos; + _globals->_walkRegions._field18[1]._pt2 = destPos; + + int tempList[REGION_LIST_SIZE]; + tempList[0] = 0; + int endIndex = 0; + int idx = 1; + + do { + int breakEntry = routeRegions[idx]; + int breakEntry2 = routeRegions[idx + 1]; + + int listIndex = 0; + while (_globals->_walkRegions._idxList[_globals->_walkRegions[breakEntry]._idxListIndex + listIndex] != + breakEntry2) + ++listIndex; + + tempList[idx] = _globals->_walkRegions._idxList2[_globals->_walkRegions[breakEntry]._idxList2Index + + listIndex]; + + ++endIndex; + } while (routeRegions[++idx] != destRegion); + + tempList[idx] = 1; + idx = 0; + for (int listIndex = 1; listIndex <= endIndex; ++listIndex) { + int var10 = tempList[listIndex]; + int var12 = tempList[listIndex + 1]; + + if (sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var12]._pt1, + _globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2) && + sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var12]._pt2, + _globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2)) + continue; + + Common::Point tempPt; + if (sub_F8E5(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[1]._pt1, + _globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var10]._pt2, &tempPt)) { + // Add point to the route list + _globals->_walkRegions._field18[0]._pt1 = tempPt; + *routeList++ = tempPt; + } else { + int v16 = + (findDistance(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var10]._pt1) << 1) + + (findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[1]._pt1) << 1) + + findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var12]._pt1) + + findDistance(_globals->_walkRegions._field18[var10]._pt1, _globals->_walkRegions._field18[var12]._pt2); + + int v1A = + (findDistance(_globals->_walkRegions._field18[0]._pt1, _globals->_walkRegions._field18[var10]._pt2) << 1) + + (findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[1]._pt2) << 1) + + findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[var12]._pt1) + + findDistance(_globals->_walkRegions._field18[var10]._pt2, _globals->_walkRegions._field18[var12]._pt2); + + if (v16 < v1A) { + checkMovement2(_globals->_walkRegions._field18[var10]._pt1, + _globals->_walkRegions._field18[var10]._pt2, 1, objPos); + } else { + checkMovement2(_globals->_walkRegions._field18[var10]._pt2, + _globals->_walkRegions._field18[var10]._pt1, 1, objPos); + } + + _globals->_walkRegions._field18[0]._pt1 = objPos; + *routeList++ = objPos; + } + } + + // Add in the route entry + *routeList++ = _globals->_walkRegions._field18[1]._pt1; + } + + // Mark the end of the path + *routeList = Common::Point(ROUTE_END_VAL, ROUTE_END_VAL); +} + +int PlayerMover::regionIndexOf(const Common::Point &pt) { + for (uint idx = 0; idx < _globals->_walkRegions._regionList.size(); ++idx) { + if (_globals->_walkRegions._regionList[idx].contains(pt)) + return idx + 1; + } + + return 0; +} + +int PlayerMover::findClosestRegion(Common::Point &pt, List<int> &indexList) { + int newY = pt.y; + int result = 0; + + for (int idx = 1; idx < SCREEN_WIDTH; ++idx, newY += idx) { + int newX = pt.x + idx; + result = regionIndexOf(newX, pt.y); + + if ((result == 0) || indexList.contains(result)) { + newY = pt.y + idx; + result = regionIndexOf(newX, newY); + + if ((result == 0) || indexList.contains(result)) { + newX -= idx; + result = regionIndexOf(newX, newY); + + if ((result == 0) || indexList.contains(result)) { + newX -= idx; + result = regionIndexOf(newX, newY); + + if ((result == 0) || indexList.contains(result)) { + newY -= idx; + result = regionIndexOf(newX, newY); + + if ((result == 0) || indexList.contains(result)) { + newY -= idx; + result = regionIndexOf(newX, newY); + + if ((result == 0) || indexList.contains(result)) { + newX += idx; + result = regionIndexOf(newX, newY); + + if ((result == 0) || indexList.contains(result)) { + newX += idx; + result = regionIndexOf(newX, newY); + + if ((result == 0) || indexList.contains(result)) { + continue; + } + } + } + } + } + } + } + } + + // Found an index + pt.x = newX; + pt.y = newY; + return result; + } + + return (result == 0) ? -1 : result; +} + +Common::Point *PlayerMover::findLinePoint(RouteEnds *routeEnds, Common::Point *objPos, int length, Common::Point *outPos) { + int xp = objPos->x + (((routeEnds->moveDest.y - routeEnds->moveSrc.y) * 9) / 8); + int yp = objPos->y - (((routeEnds->moveDest.x - routeEnds->moveSrc.x) * 8) / 9); + + int xDiff = xp - objPos->x; + int yDiff = yp - objPos->y; + int xDirection = (xDiff == 0) ? 0 : ((xDiff < 0) ? 1 : -1); + int yDirection = (yDiff == 0) ? 0 : ((yDiff < 0) ? 1 : -1); + xDiff = ABS(xDiff); + yDiff = ABS(yDiff); + int majorChange = MAX(xDiff, yDiff) / 2; + + int outX = objPos->x; + int outY = objPos->y; + + while (length-- > 0) { + if (xDiff < yDiff) { + outY += yDirection; + majorChange += xDiff; + if (majorChange > yDiff) { + majorChange -= yDiff; + outX += xDirection; + } + } else { + outX += xDirection; + majorChange += yDiff; + if (majorChange > xDiff) { + majorChange -= xDiff; + outY += yDirection; + } + } + } + + outPos->x = outX; + outPos->y = outY; + return outPos; +} + +int PlayerMover::checkMover(Common::Point &srcPos, const Common::Point &destPos) { + int regionIndex = 0; + Common::Point objPos = _sceneObject->_position; + uint32 regionBitList = _sceneObject->_regionBitList; + _sceneObject->_regionBitList = 0; + + _sceneObject->_position.x = srcPos.x; + _sceneObject->_position.y = srcPos.y; + _sceneObject->_mover = NULL; + + NpcMover *mover = new NpcMover(); + _sceneObject->addMover(mover, &destPos, NULL); + + // Handle automatic movement of the player until a walkable region is reached, + // or the end point of the movement is + do { + _sceneObject->_mover->dispatch(); + + // Scan walk regions for point + for (uint idx = 0; idx < _globals->_walkRegions._regionList.size(); ++idx) { + if (_globals->_walkRegions[idx].contains(_sceneObject->_position)) { + regionIndex = idx + 1; + srcPos = _sceneObject->_position; + break; + } + } + } while ((regionIndex == 0) && (_sceneObject->_mover) && !_vm->shouldQuit()); + + _sceneObject->_position = objPos; + _sceneObject->_regionBitList = regionBitList; + + if (_sceneObject->_mover) + _sceneObject->_mover->remove(); + + _sceneObject->_mover = this; + return regionIndex; +} + +void PlayerMover::checkMovement2(const Common::Point &srcPos, const Common::Point &destPos, int numSteps, Common::Point &ptOut) { + Common::Point objPos = _sceneObject->_position; + _sceneObject->_position = srcPos; + uint32 regionBitList = _sceneObject->_regionBitList; + _sceneObject->_position = srcPos; + _sceneObject->_mover = NULL; + + NpcMover *mover = new NpcMover(); + _sceneObject->addMover(mover, &destPos, NULL); + + while ((numSteps > 0) && ((_sceneObject->_position.x != destPos.x) || (_sceneObject->_position.y != destPos.y))) { + _sceneObject->_mover->dispatch(); + --numSteps; + } + + ptOut = _sceneObject->_position; + _sceneObject->_position = objPos; + _sceneObject->_regionBitList = regionBitList; + + if (_sceneObject->_mover) + _sceneObject->_mover->remove(); + + _sceneObject->_mover = this; +} + +int PlayerMover::proc1(int *routeList, int srcRegion, int destRegion, int &v) { + int tempList[REGION_LIST_SIZE + 1]; + v = 0; + for (int idx = 0; idx <= *routeList; ++idx) + tempList[idx] = routeList[idx]; + + if (*routeList == REGION_LIST_SIZE) + // Sequence too long + return 32000; + + int regionIndex; + for (regionIndex = 1; regionIndex <= *tempList; ++regionIndex) { + if (routeList[regionIndex] == srcRegion) + // Current path returns to original source region, so don't allow it + return 32000; + } + + WalkRegion &srcWalkRegion = _globals->_walkRegions[srcRegion]; + int distance; + if (!routeList[0]) { + // No route + distance = 0; + } else { + WalkRegion ®ion = _globals->_walkRegions[routeList[*routeList]]; + distance = findDistance(srcWalkRegion._pt, region._pt); + } + + tempList[++*tempList] = srcRegion; + int newIndex = *tempList; + + if (srcRegion == destRegion) { + v = 1; + for (int idx = newIndex; idx <= *tempList; ++idx) { + routeList[idx] = tempList[idx]; + ++*routeList; + } + return distance; + } else { + int foundIndex = 0; + int idx = 0; + int currDest; + while ((currDest = _globals->_walkRegions._idxList[srcWalkRegion._idxListIndex + idx]) != 0) { + if (currDest == destRegion) { + foundIndex = idx; + break; + } + + ++idx; + } + + int resultOffset = 31990; + while (((currDest = _globals->_walkRegions._idxList[srcWalkRegion._idxListIndex + foundIndex]) != 0) && (v == 0)) { + int newDistance = proc1(tempList, currDest, destRegion, v); + + if ((newDistance <= resultOffset) || v) { + routeList[0] = newIndex - 1; + + for (int i = newIndex; i <= tempList[0]; ++i) { + routeList[i] = tempList[i]; + ++routeList[0]; + } + + resultOffset = newDistance; + } + + tempList[0] = newIndex; + ++foundIndex; + } + + v = 0; + return resultOffset + distance; + } +} + +int PlayerMover::findDistance(const Common::Point &pt1, const Common::Point &pt2) { + int diff = ABS(pt1.x - pt2.x); + double xx = diff * diff; + diff = ABS(pt1.y - pt2.y); + double yy = diff * 8.0 / 7.0; + yy *= yy; + + return (int)sqrtf(xx + yy); +} + +bool PlayerMover::sub_F8E5(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3, + const Common::Point &pt4, Common::Point *ptOut) { + double diff1 = pt2.x - pt1.x; + double diff2 = pt2.y - pt1.y; + double diff3 = pt4.x - pt3.x; + double diff4 = pt4.y - pt3.y; + double var10 = 0.0, var8 = 0.0; + double var18 = 0.0, var20 = 0.0; + + if (diff1 != 0.0) { + var8 = diff2 / diff1; + var18 = pt1.y - (pt1.x * var8); + } + if (diff3 != 0.0) { + var10 = diff4 / diff3; + var20 = pt3.y - (pt3.x * var10); + } + + if (var8 == var10) + return false; + + double var48, var50; + if (diff1 == 0) { + if (diff3 == 0) + return false; + + var48 = pt1.x; + var50 = var10 * var48 + var20; + } else { + var48 = (diff3 == 0) ? pt3.x : (var20 - var18) / (var8 - var10); + var50 = var8 * var48 + var18; + } + + bool var52 = false, var56 = false, var54 = false, var58 = false; + Common::Point tempPt((int)(var48 + 0.5), (int)(var50 + 0.5)); + + if ((tempPt.x >= pt3.x) && (tempPt.x <= pt4.x)) + var56 = true; + else if ((tempPt.x >= pt4.x) && (tempPt.x <= pt3.x)) + var56 = true; + if (var56) { + if ((tempPt.y >= pt3.y) && (tempPt.y <= pt4.y)) + var58 = true; + else if ((tempPt.y >= pt4.y) && (tempPt.y <= pt3.y)) + var58 = true; + } + + if ((tempPt.x >= pt1.x) && (tempPt.x <= pt2.x)) + var52 = true; + else if ((tempPt.x >= pt2.x) && (tempPt.x <= pt1.x)) + var52 = true; + if (var52) { + if ((tempPt.y >= pt1.y) && (tempPt.y <= pt2.y)) + var54 = true; + else if ((tempPt.y >= pt2.y) && (tempPt.y <= pt1.y)) + var54 = true; + } + + if (var52 && var54 && var56 && var58) { + if (ptOut) + *ptOut = tempPt; + return true; + } + + return false; +} + +/*--------------------------------------------------------------------------*/ + +void PlayerMover2::synchronise(Serialiser &s) { + SYNC_POINTER(_destObject); + s.syncAsSint16LE(_field7E); + s.syncAsSint16LE(_minArea); +} + +void PlayerMover2::dispatch() { + int total = _sceneObject->getSpliceArea(_destObject); + + if (total <= _minArea) + endMove(); + else { + setDest(_destObject->_position); + ObjectMover::dispatch(); + } +} + +void PlayerMover2::startMove(SceneObject *sceneObj, va_list va) { + _sceneObject = sceneObj; + _field7E = va_arg(va, int); + _minArea = va_arg(va, int); + _destObject = va_arg(va, SceneObject *); + + PlayerMover::setDest(_destObject->_position); +} + +void PlayerMover2::endMove() { + _sceneObject->_regionIndex = 0x40; +} + +/*--------------------------------------------------------------------------*/ + +PaletteModifier::PaletteModifier() { + _scenePalette = NULL; + _action = NULL; +} + +/*--------------------------------------------------------------------------*/ + +PaletteRotation::PaletteRotation(): PaletteModifier() { + _disabled = false; + _delayFrames = 0; + _delayCtr = 0; + _frameNumber = _globals->_events.getFrameNumber(); +} + +void PaletteRotation::synchronise(Serialiser &s) { + PaletteModifier::synchronise(s); + + s.syncAsByte(_disabled); + s.syncAsSint32LE(_delayFrames); + s.syncAsSint32LE(_delayCtr); + s.syncAsUint32LE(_frameNumber); + s.syncAsSint32LE(_currIndex); + s.syncAsSint32LE(_start); + s.syncAsSint32LE(_end); + s.syncAsSint32LE(_rotationMode); + s.syncAsSint32LE(_duration); + for (int i = 0; i < 256; ++i) + s.syncAsUint32LE(_palette[i]); +} + +void PaletteRotation::signal() { + if (_delayCtr) { + uint32 frameNumber = _globals->_events.getFrameNumber(); + + if (frameNumber >= _frameNumber) { + _delayCtr = frameNumber - _frameNumber; + _frameNumber = frameNumber; + + if (_delayCtr < 0) + _delayCtr = 0; + } + } + + if (_delayCtr) + return; + _delayCtr = _delayFrames; + if (_disabled) + return; + + bool flag = true; + switch (_rotationMode) { + case -1: + if (--_currIndex < _start) { + flag = decDuration(); + if (flag) + _currIndex = _end - 1; + } + break; + case 1: + if (++_currIndex >= _end) { + flag = decDuration(); + if (flag) + _currIndex = _start; + } + break; + case 2: + if (++_currIndex >= _end) { + flag = decDuration(); + if (flag) { + _currIndex = _end - 2; + _rotationMode = 3; + } + } + break; + case 3: + if (--_currIndex < _start) { + flag = decDuration(); + if (flag) { + _currIndex = _start + 1; + _rotationMode = 2; + } + } + break; + } + + if (flag) { + int count2 = _currIndex - _start; + int count = _end - _currIndex; + g_system->getPaletteManager()->setPalette((const byte *)&_palette[_currIndex], _start, count); + + if (count2) { + g_system->getPaletteManager()->setPalette((const byte *)&_palette[_start], _start + count, count2); + } + } +} + +void PaletteRotation::remove() { + Action *action = _action; + g_system->getPaletteManager()->setPalette((const byte *)&_palette[_start], _start, _end - _start); + + if (_scenePalette->_listeners.contains(this)) + _scenePalette->_listeners.remove(this); + + delete this; + if (action) + action->signal(); +} + +void PaletteRotation::set(ScenePalette *palette, int start, int end, int rotationMode, int duration, Action *action) { + _duration = duration; + _disabled = false; + _action = action; + _scenePalette = palette; + + Common::copy(&palette->_palette[0], &palette->_palette[256], &_palette[0]); + + _start = start; + _end = end + 1; + _rotationMode = rotationMode; + + switch (_rotationMode) { + case -1: + case 3: + _currIndex = _end; + break; + default: + _currIndex = _start; + break; + } +} + +void PaletteRotation::setPalette(ScenePalette *palette, bool disabled) { + _scenePalette = palette; + _disabled = disabled; + _delayFrames = 100; +} + +bool PaletteRotation::decDuration() { + if (_duration) { + if (--_duration == 0) { + remove(); + return false; + } + } + return true; +} + +void PaletteRotation::setDelay(int amount) { + _delayFrames = _delayCtr = amount; +} + +/*--------------------------------------------------------------------------*/ + +void PaletteUnknown::synchronise(Serialiser &s) { + PaletteModifier::synchronise(s); + + s.syncAsSint16LE(_step); + s.syncAsSint16LE(_percent); + s.syncAsSint16LE(_field12); + s.syncAsSint16LE(_field14); + for (int i = 0; i < 256; ++i) + s.syncAsUint32LE(_palette[i]); +} + +void PaletteUnknown::signal() { + _percent -= _step; + if (_percent > 0) { + _scenePalette->fade((byte *)_palette, true /* 256 */, _percent); + } else { + remove(); + } +} + +void PaletteUnknown::remove() { + if (_scenePalette) { + for (int i = 0; i < 256; i++) + _scenePalette->_palette[i] = _palette[i]; + _scenePalette->refresh(); + if (_scenePalette->_listeners.contains(this)) + _scenePalette->_listeners.remove(this); + delete this; + } + + if (_action) + _action->signal(); +} + +/*--------------------------------------------------------------------------*/ + +ScenePalette::ScenePalette() { + // Set a default gradiant range + for (int idx = 0; idx < 256; ++idx) + _palette[idx] = idx | (idx << 8) | (idx << 16); + + _field412 = 0; +} + +ScenePalette::ScenePalette(int paletteNum) { + loadPalette(paletteNum); +} + +bool ScenePalette::loadPalette(int paletteNum) { + byte *palData = _vm->_dataManager->getResource(RES_PALETTE, paletteNum, 0, true); + if (!palData) + return false; + + int palStart = READ_LE_UINT16(palData); + int palSize = READ_LE_UINT16(palData + 2); + assert(palSize <= 256); + + uint32 *destP = &_palette[palStart]; + byte *srcP = palData + 6; + + + for (int i = 0; i < palSize; ++i, srcP += 3, ++destP) + *destP = *srcP | (*(srcP + 1) << 8) | (*(srcP + 2) << 16); + + DEALLOCATE(palData); + return true; +} + +void ScenePalette::refresh() { + // Set indexes for standard colours to closest colour in the palette + _colours.background = indexOf(255, 255, 255); // White background + _colours.foreground = indexOf(0, 0, 0); // Black foreground + _redColour = indexOf(180, 0, 0); // Red-ish + _greenColour = indexOf(0, 180, 0); // Green-ish + _blueColour = indexOf(0, 0, 180); // Blue-ish + _aquaColour = indexOf(0, 180, 180); // Aqua + _purpleColour = indexOf(180, 0, 180); // Purple + _limeColour = indexOf(180, 180, 0); // Lime + + // Refresh the palette + g_system->getPaletteManager()->setPalette((const byte *)&_palette[0], 0, 256); +} + +/** + * Loads a section of the palette into the game palette + */ +void ScenePalette::setPalette(int index, int count) { + g_system->getPaletteManager()->setPalette((const byte *)&_palette[index], index, count); +} + +/** + * Returns the palette index with the closest matching colour to that specified + * @param r R component + * @param g G component + * @param b B component + * @param threshold Closeness threshold. + * @remarks A threshold may be provided to specify how close the matching colour must be + */ +uint8 ScenePalette::indexOf(uint r, uint g, uint b, int threshold) { + int palIndex = -1; + + for (int i = 0; i < 256; ++i) { + int ir = _palette[i] & 0xff; + int ig = (_palette[i] >> 8) & 0xff; + int ib = (_palette[i] >> 16) & 0xff; + int rDiff = abs(ir - (int)r); + int gDiff = abs(ig - (int)g); + int bDiff = abs(ib - (int)b); + + int idxThreshold = rDiff * rDiff + gDiff * gDiff + bDiff * bDiff; + if (idxThreshold <= threshold) { + threshold = idxThreshold; + palIndex = i; + } + } + + return palIndex; +} + +/** + * Loads the specified range of the palette with the current system palette + * @param start Start index + * @param count Number of palette entries + */ +void ScenePalette::getPalette(int start, int count) { + g_system->getPaletteManager()->grabPalette((byte *)&_palette[start], start, count); +} + +void ScenePalette::signalListeners() { + for (List<PaletteModifier *>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) { + (*i)->signal(); + } +} + +void ScenePalette::clearListeners() { + List<PaletteModifier *>::iterator i = _listeners.begin(); + while (i != _listeners.end()) { + PaletteModifier *obj = *i; + ++i; + obj->remove(); + } +} + +void ScenePalette::fade(const byte *adjustData, bool fullAdjust, int percent) { + uint32 tempPalette[256]; + + // Ensure the percent adjustment is within 0 - 100% + percent = CLIP(percent, 0, 100); + + for (int palIndex = 0; palIndex < 256; ++palIndex) { + const byte *srcP = (const byte *)&_palette[palIndex]; + byte *destP = (byte *)&tempPalette[palIndex]; + + for (int rgbIndex = 0; rgbIndex < 3; ++rgbIndex, ++srcP, ++destP) { + *destP = *srcP - ((*srcP - adjustData[rgbIndex]) * (100 - percent)) / 100; + } + + if (fullAdjust) + adjustData += 3; + } + + // Set the altered pale4tte + g_system->getPaletteManager()->setPalette((const byte *)&tempPalette[0], 0, 256); + g_system->updateScreen(); +} + +PaletteRotation *ScenePalette::addRotation(int start, int end, int rotationMode, int duration, Action *action) { + PaletteRotation *obj = new PaletteRotation(); + + if ((rotationMode == 2) || (rotationMode == 3)) + duration <<= 1; + + obj->set(this, start, end, rotationMode, duration, action); + _listeners.push_back(obj); + return obj; +} + +PaletteUnknown *ScenePalette::addUnkPal(uint32 *arrBufferRGB, int unkNumb, bool disabled, Action *action) { + PaletteUnknown *paletteUnk = new PaletteUnknown(); + paletteUnk->_action = action; + for (int i = 0; i < 256; i++) { + if (unkNumb <= 1) + paletteUnk->_palette[i] = arrBufferRGB[i]; + else + paletteUnk->_palette[i] = arrBufferRGB[0]; + } +// PaletteRotation::setPalette(this, disabled); + _globals->_scenePalette._listeners.push_back(paletteUnk); + return paletteUnk; +} + + +void ScenePalette::changeBackground(const Rect &bounds, FadeMode fadeMode) { + ScenePalette tempPalette; + if (_globals->_sceneManager._hasPalette) { + if ((fadeMode == FADEMODE_GRADUAL) || (fadeMode == FADEMODE_IMMEDIATE)) { + // Fade out any active palette + tempPalette.getPalette(); + uint32 adjustData = 0; + + for (int percent = 100; percent >= 0; percent -= 5) { + if (fadeMode == FADEMODE_IMMEDIATE) + percent = 0; + tempPalette.fade((byte *)&adjustData, false, percent); + g_system->delayMillis(10); + } + } else { + _globals->_scenePalette.refresh(); + _globals->_sceneManager._hasPalette = false; + } + } + + _globals->_screenSurface.copyFrom(_globals->_sceneManager._scene->_backSurface, + bounds, Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), NULL); + tempPalette._listeners.clear2(); +} + +void ScenePalette::synchronise(Serialiser &s) { + for (int i = 0; i < 256; ++i) + s.syncAsUint32LE(_palette[i]); + s.syncAsSint32LE(_colours.foreground); + s.syncAsSint32LE(_colours.background); + + s.syncAsSint32LE(_field412); + s.syncAsByte(_redColour); + s.syncAsByte(_greenColour); + s.syncAsByte(_blueColour); + s.syncAsByte(_aquaColour); + s.syncAsByte(_purpleColour); + s.syncAsByte(_limeColour); +} + +/*--------------------------------------------------------------------------*/ + +void SceneItem::synchronise(Serialiser &s) { + EventHandler::synchronise(s); + + _bounds.synchronise(s); + s.syncString(_msg); + s.syncAsSint32LE(_fieldE); + s.syncAsSint32LE(_field10); + s.syncAsSint16LE(_position.x); s.syncAsSint32LE(_position.y); + s.syncAsSint16LE(_yDiff); + s.syncAsSint32LE(_sceneRegionId); +} + +void SceneItem::remove() { + _globals->_sceneItems.remove(this); +} + +void SceneItem::doAction(int action) { + const char *msg = NULL; + + switch ((int)action) { + case CURSOR_LOOK: + msg = LOOK_SCENE_HOTSPOT; + break; + case CURSOR_USE: + msg = USE_SCENE_HOTSPOT; + break; + case CURSOR_TALK: + msg = TALK_SCENE_HOTSPOT; + break; + case 0x1000: + msg = SPECIAL_SCENE_HOTSPOT; + break; + default: + msg = DEFAULT_SCENE_HOTSPOT; + break; + } + + GUIErrorMessage(msg); +} + +bool SceneItem::contains(const Common::Point &pt) { + const Rect &sceneBounds = _globals->_sceneManager._scene->_sceneBounds; + + if (_sceneRegionId == 0) + return _bounds.contains(pt.x + sceneBounds.left, pt.y + sceneBounds.top); + else + return _globals->_sceneRegions.indexOf(Common::Point(pt.x + sceneBounds.left, + pt.y + sceneBounds.top)) == _sceneRegionId; +} + +void SceneItem::display(int resNum, int lineNum, ...) { + Common::String msg = !resNum ? Common::String() : _vm->_dataManager->getMessage(resNum, lineNum); + + if (_globals->_sceneObjects->contains(&_globals->_sceneText)) { + _globals->_sceneText.remove(); + _globals->_sceneObjects->draw(); + } + + GfxFontBackup font; + Common::Point pos(160, 100); + Rect textRect; + int maxWidth = 120; + bool keepOnscreen = false; + bool centreText = true; + + if (resNum) { + va_list va; + va_start(va, lineNum); + + int mode; + do { + // Get next instruction + mode = va_arg(va, int); + + switch (mode) { + case SET_WIDTH: + // Set width + maxWidth = va_arg(va, int); + _globals->_sceneText._width = maxWidth; + break; + case SET_X: + // Set the X Position + pos.x = va_arg(va, int); + break; + case SET_Y: + // Set the Y Position + pos.y = va_arg(va, int); + break; + case SET_FONT: + // Set the font number + _globals->_sceneText._fontNumber = va_arg(va, int); + _globals->gfxManager()._font.setFontNumber(_globals->_sceneText._fontNumber); + break; + case SET_BG_COLOUR: { + // Set the background colour + int bgColour = va_arg(va, int); + _globals->gfxManager()._font._colours.background = bgColour; + if (!bgColour) + _globals->gfxManager().setFillFlag(false); + break; + } + case SET_FG_COLOUR: + // Set the foreground colour + _globals->_sceneText._colour1 = va_arg(va, int); + _globals->gfxManager()._font._colours.foreground = _globals->_sceneText._colour1; + break; + case SET_KEEP_ONSCREEN: + // Suppresses immediate display + keepOnscreen = va_arg(va, int) != 0; + break; + case SET_EXT_BGCOLOUR: { + // Set secondary bg colour + int v = va_arg(va, int); + _globals->_sceneText._colour2 = v; + _globals->gfxManager()._font._colours2.background = v; + break; + } + case SET_EXT_FGCOLOUR: { + // Set secondary fg colour + int v = va_arg(va, int); + _globals->_sceneText._colour3 = v; + _globals->gfxManager()._font._colours.foreground = v; + break; + } + case SET_POS_MODE: + // Set whether a custom x/y is used + centreText = va_arg(va, int) != 0; + break; + case SET_TEXT_MODE: + // Set the text mode + _globals->_sceneText._textMode = (TextAlign)va_arg(va, int); + break; + default: + break; + } + } while (mode != LIST_END); + + va_end(va); + } + + if (resNum) { + // Get required bounding size + _globals->gfxManager().getStringBounds(msg.c_str(), textRect, maxWidth); + textRect.centre(pos.x, pos.y); + + textRect.contain(_globals->gfxManager()._bounds); + if (centreText) { + _globals->_sceneText._colour1 = _globals->_sceneText._colour2; + _globals->_sceneText._colour2 = 0; + _globals->_sceneText._colour3 = 0; + } + + _globals->_sceneText.setup(msg); + if (centreText) { + _globals->_sceneText.setPosition(Common::Point( + _globals->_sceneManager._scene->_sceneBounds.left + textRect.left, + _globals->_sceneManager._scene->_sceneBounds.top + textRect.top), 0); + } else { + _globals->_sceneText.setPosition(pos, 0); + } + + _globals->_sceneText.setPriority2(255); + _globals->_sceneObjects->draw(); + } + + // Unless the flag is set to keep the message on-screen, show it until a mouse or keypress, then remove it + if (!keepOnscreen && !msg.empty()) { + Event event; + + // Keep event on-screen until a mouse or keypress + while (!_vm->getEventManager()->shouldQuit() && !_globals->_events.getEvent(event, + EVENT_BUTTON_DOWN | EVENT_KEYPRESS)) { + g_system->updateScreen(); + g_system->delayMillis(10); + } + + _globals->_sceneText.remove(); + } +} + +/*--------------------------------------------------------------------------*/ + +void SceneHotspot::doAction(int action) { + switch ((int)action) { + case CURSOR_LOOK: + display(1, 0, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_USE: + display(1, 5, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_TALK: + display(1, 15, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_WALK: + break; + default: + display(2, action, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void NamedHotspot::doAction(int action) { + switch (action) { + case CURSOR_WALK: + // Nothing + break; + case CURSOR_LOOK: + if (_lookLineNum == -1) + SceneHotspot::doAction(action); + else + SceneItem::display(_resnum, _lookLineNum, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_USE: + if (_useLineNum == -1) + SceneHotspot::doAction(action); + else + SceneItem::display(_resnum, _useLineNum, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void NamedHotspot::setup(const int ys, const int xe, const int ye, const int xs, const int resnum, const int lookLineNum, const int useLineNum) { + setBounds(ys, xe, ye, xs); + _resnum = resnum; + _lookLineNum = lookLineNum; + _useLineNum = useLineNum; + _globals->_sceneItems.addItems(this, NULL); +} + +/*--------------------------------------------------------------------------*/ + +void SceneObjectWrapper::setSceneObject(SceneObject *so) { + _sceneObject = so; + so->_strip = 1; + so->_flags |= OBJFLAG_PANES; +} + +void SceneObjectWrapper::synchronise(Serialiser &s) { + EventHandler::synchronise(s); + SYNC_POINTER(_sceneObject); +} + +void SceneObjectWrapper::remove() { + delete this; +} + +void SceneObjectWrapper::dispatch() { + _visageImages.setVisage(_sceneObject->_visage); + int frameCount = _visageImages.getFrameCount(); + int angle = _sceneObject->_angle; + int strip = _sceneObject->_strip; + + if (frameCount == 4) { + if ((angle > 314) || (angle < 45)) + strip = 4; + if ((angle > 44) && (angle < 135)) + strip = 1; + if ((angle >= 135) && (angle < 225)) + strip = 3; + if ((angle >= 225) && (angle < 315)) + strip = 2; + } else if (frameCount == 8) { + if ((angle > 330) || (angle < 30)) + strip = 4; + if ((angle >= 30) && (angle < 70)) + strip = 7; + if ((angle >= 70) && (angle < 110)) + strip = 1; + if ((angle >= 110) && (angle < 150)) + strip = 5; + if ((angle >= 150) && (angle < 210)) + strip = 3; + if ((angle >= 210) && (angle < 250)) + strip = 6; + if ((angle >= 250) && (angle < 290)) + strip = 2; + if ((angle >= 290) && (angle < 331)) + strip = 8; + } + + if (strip > frameCount) + strip = frameCount; + + _sceneObject->setStrip(strip); +} + +/*--------------------------------------------------------------------------*/ + +SceneObject::SceneObject(): SceneHotspot() { + _endAction = NULL; + _mover = NULL; + _objectWrapper = NULL; + _flags = 0; + _walkStartFrame = 0; + _animateMode = ANIM_MODE_NONE; + _updateStartFrame = 0; + _moveDiff.x = 5; + _moveDiff.y = 3; + _numFrames = 10; + _numFrames = 10; + _field7A = 10; + _regionBitList = 0; + _sceneRegionId = 0; + _percent = 100; + _flags |= OBJFLAG_PANES; + + _frameChange = 0; +} + +SceneObject::SceneObject(const SceneObject &so) { + *this = so; + if (_objectWrapper) + // Create a fresh object wrapper for this object + _objectWrapper = new SceneObjectWrapper(); +} + +SceneObject::~SceneObject() { + delete _mover; + delete _objectWrapper; +} + +int SceneObject::getNewFrame() { + int frameNum = _frame + _frameChange; + + if (_frameChange > 0) { + if (frameNum > getFrameCount()) { + frameNum = 1; + if (_animateMode == ANIM_MODE_1) + ++frameNum; + } + } else if (frameNum < 1) { + frameNum = getFrameCount(); + } + + return frameNum; +} + +int SceneObject::getFrameCount() { + _visageImages.setVisage(_visage, _strip); + return _visageImages.getFrameCount(); +} + +void SceneObject::animEnded() { + _animateMode = ANIM_MODE_NONE; + if (_endAction) + _endAction->signal(); +} + +int SceneObject::changeFrame() { + int frameNum = _frame; + uint32 mouseCtr = _globals->_events.getFrameNumber(); + + if ((_updateStartFrame <= mouseCtr) || (_animateMode == ANIM_MODE_1)) { + if (_numFrames > 0) { + int v = 60 / _numFrames; + _updateStartFrame = mouseCtr + v; + + frameNum = getNewFrame(); + } + } + + return frameNum; +} + +void SceneObject::setPosition(const Common::Point &p, int yDiff) { + _position = p; + _yDiff = yDiff; + _flags |= OBJFLAG_PANES; +} + +void SceneObject::setZoom(int percent) { + assert((percent >= -1) && (percent < 999)); + if (percent != _percent) { + _percent = percent; + _flags |= OBJFLAG_PANES; + } +} + +void SceneObject::updateZoom() { + changeZoom(_percent); +} + +void SceneObject::changeZoom(int percent) { + if (percent == -1) + _flags &= ~OBJFLAG_ZOOMED; + else { + _flags |= OBJFLAG_ZOOMED; + setZoom(percent); + } +} + +void SceneObject::setStrip(int stripNum) { + if (stripNum != _strip) { + _strip = stripNum; + _flags |= OBJFLAG_PANES; + } +} + +void SceneObject::setStrip2(int stripNum) { + if (stripNum == -1) + _flags &= ~OBJFLAG_SUPPRESS_DISPATCH; + else { + _flags |= OBJFLAG_SUPPRESS_DISPATCH; + setStrip(stripNum); + } +} + +void SceneObject::setFrame(int frameNum) { + if (frameNum != _frame) { + _frame = frameNum; + _flags |= OBJFLAG_PANES; + } +} + +void SceneObject::setFrame2(int frameNum) { + if (frameNum != -1) { + _flags |= OBJFLAG_NO_UPDATES; + setFrame(frameNum); + } else { + _flags &= ~OBJFLAG_NO_UPDATES; + } +} + +void SceneObject::setPriority(int priority) { + if (priority != _priority) { + _priority = priority; + _flags |= OBJFLAG_PANES; + } +} + +void SceneObject::setPriority2(int priority) { + if (priority == -1) { + _flags &= ~OBJFLAG_FIXED_PRIORITY; + } else { + _flags |= OBJFLAG_FIXED_PRIORITY; + setPriority(priority); + } +} + +void SceneObject::setVisage(int visage) { + if (visage != _visage) { + _visage = visage; + _flags |= OBJFLAG_PANES; + } +} + +void SceneObject::setObjectWrapper(SceneObjectWrapper *objWrapper) { + if (_objectWrapper) + _objectWrapper->remove(); + _objectWrapper = objWrapper; + if (objWrapper) + objWrapper->setSceneObject(this); +} + +void SceneObject::addMover(ObjectMover *mover, ...) { + if (_mover) + _mover->remove(); + _mover = mover; + + if (mover) { + // Set up the assigned mover + _walkStartFrame = _globals->_events.getFrameNumber(); + if (_field7A != 0) + _walkStartFrame = 60 / _field7A; + + // Signal the mover that movement is beginning + va_list va; + va_start(va, mover); + mover->startMove(this, va); + va_end(va); + } +} + +void SceneObject::getHorizBounds() { + Rect tempRect; + + GfxSurface frame = getFrame(); + tempRect.resize(frame, _position.x, _position.y - _yDiff, _percent); + + _xs = tempRect.left; + _xe = tempRect.right; +} + +int SceneObject::getRegionIndex() { + return _globals->_sceneRegions.indexOf(_position); +} + +int SceneObject::checkRegion(const Common::Point &pt) { + Rect tempRect; + int regionIndex = 0; + + // Temporarily change the position + Common::Point savedPos = _position; + _position = pt; + + int regIndex = _globals->_sceneRegions.indexOf(pt); + if (_regionBitList & (1 << regIndex)) + regionIndex = regIndex; + + // Restore position + _position = savedPos; + + // Get the object's frame bounds + GfxSurface frame = getFrame(); + tempRect.resize(frame, _position.x, _position.y - _yDiff, _percent); + + int yPos, newY; + if ((_position.y - _yDiff) <= (pt.y - _yDiff)) { + yPos = _position.y - _yDiff; + newY = pt.y; + } else { + yPos = pt.y - _yDiff; + newY = _position.y; + } + newY -= _yDiff; + + List<SceneObject *>::iterator i; + for (i = _globals->_sceneObjects->begin(); (regionIndex == 0) && (i != _globals->_sceneObjects->end()); ++i) { + if ((*i) && ((*i)->_flags & OBJFLAG_CHECK_REGION)) { + int objYDiff = (*i)->_position.y - _yDiff; + if ((objYDiff >= yPos) && (objYDiff <= newY) && + ((*i)->_xs < tempRect.right) && ((*i)->_xe > tempRect.left)) { + // Found index + regionIndex = -1; //****DEBUG*** = *i; + break; + } + } + } + + return regionIndex; +} + +void SceneObject::animate(AnimateMode animMode, ...) { + _animateMode = animMode; + _updateStartFrame = _globals->_events.getFrameNumber(); + if (_numFrames) + _updateStartFrame += 60 / _numFrames; + + va_list va; + va_start(va, animMode); + + switch (_animateMode) { + case ANIM_MODE_NONE: + _endAction = NULL; + break; + + case ANIM_MODE_1: + _frameChange = 1; + _field2E = _position; + _endAction = 0; + break; + + case ANIM_MODE_2: + _frameChange = 1; + _endAction = NULL; + break; + + case ANIM_MODE_3: + _frameChange = -1; + _endAction = NULL; + break; + + case ANIM_MODE_4: + _endFrame = va_arg(va, int); + _frameChange = va_arg(va, int); + _endAction = va_arg(va, Action *); + if (_endFrame == _frame) + setFrame(getNewFrame()); + break; + + case ANIM_MODE_5: + _frameChange = 1; + _endFrame = getFrameCount(); + _endAction = va_arg(va, Action *); + if (_endFrame == _frame) + setFrame(getNewFrame()); + break; + + case ANIM_MODE_6: + _frameChange = -1; + _endAction = va_arg(va, Action *); + _endFrame = 1; + if (_frame == _endFrame) + setFrame(getNewFrame()); + break; + + case ANIM_MODE_7: + _endFrame = va_arg(va, int); + _endAction = va_arg(va, Action *); + _frameChange = 1; + break; + + case ANIM_MODE_8: + _field68 = va_arg(va, int); + _endAction = va_arg(va, Action *); + _frameChange = 1; + _endFrame = getFrameCount(); + if (_frame == _endFrame) + setFrame(getNewFrame()); + break; + } +} + +SceneObject *SceneObject::clone() const { + SceneObject *obj = new SceneObject(*this); + return obj; +} + +void SceneObject::checkAngle(const SceneObject *obj) { + _angle = GfxManager::getAngle(_position, obj->_position); + + if (_objectWrapper) + _objectWrapper->dispatch(); +} + +void SceneObject::hide() { + _flags |= OBJFLAG_HIDE; + if (_flags & OBJFLAG_HIDING) + _flags |= OBJFLAG_PANES; +} + +void SceneObject::show() { + if (_flags & OBJFLAG_HIDE) { + _flags &= ~OBJFLAG_HIDE; + _flags |= OBJFLAG_PANES; + } +} + +int SceneObject::getSpliceArea(const SceneObject *obj) { + int xd = ABS(_position.x - obj->_position.x); + int yd = ABS(_position.y - obj->_position.y); + + return (xd * xd + yd) / 2; +} + +void SceneObject::synchronise(Serialiser &s) { + SceneHotspot::synchronise(s); + + s.syncAsUint32LE(_updateStartFrame); + s.syncAsUint32LE(_walkStartFrame); + s.syncAsSint16LE(_field2E.x); s.syncAsSint16LE(_field2E.y); + s.syncAsSint16LE(_percent); + s.syncAsSint16LE(_priority); + s.syncAsSint16LE(_angle); + s.syncAsUint32LE(_flags); + s.syncAsSint16LE(_xs); + s.syncAsSint16LE(_xe); + _paneRects[0].synchronise(s); + _paneRects[1].synchronise(s); + s.syncAsSint32LE(_visage); + SYNC_POINTER(_objectWrapper); + s.syncAsSint32LE(_strip); + SYNC_ENUM(_animateMode, AnimateMode); + s.syncAsSint32LE(_frame); + s.syncAsSint32LE(_endFrame); + s.syncAsSint32LE(_field68); + s.syncAsSint32LE(_frameChange); + s.syncAsSint32LE(_numFrames); + s.syncAsSint32LE(_regionIndex); + SYNC_POINTER(_mover); + s.syncAsSint16LE(_moveDiff.x); s.syncAsSint16LE(_moveDiff.y); + s.syncAsSint32LE(_field7A); + SYNC_POINTER(_endAction); + s.syncAsUint32LE(_regionBitList); +} + +void SceneObject::postInit(SceneObjectList *OwnerList) { + if (!OwnerList) + OwnerList = _globals->_sceneObjects; + + if (!OwnerList->contains(this)) { + _percent = 100; + _priority = 255; + _flags = 4; + _visage = 0; + _strip = 1; + _frame = 1; + _objectWrapper = NULL; + _animateMode = ANIM_MODE_NONE; + _endAction = 0; + _mover = NULL; + _yDiff = 0; + _moveDiff.x = 5; + _moveDiff.y = 3; + _field7A = 10; + _regionIndex = 0x40; + _numFrames = 10; + _regionBitList = 0; + + OwnerList->push_back(this); + _flags |= OBJFLAG_PANES; + } +} + +void SceneObject::remove() { + SceneItem::remove(); + if (_globals->_sceneObjects->contains(this)) + // For objects in the object list, flag the object for removal in the next drawing, so that + // the drawing code has a chance to restore the area previously covered by the object + _flags |= OBJFLAG_PANES | OBJFLAG_REMOVE | OBJFLAG_HIDE; + else + // Not in the list, so immediately remove the object + removeObject(); +} + +void SceneObject::dispatch() { + uint32 currTime = _globals->_events.getFrameNumber(); + if (_action) + _action->dispatch(); + + if (_mover && (_walkStartFrame <= currTime)) { + if (_field7A) { + int frameInc = 60 / _field7A; + _walkStartFrame = currTime + frameInc; + } + _mover->dispatch(); + } + + if (!(_flags & OBJFLAG_NO_UPDATES)) { + switch (_animateMode) { + case ANIM_MODE_1: + if (isNoMover()) + setFrame(1); + else if ((_field2E.x != _position.x) || (_field2E.y != _position.y)) { + setFrame(changeFrame()); + _field2E = _position; + + } + break; + + case ANIM_MODE_2: + case ANIM_MODE_3: + setFrame(changeFrame()); + + break; + case ANIM_MODE_4: + case ANIM_MODE_5: + case ANIM_MODE_6: + if (_frame == _endFrame) + animEnded(); + else + setFrame(changeFrame()); + break; + + case ANIM_MODE_7: + if (changeFrame() != _frame) { + // Pick a new random frame + int frameNum = 0; + do { + int count = getFrameCount(); + frameNum = _globals->_randomSource.getRandomNumber(count - 1); + } while (frameNum == _frame); + + setFrame(frameNum); + if (_endFrame) { + if (--_endFrame == 0) + animEnded(); + } + } + break; + + case ANIM_MODE_8: + if (_frame == _endFrame) { + if (_frameChange != -1) { + _frameChange = -1; + _endFrame = 1; + + setFrame(changeFrame()); + } else if (!_field68 || (--_field68 > 0)) { + _frameChange = 1; + _endFrame = getFrameCount(); + + setFrame(changeFrame()); + } else { + animEnded(); + } + } else { + setFrame(changeFrame()); + } + + break; + + default: + break; + } + } + + // Handle updating the zoom and/or priority + if (!(_flags & OBJFLAG_ZOOMED)) { + int yp = CLIP((int)_position.y, 0, 255); + setZoom(_globals->_sceneManager._scene->_zoomPercents[yp]); + } + if (!(_flags & OBJFLAG_FIXED_PRIORITY)) { + setPriority(_position.y); + } +} + +void SceneObject::calcAngle(const Common::Point &pt) { + int newAngle = GfxManager::getAngle(_position, pt); + if (newAngle != -1) + _angle = newAngle; +} + +void SceneObject::removeObject() { + if (_globals->_sceneItems.contains(this)) + _globals->_sceneItems.remove(this); + + if (_globals->_sceneObjects->contains(this)) + _globals->_sceneObjects->remove(this); + + if (_visage) { + _vm->_memoryManager.deallocate(_visage); + _visage = 0; + } + + if (_objectWrapper) { + _objectWrapper->remove(); + _objectWrapper = NULL; + } + if (_mover) { + _mover->remove(); + _mover = NULL; + } + if (_flags & 0x800) + destroy(); +} + +GfxSurface SceneObject::getFrame() { + _visageImages.setVisage(_visage, _strip); + return _visageImages.getFrame(_frame); +} + +void SceneObject::reposition() { + GfxSurface frame = getFrame(); + _bounds.resize(frame, _position.x, _position.y - _yDiff, _percent); + _xs = _bounds.left; + _xe = _bounds.right; +} + +/** + * Draws an object into the scene + */ +void SceneObject::draw() { + Rect destRect = _bounds; + destRect.translate(-_globals->_sceneManager._scene->_sceneBounds.left, + -_globals->_sceneManager._scene->_sceneBounds.top); + Region *priorityRegion = _globals->_sceneManager._scene->_priorities.find(_priority); + GfxSurface frame = getFrame(); + _globals->gfxManager().copyFrom(frame, destRect, priorityRegion); +} + +/** + * Refreshes the background around the area of a scene object prior to it's being redrawn, + * in case it is moving + */ +void SceneObject::updateScreen() { + Rect srcRect = _paneRects[CURRENT_PANENUM]; + const Rect &sceneBounds = _globals->_sceneManager._scene->_sceneBounds; + srcRect.left = (srcRect.left / 4) * 4; + srcRect.right = ((srcRect.right + 3) / 4) * 4; + srcRect.clip(_globals->_sceneManager._scene->_sceneBounds); + + if (srcRect.isValidRect()) { + Rect destRect = srcRect; + destRect.translate(-sceneBounds.left, -sceneBounds.top); + srcRect.translate(-_globals->_sceneOffset.x, -_globals->_sceneOffset.y); + + _globals->_screenSurface.copyFrom(_globals->_sceneManager._scene->_backSurface, srcRect, destRect); + } +} + +void SceneObject::setup(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority) { + postInit(); + setVisage(visage); + setStrip(stripFrameNum); + setFrame(frameNum); + setPosition(Common::Point(posX, posY), 0); + setPriority2(priority); +} + +/*--------------------------------------------------------------------------*/ + +void SceneObjectList::draw() { + Common::Array<SceneObject *> objList; + int paneNum = 0; + int xAmount = 0, yAmount = 0; + + if (_objList.size() == 0) { + // Alternate draw mode + + if (_globals->_paneRefreshFlag[paneNum] == 1) { + // Load the background + _globals->_sceneManager._scene->refreshBackground(0, 0); + + Rect tempRect = _globals->_sceneManager._scene->_sceneBounds; + tempRect.translate(-_globals->_sceneOffset.x, -_globals->_sceneOffset.y); + ScenePalette::changeBackground(tempRect, _globals->_sceneManager._fadeMode); + } else { + _globals->_paneRegions[CURRENT_PANENUM].draw(); + } + + _globals->_paneRegions[CURRENT_PANENUM].setRect(0, 0, 0, 0); + _globals->_sceneManager.fadeInIfNecessary(); + + } else { + // If there is a scroll follower, check whether it has moved off-screen + if (_globals->_scrollFollower) { + const Rect &scrollerRect = _globals->_sceneManager._scrollerRect; + Common::Point objPos( + _globals->_scrollFollower->_position.x - _globals->_sceneManager._scene->_sceneBounds.left, + _globals->_scrollFollower->_position.y - _globals->_sceneManager._scene->_sceneBounds.top); + int loadCount = 0; + + if (objPos.x >= scrollerRect.right) { + xAmount = 8; + loadCount = 20; + } + if (objPos.x < scrollerRect.left) { + xAmount = -8; + loadCount = 20; + } + if (objPos.y >= scrollerRect.bottom) { + yAmount = 2; + loadCount = 25; + } + if (objPos.y < scrollerRect.top) { + yAmount = -2; + loadCount = 25; + } + + if (loadCount > 0) + _globals->_sceneManager.setBgOffset(Common::Point(xAmount, yAmount), loadCount); + } + + if (_globals->_sceneManager._sceneLoadCount > 0) { + --_globals->_sceneManager._sceneLoadCount; + _globals->_sceneManager._scene->loadBackground(_globals->_sceneManager._sceneBgOffset.x, + _globals->_sceneManager._sceneBgOffset.y); + } + + // Set up the flag mask + uint32 flagMask = (paneNum == 0) ? OBJFLAG_PANE_0 : OBJFLAG_PANE_1; + + // Initial loop to set up object list and update object position, priority, and flags + for (List<SceneObject *>::iterator i = _globals->_sceneObjects->begin(); + i != _globals->_sceneObjects->end(); ++i) { + SceneObject *obj = *i; + objList.push_back(obj); + + if (!(obj->_flags & OBJFLAG_HIDE)) + obj->_flags &= ~OBJFLAG_HIDING; + + // Reposition the bounds of the object to match the desired position + obj->reposition(); + + // Handle updating object priority + if (!(obj->_flags & OBJFLAG_FIXED_PRIORITY)) { + obj->_priority = MIN((int)obj->_position.y - 1, + (int)_globals->_sceneManager._scene->_backgroundBounds.bottom); + } + + if ((_globals->_paneRefreshFlag[paneNum] != 0) || !_globals->_paneRegions[paneNum].empty()) { + obj->_flags |= flagMask; + } + } + + // Check for any intersections, and then sort the object list by priority + checkIntersection(objList, objList.size(), CURRENT_PANENUM); + sortList(objList); + + if (_globals->_paneRefreshFlag[paneNum] == 1) { + // Load the background + _globals->_sceneManager._scene->refreshBackground(0, 0); + } + + _globals->_sceneManager._scene->_sceneBounds.left &= ~3; + _globals->_sceneManager._scene->_sceneBounds.right &= ~3; + _globals->_sceneOffset.x &= ~3; + + if (_globals->_paneRefreshFlag[paneNum] != 0) { + // Change the background + Rect tempRect = _globals->_sceneManager._scene->_sceneBounds; + tempRect.translate(-_globals->_sceneOffset.x, -_globals->_sceneOffset.y); + ScenePalette::changeBackground(tempRect, _globals->_sceneManager._fadeMode); + } else { + for (uint objIndex = 0; objIndex < objList.size(); ++objIndex) { + SceneObject *obj = objList[objIndex]; + + if ((obj->_flags & flagMask) && obj->_paneRects[paneNum].isValidRect()) + obj->updateScreen(); + } + + _globals->_paneRegions[paneNum].draw(); + } + + _globals->_paneRegions[paneNum].setRect(0, 0, 0, 0); +redraw: + // Main draw loop + for (uint objIndex = 0; objIndex < objList.size(); ++objIndex) { + SceneObject *obj = objList[objIndex]; + + if ((obj->_flags & flagMask) && !(obj->_flags & OBJFLAG_HIDE)) { + obj->_paneRects[paneNum] = obj->_bounds; + obj->draw(); + } + } + + // Update the palette + _globals->_sceneManager.fadeInIfNecessary(); + _globals->_sceneManager._loadMode = 0; + _globals->_paneRefreshFlag[paneNum] = 0; + + // Loop through the object list, removing any objects and refreshing the screen as necessary + for (uint objIndex = 0; objIndex < objList.size(); ++objIndex) { + SceneObject *obj = objList[objIndex]; + + if (obj->_flags & OBJFLAG_HIDE) + obj->_flags |= OBJFLAG_HIDING; + obj->_flags &= ~flagMask; + if (obj->_flags & OBJFLAG_REMOVE) { + obj->_flags |= OBJFLAG_PANES; + + checkIntersection(objList, objIndex, CURRENT_PANENUM); + + obj->updateScreen(); + obj->removeObject(); + + // FIXME: Currently, removing objects causes screen flickers when the removed object intersects + // another drawn object, since the background is briefly redrawn over the object. For now, I'm + // using a forced jump back to redraw objects. In the long term, I should figure out how the + // original game does this properly + objList.remove_at(objIndex); + goto redraw; + } + } + } +} + +void SceneObjectList::checkIntersection(Common::Array<SceneObject *> &ObjList, uint ObjIndex, int PaneNum) { + uint32 flagMask = (PaneNum == 0) ? OBJFLAG_PANE_0 : OBJFLAG_PANE_1; + SceneObject *obj = (ObjIndex == ObjList.size()) ? NULL : ObjList[ObjIndex]; + Rect rect1; + + for (uint idx = 0; idx < ObjList.size(); ++idx) { + SceneObject *currObj = ObjList[idx]; + + if (ObjIndex == ObjList.size()) { + if (currObj->_flags & flagMask) + checkIntersection(ObjList, idx, PaneNum); + } else if (idx != ObjIndex) { + Rect &paneRect = obj->_paneRects[PaneNum]; + Rect objBounds = currObj->_bounds; + if (paneRect.isValidRect()) + objBounds.extend(paneRect); + + Rect objBounds2 = currObj->_bounds; + if (paneRect.isValidRect()) + objBounds2.extend(paneRect); + + objBounds.left &= ~3; + objBounds.right += 3; + objBounds.right &= ~3; + objBounds2.left &= ~3; + objBounds2.right += 3; + objBounds2.right &= ~3; + + if (objBounds.intersects(objBounds2) && !(currObj->_flags & flagMask)) { + currObj->_flags |= flagMask; + checkIntersection(ObjList, idx, PaneNum); + } + } + } +} + +struct SceneObjectLess { + bool operator()(const SceneObject *x, const SceneObject *y) const { + if (y->_priority > x->_priority) + return true; + else if ((y->_priority == x->_priority) && (y->_position.y > x->_position.y)) + return true; + else if ((y->_priority == x->_priority) && (y->_position.y == x->_position.y) && + (y->_yDiff > x->_yDiff)) + return true; + + return false; + } +}; + +void SceneObjectList::sortList(Common::Array<SceneObject *> &ObjList) { + Common::sort(ObjList.begin(), ObjList.end(), SceneObjectLess()); +} + +void SceneObjectList::activate() { + SceneObjectList *objectList = _globals->_sceneObjects; + _globals->_sceneObjects = this; + _globals->_sceneObjects_queue.push_front(this); + + // Flag all the objects as modified + List<SceneObject *>::iterator i; + for (i = begin(); i != end(); ++i) { + (*i)->_flags |= OBJFLAG_PANES; + } + + // Replicate all existing objects on the old object list + for (i = objectList->begin(); i != objectList->end(); ++i) { + SceneObject *sceneObj = (*i)->clone(); + sceneObj->_flags |= OBJFLAG_HIDE | OBJFLAG_REMOVE | OBJFLAG_CLONED; + push_front(sceneObj); + } +} + +void SceneObjectList::deactivate() { + if (_globals->_sceneObjects_queue.size() <= 1) + return; + + SceneObjectList *objectList = *_globals->_sceneObjects_queue.begin(); + _globals->_sceneObjects_queue.pop_front(); + _globals->_sceneObjects = *_globals->_sceneObjects_queue.begin(); + + List<SceneObject *>::iterator i; + for (i = objectList->begin(); i != objectList->end(); ++i) { + if (!((*i)->_flags & OBJFLAG_CLONED)) { + SceneObject *sceneObj = (*i)->clone(); + sceneObj->_flags |= OBJFLAG_HIDE | OBJFLAG_REMOVE | OBJFLAG_CLONED; + _globals->_sceneObjects->push_front(sceneObj); + } + } +} + +void SceneObjectList::synchronise(Serialiser &s) { + _objList.synchronise(s); +} + +/*--------------------------------------------------------------------------*/ + +SceneText::SceneText(): SceneObject() { + _fontNumber = 2; + _width = 160; + _textMode = ALIGN_LEFT; + _colour2 = 0; + _colour3 = 0; +} + +SceneText::~SceneText() { +} + +void SceneText::setup(const Common::String &msg) { + GfxManager gfxMan(_textSurface); + gfxMan.activate(); + Rect textRect; + + gfxMan._font.setFontNumber(_fontNumber); + gfxMan._font._colours.foreground = _colour1; + gfxMan._font._colours2.background = _colour2; + gfxMan._font._colours2.foreground = _colour3; + + gfxMan.getStringBounds(msg.c_str(), textRect, _width); + + // Set up a new blank surface to hold the text + _textSurface.create(textRect.width(), textRect.height()); + _textSurface._transColour = 0xff; + _textSurface.fillRect(textRect, _textSurface._transColour); + + // Write the text to the surface + gfxMan._bounds = textRect; + gfxMan._font.writeLines(msg.c_str(), textRect, _textMode); + + // Do post-init, which adds this SceneText object to the scene + postInit(); + gfxMan.deactivate(); +} + +void SceneText::synchronise(Serialiser &s) { + SceneObject::synchronise(s); + + s.syncAsSint16LE(_fontNumber); + s.syncAsSint16LE(_width); + s.syncAsSint16LE(_colour1); + s.syncAsSint16LE(_colour2); + s.syncAsSint16LE(_colour3); + SYNC_ENUM(_textMode, TextAlign); +} + +/*--------------------------------------------------------------------------*/ + +Visage::Visage() { + _resNum = 0; + _rlbNum = 0; + _data = NULL; +} + +Visage::Visage(const Visage &v) { + _resNum = v._resNum; + _rlbNum = v._rlbNum; + _data = v._data; + if (_data) + _vm->_memoryManager.incLocks(_data); +} + +Visage &Visage::operator=(const Visage &s) { + _resNum = s._resNum; + _rlbNum = s._rlbNum; + _data = s._data; + if (_data) + _vm->_memoryManager.incLocks(_data); + + return *this; +} + +void Visage::setVisage(int resNum, int rlbNum) { + if ((_resNum != resNum) || (_rlbNum != rlbNum)) { + _resNum = resNum; + _rlbNum = rlbNum; + DEALLOCATE(_data); + _data = _vm->_dataManager->getResource(RES_VISAGE, resNum, rlbNum); + assert(_data); + } +} + +Visage::~Visage() { + DEALLOCATE(_data); +} + +GfxSurface Visage::getFrame(int frameNum) { + int numFrames = READ_LE_UINT16(_data); + if (frameNum > numFrames) + frameNum = numFrames; + if (frameNum > 0) + --frameNum; + + int offset = READ_UINT32(_data + 2 + frameNum * 4); + byte *frameData = _data + offset; + + return surfaceFromRes(frameData); +} + +int Visage::getFrameCount() const { + return READ_LE_UINT16(_data); +} + +/*--------------------------------------------------------------------------*/ + +void Player::postInit(SceneObjectList *OwnerList) { + SceneObject::postInit(); + + _canWalk = true; + _uiEnabled = true; + _percent = 100; + _field8C = 10; + _moveDiff.x = 4; + _moveDiff.y = 2; +} + +void Player::disableControl() { + _canWalk = false; + _uiEnabled = false; + _globals->_events.setCursor(CURSOR_NONE); +} + +void Player::enableControl() { + _canWalk = true; + _uiEnabled = true; + _globals->_events.setCursor(CURSOR_WALK); + + switch (_globals->_events.getCursor()) { + case CURSOR_WALK: + case CURSOR_LOOK: + case CURSOR_USE: + case CURSOR_TALK: + _globals->_events.setCursor(_globals->_events.getCursor()); + break; + default: + _globals->_events.setCursor(CURSOR_WALK); + break; + } +} + +void Player::process(Event &event) { + if (!event.handled && (event.eventType == EVENT_BUTTON_DOWN) && + (_globals->_events.getCursor() == CURSOR_WALK) && _globals->_player._canWalk && + (_position != event.mousePos) && _globals->_sceneObjects->contains(this)) { + + PlayerMover *newMover = new PlayerMover(); + Common::Point destPos(event.mousePos.x + _globals->_sceneManager._scene->_sceneBounds.left, + event.mousePos.y + _globals->_sceneManager._scene->_sceneBounds.top); + + addMover(newMover, &destPos, NULL); + event.handled = true; + } +} + +void Player::synchronise(Serialiser &s) { + SceneObject::synchronise(s); + + s.syncAsByte(_canWalk); + s.syncAsByte(_uiEnabled); + s.syncAsSint16LE(_field8C); +} + +/*--------------------------------------------------------------------------*/ + +Region::Region(int resNum, int rlbNum, ResourceType ctlType) { + _regionId = rlbNum; + + byte *regionData = _vm->_dataManager->getResource(ctlType, resNum, rlbNum); + assert(regionData); + + // Set the region bounds + _bounds.top = READ_LE_UINT16(regionData + 6); + _bounds.left = READ_LE_UINT16(regionData + 8); + _bounds.bottom = READ_LE_UINT16(regionData + 10); + _bounds.right = READ_LE_UINT16(regionData + 12); + + // Special handling for small size regions + _regionSize = READ_LE_UINT16(regionData); + if (_regionSize == 14) + // No line slices + return; + + // Set up the line slices + for (int y = 0; y < (_regionSize == 22 ? 1 : _bounds.height()); ++y) { + int slicesCount = READ_LE_UINT16(regionData + 16 + y * 4); + int slicesOffset = READ_LE_UINT16(regionData + 14 + y * 4); + assert(slicesCount < 100); + LineSliceSet sliceSet; + sliceSet.load(slicesCount, regionData + 14 + slicesOffset); + + _ySlices.push_back(sliceSet); + } + + DEALLOCATE(regionData); +} + +/** + * Returns true if the given region contains the specified point + * @param pt Specified position + */ +bool Region::contains(const Common::Point &pt) { + // First check if the point falls inside the overall bounding rectangle + if (!_bounds.contains(pt) || _ySlices.empty()) + return false; + + // Get the correct Y line to use + const LineSliceSet &line = getLineSlices(pt.y); + + // Loop through the horizontal slice list to see if the point falls in one + for (uint idx = 0; idx < line.items.size(); ++idx) { + if ((pt.x >= line.items[idx].xs) && (pt.x < line.items[idx].xe)) + return true; + } + + return false; +} + +/** + * Returns true if the given region is empty + */ +bool Region::empty() const { + return !_bounds.isValidRect() && (_regionSize == 14); +} + +void Region::clear() { + _bounds.set(0, 0, 0, 0); + _regionId = 0; + _regionSize = 0; +} + +void Region::setRect(const Rect &r) { + setRect(r.left, r.top, r.right, r.bottom); +} + +void Region::setRect(int xs, int ys, int xe, int ye) { + bool validRect = (ys < ye) && (xs < xe); + _ySlices.clear(); + + if (!validRect) { + _regionSize = 14; + _bounds.set(0, 0, 0, 0); + } else { + _regionSize = 22; + _bounds.set(xs, ys, xe, ye); + + LineSliceSet sliceSet; + sliceSet.load2(1, xs, xe); + + _ySlices.push_back(sliceSet); + } +} + +const LineSliceSet &Region::getLineSlices(int yp) { + return _ySlices[(_regionSize == 22) ? 0 : yp - _bounds.top]; +} + +LineSliceSet Region::sectPoints(int yp, const LineSliceSet &sliceSet) { + if ((yp < _bounds.top) || (yp >= _bounds.bottom)) + return LineSliceSet(); + + const LineSliceSet &ySet = getLineSlices(yp); + return mergeSlices(sliceSet, ySet); +} + +LineSliceSet Region::mergeSlices(const LineSliceSet &set1, const LineSliceSet &set2) { + LineSliceSet result; + + uint set1Index = 0, set2Index = 0; + + while ((set1Index < set1.items.size()) && (set2Index < set2.items.size())) { + if (set1.items[set1Index].xe <= set2.items[set2Index].xs) { + ++set1Index; + } else if (set2.items[set2Index].xe <= set1.items[set1Index].xs) { + ++set2Index; + } else { + bool set1Flag = set1.items[set1Index].xs >= set2.items[set2Index].xs; + const LineSlice &slice = set1Flag ? set1.items[set1Index] : set2.items[set2Index]; + + result.add(slice.xs, MIN(set1.items[set1Index].xe, set2.items[set2Index].xe)); + if (set1Flag) + ++set1Index; + else + ++set2Index; + } + } + + return result; +} + +/** + * Copies the background covered by the given region to the screen surface + */ +void Region::draw() { + Rect &sceneBounds = _globals->_sceneManager._scene->_sceneBounds; + + for (int yp = sceneBounds.top; yp < sceneBounds.bottom; ++yp) { + // Generate a line slice set + LineSliceSet tempSet; + tempSet.add(sceneBounds.left, sceneBounds.right); + LineSliceSet newSet = sectPoints(yp, tempSet); + + // Loop through the calculated slices + for (uint idx = 0; idx < newSet.items.size(); ++idx) { + Rect rect1(newSet.items[idx].xs, yp, newSet.items[idx].xe, yp + 1); + rect1.left &= ~3; + rect1.right = (rect1.right + 3) & ~3; + + Rect rect2 = rect1; + rect1.translate(-_globals->_sceneOffset.x, -_globals->_sceneOffset.y); + rect2.translate(-sceneBounds.left, -sceneBounds.top); + + _globals->gfxManager().getSurface().copyFrom(_globals->_sceneManager._scene->_backSurface, + rect1, rect2); + } + } +} + +void Region::uniteLine(int yp, LineSliceSet &sliceSet) { + // TODO: More properly implement like the original + + // First expand the bounds as necessary to fit in the row + if (_ySlices.empty()) { + _bounds = Rect(sliceSet.items[0].xs, yp, sliceSet.items[sliceSet.items.size() - 1].xe, yp + 1); + _ySlices.push_back(LineSliceSet()); + } + while (yp < _bounds.top) { + _ySlices.insert_at(0, LineSliceSet()); + --_bounds.top; + } + while (yp >= _bounds.bottom) { + _ySlices.push_back(LineSliceSet()); + ++_bounds.bottom; + } + + // Merge the existing line set into the line + LineSliceSet &destSet = _ySlices[yp - _bounds.top]; + for (uint srcIndex = 0; srcIndex < sliceSet.items.size(); ++srcIndex) { + LineSlice &srcSlice = sliceSet.items[srcIndex]; + + // Check if overlaps existing slices + uint destIndex = 0; + while (destIndex < destSet.items.size()) { + LineSlice &destSlice = destSet.items[destIndex]; + if (((srcSlice.xs >= destSlice.xs) && (srcSlice.xs <= destSlice.xe)) || + ((srcSlice.xe >= destSlice.xs) && (srcSlice.xe <= destSlice.xe)) || + ((srcSlice.xs < destSlice.xs) && (srcSlice.xe > destSlice.xe))) { + // Intersecting, so merge them + destSlice.xs = MIN(srcSlice.xs, destSlice.xs); + destSlice.xe = MAX(srcSlice.xe, destSlice.xe); + break; + } + ++destIndex; + } + if (destIndex == destSet.items.size()) { + // No intersecting region found, so add it to the list + destSet.items.push_back(srcSlice); + } + } + + // Check whether to expand the left/bounds bounds + if (destSet.items[0].xs < _bounds.left) + _bounds.left = destSet.items[0].xs; + if (destSet.items[destSet.items.size() - 1].xe > _bounds.right) + _bounds.right = destSet.items[destSet.items.size() - 1].xe; +} + +void Region::uniteRect(const Rect &rect) { + for (int yp = rect.top; yp < rect.bottom; ++yp) { + LineSliceSet sliceSet; + sliceSet.add(rect.left, rect.right); + uniteLine(yp, sliceSet); + } +} + +/*--------------------------------------------------------------------------*/ + +void SceneRegions::load(int sceneNum) { + clear(); + + byte *regionData = _vm->_dataManager->getResource(RES_CONTROL, sceneNum, 9999, true); + + if (regionData) { + int regionCount = READ_LE_UINT16(regionData); + for (int regionCtr = 0; regionCtr < regionCount; ++regionCtr) { + int rlbNum = READ_LE_UINT16(regionData + regionCtr * 6 + 2); + + push_back(Region(sceneNum, rlbNum)); + } + + DEALLOCATE(regionData); + } +} + +int SceneRegions::indexOf(const Common::Point &pt) { + for (SceneRegions::iterator i = begin(); i != end(); ++i) { + if ((*i).contains(pt)) + return (*i)._regionId; + } + + return 0; +} + +/*--------------------------------------------------------------------------*/ + +SoundHandler::SoundHandler() { + _action = NULL; + _field280 = -1; + if (_globals) + _globals->_sceneListeners.push_back(this); +} + +SoundHandler::~SoundHandler() { + if (_globals) + _globals->_sceneListeners.remove(this); +} + +void SoundHandler::dispatch() { + EventHandler::dispatch(); + int v = _sound.proc12(); + + if (v != -1) { + _field280 = v; + _sound.proc2(-1); + + if (_action) + _action->signal(); + } + + if (_field280 != -1) { + // FIXME: Hardcoded to only flag a sound ended if an action has been set + if (_action) { +// if (!_sound.proc3()) { + _field280 = -1; + if (_action) { + _action->signal(); + _action = NULL; + } + } + } +} + +void SoundHandler::startSound(int soundNum, Action *action, int volume) { + _action = action; + _field280 = 0; + setVolume(volume); + _sound.startSound(soundNum); + + warning("TODO: SoundHandler::startSound"); +} + + +/*--------------------------------------------------------------------------*/ + +void SceneItemList::addItems(SceneItem *first, ...) { + va_list va; + va_start(va, first); + + SceneItem *p = first; + while (p) { + push_back(p); + p = va_arg(va, SceneItem *); + } +} + +/*--------------------------------------------------------------------------*/ + +RegionSupportRec WalkRegion::_processList[PROCESS_LIST_SIZE]; + +void RegionSupportRec::process() { + if (_xDiff < _yDiff) { + _halfDiff += _xDiff; + if (_halfDiff > _yDiff) { + _halfDiff -= _yDiff; + _xp += _xDirection; + } + } else { + do { + _xp += _xDirection; + _halfDiff += _yDiff; + } while (_halfDiff <= _xDiff); + _halfDiff -= _xDiff; + } + --_yDiff2; +} + +/*--------------------------------------------------------------------------*/ + +void WalkRegion::loadRegion(byte *dataP, int size) { + // First clear the region + clear(); + + // Decode the data for the region + int dataCount, regionHeight; + loadProcessList(dataP, size, dataCount, regionHeight); + + int processIndex = 0, idx2 = 0, count; + for (int yp = _processList[0]._yp; yp < regionHeight; ++yp) { + process3(yp, dataCount, processIndex, idx2); + process4(yp, processIndex, idx2, count); + + loadRecords(yp, count, processIndex); + } +} + +void WalkRegion::loadProcessList(byte *dataP, int dataSize, int &dataIndex, int ®ionHeight) { + dataIndex = 0; + int x1 = READ_LE_UINT16(dataP + (dataSize - 1) * 4); + int y1 = READ_LE_UINT16(dataP + (dataSize - 1) * 4 + 2); + regionHeight = y1; + + for (int idx = 0; idx < dataSize; ++idx) { + int xp = READ_LE_UINT16(dataP + idx * 4); + int yp = READ_LE_UINT16(dataP + idx * 4 + 2); + if (yp != y1) { + /* + * Commented out: doesn't seem to be used + int v; + if (idx == (dataSize - 1)) + v = READ_LE_UINT16(dataP + 2); + else + v = process1(idx, dataP, dataSize); + warning("TODO: v not used? - %d", v); + */ + process2(dataIndex, x1, y1, xp, yp); + ++dataIndex; + } + + // Keep regionHeight as the maximum of any y + if (yp > regionHeight) + regionHeight = yp; + + x1 = xp; + y1 = yp; + } +} + +int WalkRegion::process1(int idx, byte *dataP, int dataSize) { + int idx2 = idx + 1; + if (idx2 == dataSize) + idx2 = 0; + + while (READ_LE_UINT16(dataP + idx2 * 4 + 2) == READ_LE_UINT16(dataP + idx * 4 + 2)) { + if (idx2 == (dataSize - 1)) + idx2 = 0; + else + ++idx2; + } + + return READ_LE_UINT16(dataP + idx2 * 4 + 2); +} + +void WalkRegion::process2(int dataIndex, int x1, int y1, int x2, int y2) { + int xDiff = ABS(x2 - x1); + int yDiff = ABS(y2 - y1); + int halfDiff = MAX(xDiff, yDiff) / 2; + int yMax = MIN(y1, y2); + + while (dataIndex && (_processList[dataIndex - 1]._yp > yMax)) { + _processList[dataIndex] = _processList[dataIndex - 1]; + --dataIndex; + } + _processList[dataIndex]._yp = yMax; + + _processList[dataIndex]._xp = (y1 >= y2) ? x2 : x1; + _processList[dataIndex]._xDiff = xDiff; + _processList[dataIndex]._yDiff = yDiff; + _processList[dataIndex]._halfDiff = halfDiff; + + int xTemp = (y1 >= y2) ? x1 - x2 : x2 - x1; + _processList[dataIndex]._xDirection = (xTemp == 0) ? 0 : ((xTemp < 0) ? -1 : 1); + _processList[dataIndex]._yDiff2 = yDiff; +} + +void WalkRegion::process3(int yp, int dataCount, int &idx1, int &idx2) { + while ((idx2 < (dataCount - 1)) && (_processList[idx2 + 1]._yp <= yp)) + ++idx2; + while (!_processList[idx1]._yDiff2) + ++idx1; +} + +void WalkRegion::process4(int yp, int idx1, int idx2, int &count) { + count = 0; + for (int idx = idx1; idx <= idx2; ++idx) { + if (_processList[idx]._yDiff2 > 0) + ++count; + process5(idx, idx1); + } +} + +void WalkRegion::process5(int idx1, int idx2) { + while ((idx1 > idx2) && (_processList[idx1 - 1]._xp > _processList[idx1]._xp)) { + SWAP(_processList[idx1], _processList[idx1 - 1]); + --idx1; + } +} + +void WalkRegion::loadRecords(int yp, int size, int processIndex) { + LineSliceSet sliceSet; + int sliceCount = size / 2; + + for (int idx = 0; idx < sliceCount; ++idx, ++processIndex) { + while (!_processList[processIndex]._yDiff2) + ++processIndex; + + int sliceXs = _processList[processIndex]._xp; + _processList[processIndex].process(); + + do { + ++processIndex; + } while (!_processList[processIndex]._yDiff2); + + int sliceXe = _processList[processIndex]._xp; + _processList[processIndex].process(); + + sliceSet.items.push_back(LineSlice(sliceXs, sliceXe)); + } + + uniteLine(yp, sliceSet); +} + +/*--------------------------------------------------------------------------*/ + +void WRField18::load(byte *data) { + _pt1.x = READ_LE_UINT16(data); + _pt1.y = READ_LE_UINT16(data + 2); + _pt2.x = READ_LE_UINT16(data + 4); + _pt2.y = READ_LE_UINT16(data + 6); + _v = READ_LE_UINT16(data + 8); +} + +/*--------------------------------------------------------------------------*/ + +void WalkRegions::clear() { + _regionList.clear(); + _field18.clear(); + _idxList.clear(); + _idxList2.clear(); +} + +void WalkRegions::load(int sceneNum) { + clear(); + + _resNum = sceneNum; + byte *regionData = _vm->_dataManager->getResource(RES_WALKRGNS, sceneNum, 1, true); + if (!regionData) { + // No data, so return + _resNum = -1; + return; + } + + byte *dataP; + int dataSize; + + // Load the field 18 list + dataP = _vm->_dataManager->getResource(RES_WALKRGNS, sceneNum, 2); + dataSize = _vm->_memoryManager.getSize(dataP); + assert(dataSize % 10 == 0); + + byte *p = dataP; + for (int idx = 0; idx < (dataSize / 10); ++idx, p += 10) { + WRField18 rec; + rec.load(p); + _field18.push_back(rec); + } + + DEALLOCATE(dataP); + + // Load the idx list + dataP = _vm->_dataManager->getResource(RES_WALKRGNS, sceneNum, 3); + dataSize = _vm->_memoryManager.getSize(dataP); + assert(dataSize % 2 == 0); + + p = dataP; + for (int idx = 0; idx < (dataSize / 2); ++idx, p += 2) + _idxList.push_back(READ_LE_UINT16(p)); + + DEALLOCATE(dataP); + + // Load the secondary idx list + dataP = _vm->_dataManager->getResource(RES_WALKRGNS, sceneNum, 4); + dataSize = _vm->_memoryManager.getSize(dataP); + assert(dataSize % 2 == 0); + + p = dataP; + for (int idx = 0; idx < (dataSize / 2); ++idx, p += 2) + _idxList2.push_back(READ_LE_UINT16(p)); + + DEALLOCATE(dataP); + + // Handle the loading of the actual regions themselves + dataP = _vm->_dataManager->getResource(RES_WALKRGNS, sceneNum, 5); + + byte *pWalkRegion = regionData + 16; + byte *srcP = dataP; + for (; (int16)READ_LE_UINT16(pWalkRegion) != -20000; pWalkRegion += 16) { + WalkRegion wr; + + // Set the Walk region specific fields + wr._pt.x = (int16)READ_LE_UINT16(pWalkRegion); + wr._pt.y = (int16)READ_LE_UINT16(pWalkRegion + 2); + wr._idxListIndex = READ_LE_UINT32(pWalkRegion + 4); + wr._idxList2Index = READ_LE_UINT32(pWalkRegion + 8); + + // Region in the region data + int size = READ_LE_UINT16(srcP); + srcP += 2; + wr.loadRegion(srcP, size); + + srcP += size * 4; + _regionList.push_back(wr); + } + + DEALLOCATE(dataP); + DEALLOCATE(regionData); +} + +/** + * Returns the index of the walk region that contains the given point + * @param pt Point to locate + * @param indexList List of region indexes that should be ignored + */ +int WalkRegions::indexOf(const Common::Point &pt, List<int> *indexList) { + for (uint idx = 0; idx < _regionList.size(); ++idx) { + if ((!indexList || !indexList->contains(idx + 1)) && _regionList[idx].contains(pt)) + return idx + 1; + } + + return -1; +} + +/*--------------------------------------------------------------------------*/ + +void ScenePriorities::load(int resNum) { + _resNum = resNum; + clear(); + + byte *regionData = _vm->_dataManager->getResource(RES_PRIORITY, resNum, 9999, true); + + if (regionData) { + int regionCount = READ_LE_UINT16(regionData); + for (int regionCtr = 0; regionCtr < regionCount; ++regionCtr) { + int rlbNum = READ_LE_UINT16(regionData + regionCtr * 6 + 2); + + push_back(Region(resNum, rlbNum, RES_PRIORITY)); + } + + DEALLOCATE(regionData); + } +} + +Region *ScenePriorities::find(int priority) { + // If no priority regions are loaded, then return the placeholder region + if (empty()) + return &_defaultPriorityRegion; + + if (priority > 255) + priority = 255; + + // Loop through the regions to find the closest for the givne priority level + int minRegionId = 9998; + Region *region = NULL; + for (ScenePriorities::iterator i = begin(); i != end(); ++i) { + Region *r = &(*i); + int regionId = r->_regionId; + + if ((regionId > priority) && (regionId < minRegionId)) { + minRegionId = regionId; + region = r; + } + } + + assert(region); + return region; +} + +/*--------------------------------------------------------------------------*/ + +void FloatSet::add(double v1, double v2, double v3) { + _float1 += v1; + _float2 += v2; + _float3 += v3; +} + +void FloatSet::proc1(double v) { + double diff = (cos(v) * _float1) - (sin(v) * _float2); + _float2 = (sin(v) * _float1) + (cos(v) * _float2); + _float1 = diff; +} + +double FloatSet::sqrt(FloatSet &floatSet) { + double f1Diff = _float1 - floatSet._float1; + double f2Diff = _float2 - floatSet._float2; + double f3Diff = _float3 - floatSet._float3; + + return ::sqrt(f1Diff * f1Diff + f2Diff * f2Diff + f3Diff * f3Diff); +} + +/*--------------------------------------------------------------------------*/ + +GameHandler::GameHandler(): EventHandler() { + _nextWaitCtr = 1; + _waitCtr.setCtr(1); + _field14 = 10; +} + +GameHandler::~GameHandler() { + if (_globals) + _globals->_game.removeHandler(this); +} + +void GameHandler::execute() { + if (_waitCtr.decCtr() == 0) { + _waitCtr.setCtr(_nextWaitCtr); + dispatch(); + } +} + +void GameHandler::synchronise(Serialiser &s) { + _lockCtr.synchronise(s); + _waitCtr.synchronise(s); + s.syncAsSint16LE(_nextWaitCtr); + s.syncAsSint16LE(_field14); +} + +/*--------------------------------------------------------------------------*/ + +SceneHandler::SceneHandler() { + _saveGameSlot = -1; + _loadGameSlot = -1; +} + +void SceneHandler::registerHandler() { + postInit(); + _globals->_game.addHandler(this); +} + +void SceneHandler::postInit(SceneObjectList *OwnerList) { + _delayTicks = 2; + + _globals->_scenePalette.loadPalette(0); + _globals->_scenePalette.refresh(); + + // TODO: Bunch of other scene related setup goes here + _globals->_soundManager.postInit(); + + // Set some default flags and cursor + _globals->setFlag(12); + _globals->setFlag(34); + _globals->_events.setCursor(CURSOR_WALK); + + // Set the screen to scroll in response to the player moving off-screen + _globals->_scrollFollower = &_globals->_player; + + // Set the object's that will be in the player's inventory by default + _globals->_inventory._stunner._sceneNumber = 1; + _globals->_inventory._scanner._sceneNumber = 1; + _globals->_inventory._ring._sceneNumber = 1; + + // Switch to the title screen + _globals->_sceneManager.setNewScene(1000); +} + +void SceneHandler::process(Event &event) { + // Main keypress handler + if ((event.eventType == EVENT_KEYPRESS) && !event.handled) { + switch (event.kbd.keycode) { + case Common::KEYCODE_F1: + // F1 - Help + _globals->_events.setCursor(CURSOR_ARROW); + MessageDialog::show(HELP_MSG, OK_BTN_STRING); + break; + + case Common::KEYCODE_F2: { + // F2 - Sound Options + ConfigDialog *dlg = new ConfigDialog(); + dlg->runModal(); + delete dlg; + _globals->_events.setCursorFromFlag(); + break; + } + + case Common::KEYCODE_F3: + // F3 - Quit + _globals->_game.quitGame(); + event.handled = false; + break; + + case Common::KEYCODE_F4: + // F4 - Restart + _globals->_game.restartGame(); + _globals->_events.setCursorFromFlag(); + break; + + case Common::KEYCODE_F7: + // F7 - Restore + _globals->_game.restoreGame(); + _globals->_events.setCursorFromFlag(); + break; + + case Common::KEYCODE_F10: + // F10 - Pause + GfxDialog::setPalette(); + MessageDialog::show(GAME_PAUSED_MSG, OK_BTN_STRING); + _globals->_events.setCursorFromFlag(); + break; + + default: + break; + } + + _globals->_events.setCursorFromFlag(); + } + + // Check for displaying right-click dialog + if ((event.eventType == EVENT_BUTTON_DOWN) && (event.btnState == BTNSHIFT_RIGHT) && + _globals->_player._uiEnabled) { + RightClickDialog *dlg = new RightClickDialog(); + dlg->execute(); + delete dlg; + + event.handled = true; + return; + } + + // If there is an active scene, pass the event to it + if (_globals->_sceneManager._scene) + _globals->_sceneManager._scene->process(event); + + if (!event.handled) { + // Separate check for F5 - Save key + if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_F5)) { + // F5 - Save + _globals->_game.saveGame(); + event.handled = true; + _globals->_events.setCursorFromFlag(); + } + + // Check for debugger + if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_d) && + (event.kbd.flags & Common::KBD_CTRL)) { + // Attach to the debugger + _vm->_debugger->attach(); + _vm->_debugger->onFrame(); + } + + // Mouse press handling + if (_globals->_player._uiEnabled && (event.eventType == EVENT_BUTTON_DOWN) && + !_globals->_sceneItems.empty()) { + // Scan the item list to find one the mouse is within + List<SceneItem *>::iterator i = _globals->_sceneItems.begin(); + while ((i != _globals->_sceneItems.end()) && !(*i)->contains(event.mousePos)) + ++i; + + if (i != _globals->_sceneItems.end()) { + // Pass the action to the item + (*i)->doAction(_globals->_events.getCursor()); + event.handled = _globals->_events.getCursor() != CURSOR_WALK; + + if (_globals->_player._uiEnabled && _globals->_player._canWalk && + (_globals->_events.getCursor() != CURSOR_LOOK)) { + _globals->_events.setCursor(CURSOR_WALK); + } else if (_globals->_player._canWalk && (_globals->_events.getCursor() != CURSOR_LOOK)) { + _globals->_events.setCursor(CURSOR_WALK); + } else if (_globals->_player._uiEnabled && (_globals->_events.getCursor() != CURSOR_LOOK)) { + _globals->_events.setCursor(CURSOR_USE); + } + } + + // Handle player processing + _globals->_player.process(event); + } + } +} + +void SceneHandler::dispatch() { + // Handle game saving and loading + if (_saveGameSlot != -1) { + int saveSlot = _saveGameSlot; + _saveGameSlot = -1; + if (_saver->save(saveSlot, _saveName) != Common::kNoError) + GUIErrorMessage(SAVE_ERROR_MSG); + } + if (_loadGameSlot != -1) { + int loadSlot = _loadGameSlot; + _loadGameSlot = -1; + _saver->restore(loadSlot); + _globals->_events.setCursorFromFlag(); + } + + _globals->_soundManager.dispatch(); + _globals->_scenePalette.signalListeners(); + + // Dispatch to any objects registered in the scene + _globals->_sceneObjects->recurse(SceneHandler::dispatchObject); + + // If a scene is active, then dispatch to it + if (_globals->_sceneManager._scene) + _globals->_sceneManager._scene->dispatch(); + + //TODO: Figure out purpose of the given list + //_globals->_regions.forEach(SceneHandler::handleListener); + + Event event; + while (_globals->_events.getEvent(event)) + process(event); + + // Handle drawing the contents of the scene + if (_globals->_sceneManager._scene) + _globals->_sceneObjects->draw(); + + // Check to see if any scene change is required + _globals->_sceneManager.checkScene(); + + // Signal the ScummVM debugger + _vm->_debugger->onFrame(); + + // Delay between frames + _globals->_events.delay(_delayTicks); +} + +void SceneHandler::dispatchObject(EventHandler *obj) { + obj->dispatch(); +} + +void SceneHandler::saveListener(Serialiser &ser) { + warning("TODO: SceneHandler::saveListener"); +} + +/*--------------------------------------------------------------------------*/ + +void Game::execute() { + // Main game loop + bool activeFlag = false; + do { + // Process all currently atcive game handlers + activeFlag = false; + for (List<GameHandler *>::iterator i = _handlers.begin(); i != _handlers.end(); ++i) { + GameHandler *gh = *i; + if (gh->_lockCtr.getCtr() == 0) { + gh->execute(); + activeFlag = true; + } + } + } while (activeFlag && !_vm->getEventManager()->shouldQuit()); +} + +void Game::restartGame() { + if (MessageDialog::show(RESTART_MSG, CANCEL_BTN_STRING, RESTART_BTN_STRING) == 1) + _globals->_game.restart(); +} + +void Game::saveGame() { + if (_globals->getFlag(50)) + MessageDialog::show(SAVING_NOT_ALLOWED_MSG, OK_BTN_STRING); + else { + // Show the save dialog + handleSaveLoad(true, _globals->_sceneHandler._saveGameSlot, _globals->_sceneHandler._saveName); + } +} + +void Game::restoreGame() { + if (_globals->getFlag(50)) + MessageDialog::show(RESTORING_NOT_ALLOWED_MSG, OK_BTN_STRING); + else { + // Show the load dialog + handleSaveLoad(false, _globals->_sceneHandler._loadGameSlot, _globals->_sceneHandler._saveName); + } +} + +void Game::quitGame() { + if (MessageDialog::show(QUIT_CONFIRM_MSG, CANCEL_BTN_STRING, QUIT_BTN_STRING) == 1) + _vm->quitGame(); +} + +void Game::handleSaveLoad(bool saveFlag, int &saveSlot, Common::String &saveName) { + const EnginePlugin *plugin = 0; + EngineMan.findGame(_vm->getGameId(), &plugin); + GUI::SaveLoadChooser *dialog; + if (saveFlag) + dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save")); + else + dialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load")); + + dialog->setSaveMode(saveFlag); + + saveSlot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + saveName = dialog->getResultString(); + + delete dialog; +} + +void Game::restart() { + _globals->_scenePalette.clearListeners(); + _globals->_soundHandler.proc3(); + + // Reset the flags + _globals->reset(); + _globals->setFlag(34); + + // Clear save/load slots + _globals->_sceneHandler._saveGameSlot = -1; + _globals->_sceneHandler._loadGameSlot = -1; + + _globals->_stripNum = 0; + _globals->_events.setCursor(CURSOR_WALK); + + // Reset item properties + _globals->_inventory._stunner._sceneNumber = 1; + _globals->_inventory._scanner._sceneNumber = 1; + _globals->_inventory._stasisBox._sceneNumber = 5200; + _globals->_inventory._infoDisk._sceneNumber = 40; + _globals->_inventory._stasisNegator._sceneNumber = 0; + _globals->_inventory._keyDevice._sceneNumber = 0; + _globals->_inventory._medkit._sceneNumber = 2280; + _globals->_inventory._ladder._sceneNumber = 4100; + _globals->_inventory._rope._sceneNumber = 4150; + _globals->_inventory._key._sceneNumber = 7700; + _globals->_inventory._translator._sceneNumber = 2150; + _globals->_inventory._paper._sceneNumber = 7700; + _globals->_inventory._waldos._sceneNumber = 0; + _globals->_inventory._ring._sceneNumber = 1; + _globals->_inventory._stasisBox2._sceneNumber = 8100; + _globals->_inventory._cloak._sceneNumber = 9850; + _globals->_inventory._tunic._sceneNumber = 9450; + _globals->_inventory._candle._sceneNumber = 9500; + _globals->_inventory._straw._sceneNumber = 9400; + _globals->_inventory._scimitar._sceneNumber = 9850; + _globals->_inventory._sword._sceneNumber = 9850; + _globals->_inventory._helmet._sceneNumber = 9500; + _globals->_inventory._items._sceneNumber = 4300; + _globals->_inventory._concentrator._sceneNumber = 4300; + _globals->_inventory._nullifier._sceneNumber = 4300; + _globals->_inventory._peg._sceneNumber = 4045; + _globals->_inventory._vial._sceneNumber = 5100; + _globals->_inventory._jacket._sceneNumber = 9850; + _globals->_inventory._tunic2._sceneNumber = 9850; + _globals->_inventory._bone._sceneNumber = 5300; + _globals->_inventory._jar._sceneNumber = 7700; + _globals->_inventory._emptyJar._sceneNumber = 7700; + + // Change to the first game scene + _globals->_sceneManager.changeScene(30); +} + +void Game::endGame(int resNum, int lineNum) { + _globals->_events.setCursor(CURSOR_WALK); + Common::String msg = _vm->_dataManager->getMessage(resNum, lineNum); + bool savesExist = _saver->savegamesExist(); + + if (!savesExist) { + // No savegames exist, so prompt the user to restart or quit + if (MessageDialog::show(msg, QUIT_BTN_STRING, RESTART_BTN_STRING) == 0) + _vm->quitGame(); + else + restart(); + } else { + // Savegames exist, so prompt for Restore/Restart + bool breakFlag; + do { + if (MessageDialog::show(msg, RESTART_BTN_STRING, RESTORE_BTN_STRING) == 0) { + breakFlag = true; + } else { + handleSaveLoad(false, _globals->_sceneHandler._loadGameSlot, _globals->_sceneHandler._saveName); + breakFlag = _globals->_sceneHandler._loadGameSlot > 0; + } + } while (!breakFlag); + } + + _globals->_events.setCursorFromFlag(); +} + +} // End of namespace tSage diff --git a/engines/tsage/core.h b/engines/tsage/core.h new file mode 100644 index 0000000000..5e3da6a170 --- /dev/null +++ b/engines/tsage/core.h @@ -0,0 +1,956 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/core.h $ + * $Id: core.h 227 2011-02-11 22:13:54Z dreammaster $ + * + */ + +#ifndef TSAGE_CORE_H +#define TSAGE_CORE_H + +#include "common/scummsys.h" +#include "common/endian.h" +#include "common/error.h" +#include "common/list.h" +#include "common/rect.h" +#include "graphics/surface.h" +#include "tsage/events.h" +#include "tsage/graphics.h" +#include "tsage/resources.h" +#include "tsage/saveload.h" +#include "tsage/sound.h" + +namespace tSage { + +#define MAX_FLAGS 256 + +class EventHandler; +class SceneObject; +class SceneObjectList; +class ObjectMover; +class Action; +class Serialiser; + +class InvObject: public SavedObject { +public: + int _sceneNumber; + int _displayResNum; + int _rlbNum; + int _cursorNum; + Rect _bounds; + CursorType _cursorId; + Common::String _description; + int _iconResNum; +public: + InvObject(int sceneNumber, int rlbNum, int cursorNum, CursorType cursorId, const Common::String description); + + bool inInventory() const { return _sceneNumber == 1; } + void setCursor(); + + virtual Common::String getClassName() { return "InvObject"; } + virtual void synchronise(Serialiser &s) { + s.syncAsUint16LE(_sceneNumber); + } +}; + +class InvObjectList: public SavedObject { +public: + InvObject _stunner; + InvObject _scanner; + InvObject _stasisBox; + InvObject _infoDisk; + InvObject _stasisNegator; + InvObject _keyDevice; + InvObject _medkit; + InvObject _ladder; + InvObject _rope; + InvObject _key; + InvObject _translator; + InvObject _ale; + InvObject _paper; + InvObject _waldos; + InvObject _stasisBox2; + InvObject _ring; + InvObject _cloak; + InvObject _tunic; + InvObject _candle; + InvObject _straw; + InvObject _scimitar; + InvObject _sword; + InvObject _helmet; + InvObject _items; + InvObject _concentrator; + InvObject _nullifier; + InvObject _peg; + InvObject _vial; + InvObject _jacket; + InvObject _tunic2; + InvObject _bone; + InvObject _jar; + InvObject _emptyJar; + + List<InvObject *> _itemList; + InvObject *_selectedItem; +public: + InvObjectList(); + + virtual Common::String getClassName() { return "InvObjectList"; } + virtual void synchronise(Serialiser &s); +}; + +/*--------------------------------------------------------------------------*/ + +/** + * Basic reference counter class + */ +class RefCounter: public Serialisable { +private: + int _ctr; +public: + RefCounter() { clear(); } + virtual ~RefCounter() {} + + RefCounter(int v) { _ctr = v; } + + void clear() { _ctr = 0; } + void setCtr(int v) { _ctr = v; } + int decCtr() { + if (_ctr > 0) --_ctr; + return _ctr; + } + int incCtr() { return ++_ctr; } + int getCtr() const { return _ctr; } + + virtual void synchronise(Serialiser &s) { s.syncAsSint16LE(_ctr); } +}; + +class EventHandler: public SavedObject { +public: + Action *_action; + + EventHandler(): SavedObject() { _action = NULL; } + virtual ~EventHandler() { destroy(); } + + virtual void synchronise(Serialiser &s) { SYNC_POINTER(_action); } + virtual Common::String getClassName() { return "EventHandler"; } + virtual void postInit(SceneObjectList *OwnerList = NULL) {} + virtual void remove() {} + virtual void signal() {} + virtual void process(Event &event) {} + virtual void dispatch(); + virtual void setAction(Action *action) { setAction(action, NULL); } + virtual void setAction(Action *action, EventHandler *fmt, ...); + virtual void destroy() {}; +}; + +class Action: public EventHandler { +public: + EventHandler *_owner; + int _actionIndex; + int _delayFrames; + uint32 _startFrame; + int _field16; + EventHandler *_fmt; + + Action(); + + virtual void synchronise(Serialiser &s); + virtual Common::String getClassName() { return "Action"; } + virtual void remove(); + virtual void process(Event &event); + virtual void dispatch(); + virtual void attached(EventHandler *newOwner, EventHandler *fmt, va_list va); + + void attach(EventHandler *newOwner, EventHandler *fmt, ...) { + va_list va; + va_start(va, fmt); + attached(newOwner, fmt, va); + va_end(va); + } + int getActionIndex() const { return _actionIndex; } + void setActionIndex(int index) { _actionIndex = index; } + void setDelay(int numFrames); +}; + +class ActionExt: public Action { +public: + int _state; +}; + +class ObjectMover: public EventHandler { +public: + Common::Point _destPosition; + Common::Point _moveDelta; + Common::Point _moveSign; + int _minorDiff; + int _majorDiff; + int _field1A; + Action *_action; + SceneObject *_sceneObject; +public: + ObjectMover() { _action = NULL; _sceneObject = NULL; } + virtual ~ObjectMover(); + + virtual void synchronise(Serialiser &s); + virtual Common::String getClassName() { return "ObjectMover"; } + virtual void remove(); + virtual void dispatch(); + virtual void startMove(SceneObject *sceneObj, va_list va) {} + virtual void setup(const Common::Point &destPos); + virtual bool dontMove() const; + virtual void endMove(); +}; + +class ObjectMover2: public ObjectMover { +public: + SceneObject *_destObject; + int _minArea; + int _maxArea; +public: + ObjectMover2(); + virtual ~ObjectMover2() {} + + virtual void synchronise(Serialiser &s); + virtual Common::String getClassName() { return "ObjectMover2"; } + virtual void dispatch(); + virtual void startMove(SceneObject *sceneObj, va_list va); + virtual void endMove(); +}; + +class ObjectMover3: public ObjectMover2 { +public: + virtual Common::String getClassName() { return "ObjectMover3"; } + virtual void dispatch(); + virtual void startMove(SceneObject *sceneObj, va_list va); + virtual void endMove(); +}; + +class NpcMover: public ObjectMover { +public: + virtual Common::String getClassName() { return "NpcMover"; } + virtual void startMove(SceneObject *sceneObj, va_list va); +}; + +#define MAX_ROUTE_SIZE 20 +#define ROUTE_END_VAL -20000 + +class RouteEnds { +public: + Common::Point moveSrc; + Common::Point moveDest; +}; + +class PlayerMover: public NpcMover { +protected: + void setDest(const Common::Point &destPos); + void pathfind(Common::Point *routeList, Common::Point srcPos, Common::Point destPos, RouteEnds routeEnds); + int regionIndexOf(const Common::Point &pt); + int regionIndexOf(int xp, int yp) { return regionIndexOf(Common::Point(xp, yp)); } + int findClosestRegion(Common::Point &pt, List<int> &indexList); + int checkMover(Common::Point &srcPos, const Common::Point &destPos); + void checkMovement2(const Common::Point &pt1, const Common::Point &pt2, int numSteps, Common::Point &ptOut); + int proc1(int *routeList, int srcRegion, int destRegion, int &v); + + static Common::Point *findLinePoint(RouteEnds *routeEnds, Common::Point *objPos, int length, Common::Point *outPos); + static int findDistance(const Common::Point &pt1, const Common::Point &pt2); + static bool sub_F8E5(const Common::Point &pt1, const Common::Point &pt2, const Common::Point &pt3, + const Common::Point &pt4, Common::Point *ptOut = NULL); +public: + Common::Point _finalDest; + Common::Point _routeList[MAX_ROUTE_SIZE]; + int _routeIndex; + + virtual void synchronise(Serialiser &s); + virtual Common::String getClassName() { return "PlayerMover"; } + virtual void startMove(SceneObject *sceneObj, va_list va); + virtual void endMove(); +}; + +class PlayerMover2: public PlayerMover { +public: + SceneObject *_destObject; + int _field7E; + int _minArea; + PlayerMover2(): PlayerMover() { _destObject = NULL; } + + virtual void synchronise(Serialiser &s); + virtual Common::String getClassName() { return "PlayerMover2"; } + virtual void dispatch(); + virtual void startMove(SceneObject *sceneObj, va_list va); + virtual void endMove(); +}; + +/*--------------------------------------------------------------------------*/ + +class ScenePalette; + +class PaletteModifier: public SavedObject { +public: + ScenePalette *_scenePalette; + Action *_action; +public: + PaletteModifier(); + + virtual void synchronise(Serialiser &s) { + SYNC_POINTER(_scenePalette); + SYNC_POINTER(_action); + } + virtual void signal() = 0; + virtual void remove() = 0; +}; + +class PaletteRotation: public PaletteModifier { +public: + bool _disabled; + int _delayFrames; + int _delayCtr; + uint32 _frameNumber; + int _currIndex; + int _start; + int _end; + int _rotationMode; + int _duration; + uint32 _palette[256]; +public: + PaletteRotation(); + + virtual Common::String getClassName() { return "PaletteRotation"; } + virtual void synchronise(Serialiser &s); + virtual void signal(); + virtual void remove(); + + void setDisabled(bool v) { _disabled = v; } + void set(ScenePalette *palette, int start, int end, int rotationMode, int duration, Action *action); + void setPalette(ScenePalette *palette, bool disabled); + bool decDuration(); + void setDelay(int amount); +}; + +/*--------------------------------------------------------------------------*/ + +class PaletteUnknown: public PaletteModifier { +public: + int _step, _percent, _field12, _field14; + uint32 _palette[256]; +public: + virtual Common::String getClassName() { return "PaletteUnknown"; } + virtual void synchronise(Serialiser &s); + virtual void signal(); + virtual void remove(); +}; + +enum FadeMode {FADEMODE_NONE = 0, FADEMODE_GRADUAL = 1, FADEMODE_IMMEDIATE = 2}; + +class ScenePalette: public SavedObject { +public: + uint32 _palette[256]; + GfxColours _colours; + List<PaletteModifier *> _listeners; + int _field412; + + uint8 _redColour; + uint8 _greenColour; + uint8 _blueColour; + uint8 _aquaColour; + uint8 _purpleColour; + uint8 _limeColour; +public: + ScenePalette(); + ScenePalette(int paletteNum); + + bool loadPalette(int paletteNum); + void refresh(); + void setPalette(int index, int count); + uint8 indexOf(uint r, uint g, uint b, int threshold = 0xffff); + void getPalette(int start = 0, int count = 256); + void signalListeners(); + void clearListeners(); + void fade(const byte *adjustData, bool fullAdjust, int percent); + PaletteRotation *addRotation(int start, int end, int rotationMode, int duration = 0, Action *action = NULL); + PaletteUnknown *addUnkPal(uint32 *arrBufferRGB, int unkNumb, bool disabled, Action *action); + + static void changeBackground(const Rect &bounds, FadeMode fadeMode); + + virtual void synchronise(Serialiser &s); + virtual Common::String getClassName() { return "ScenePalette"; } +}; + +// DisplayParamType constant set. This must not be an enum +const int SET_WIDTH = 0; +const int SET_X = 1; +const int SET_Y = 2; +const int SET_FONT = 3; +const int SET_BG_COLOUR = 4; +const int SET_FG_COLOUR = 5; +const int SET_KEEP_ONSCREEN = 6; +const int SET_EXT_BGCOLOUR = 7; +const int SET_EXT_FGCOLOUR = 8; +const int SET_POS_MODE = 9; +const int SET_TEXT_MODE = 10; +const int LIST_END = -999; + +class SceneItem: public EventHandler { +public: + Rect _bounds; + Common::String _msg; + int _fieldE, _field10; + Common::Point _position; + int _yDiff; + int _sceneRegionId; +public: + SceneItem(): EventHandler() { _msg = "Feature"; _action = NULL; _sceneRegionId = 0; } + + virtual void synchronise(Serialiser &s); + virtual Common::String getClassName() { return "SceneItem"; } + virtual void remove(); + virtual void destroy() {} + virtual void startMover(CursorType action) { doAction(action); } + virtual void doAction(int action); + + bool contains(const Common::Point &pt); + void setBounds(const Rect &newBounds) { _bounds = newBounds; } + void setBounds(const int ys, const int xe, const int ye, const int xs) { _bounds = Rect(MIN(xs, xe), MIN(ys, ye), MAX(xs, xe), MAX(ys, ye)); } + static void display(int resNum, int lineNum, ...); + static void display2(int resNum, int lineNum) { + display(resNum, lineNum, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } +}; + +class SceneItemExt: public SceneItem { +public: + int _state; + + virtual Common::String getClassName() { return "SceneItemExt"; } + virtual void synchronise(Serialiser &s) { + SceneItem::synchronise(s); + s.syncAsSint16LE(_state); + } +}; + +class SceneHotspot: public SceneItem { +public: + SceneHotspot(): SceneItem() {} + + virtual Common::String getClassName() { return "SceneHotspot"; } + virtual void doAction(int action); +}; + +class NamedHotspot: public SceneHotspot { +public: + int _resnum, _lookLineNum, _useLineNum; + NamedHotspot(): SceneHotspot() {} + + void setup(const int ys, const int xe, const int ye, const int xs, const int resnum, const int lookLineNum, const int useLineNum); + virtual void doAction(int action); + virtual Common::String getClassName() { return "NamedHotspot"; } +}; + +enum AnimateMode {ANIM_MODE_NONE = 0, ANIM_MODE_1 = 1, ANIM_MODE_2 = 2, ANIM_MODE_3 = 3, + ANIM_MODE_4 = 4, ANIM_MODE_5 = 5, ANIM_MODE_6 = 6, ANIM_MODE_7 = 7, ANIM_MODE_8 = 8}; + +class SceneObject; + +class Visage { +private: + byte *_data; +public: + int _resNum; + int _rlbNum; +public: + Visage(); + Visage(const Visage &v); + ~Visage(); + + void setVisage(int resNum, int rlbNum = 9999); + GfxSurface getFrame(int frameNum); + int getFrameCount() const; + Visage &operator=(const Visage &s); +}; + +class SceneObjectWrapper: public EventHandler { +private: + Visage _visageImages; +public: + SceneObject *_sceneObject; +public: + SceneObjectWrapper() { _sceneObject = NULL; } + virtual ~SceneObjectWrapper() {} + + void setSceneObject(SceneObject *so); + + virtual void synchronise(Serialiser &s); + virtual Common::String getClassName() { return "SceneObjectWrapper"; } + virtual void remove(); + virtual void dispatch(); +}; + +enum ObjectFlags {OBJFLAG_FIXED_PRIORITY = 1, OBJFLAG_NO_UPDATES = 2, OBJFLAG_ZOOMED = 4, + OBJFLAG_SUPPRESS_DISPATCH = 8, OBJFLAG_HIDE = 0x100, OBJFLAG_HIDING = 0x200, OBJFLAG_REMOVE = 0x400, + OBJFLAG_CLONED = 0x800, OBJFLAG_CHECK_REGION = 0x1000, OBJFLAG_PANE_0 = 0x4000, OBJFLAG_PANE_1 = 0x8000, + OBJFLAG_PANES = OBJFLAG_PANE_0 | OBJFLAG_PANE_1 +}; + +class SceneObject: public SceneHotspot { +private: + Visage _visageImages; + + int getNewFrame(); + void animEnded(); + int changeFrame(); + bool isNoMover() const { return !_mover || (_regionIndex > 0); } +public: + uint32 _updateStartFrame; + uint32 _walkStartFrame; + Common::Point _field2E; + int _percent; + int _priority; + int _angle; + uint32 _flags; + int _xs, _xe; + Rect _paneRects[2]; + int _visage; + SceneObjectWrapper *_objectWrapper; + int _strip; + AnimateMode _animateMode; + int _frame; + int _endFrame; + int _field68; + int _frameChange; + int _numFrames; + int _regionIndex; + EventHandler *_mover; + Common::Point _moveDiff; + int _field7A; + Action *_endAction; + uint32 _regionBitList; +public: + SceneObject(); + SceneObject(const SceneObject &so); + virtual ~SceneObject(); + + void setPosition(const Common::Point &p, int yDiff = 0); + void setStrip(int frameNum); + void setStrip2(int frameNum); + void setZoom(int percent); + void updateZoom(); + void changeZoom(int percent); + void setFrame(int frameNum); + void setFrame2(int frameNum); + void setPriority(int priority); + void setPriority2(int priority); + void setVisage(int visage); + void setObjectWrapper(SceneObjectWrapper *objWrapper); + void addMover(ObjectMover *mover, ...); + void getHorizBounds(); + int getRegionIndex(); + int checkRegion(const Common::Point &pt); + void animate(AnimateMode animMode, ...); + SceneObject *clone() const; + void checkAngle(const SceneObject *obj); + void hide(); + void show(); + int getSpliceArea(const SceneObject *obj); + int getFrameCount(); + + virtual void synchronise(Serialiser &s); + virtual Common::String getClassName() { return "SceneObject"; } + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void remove(); + virtual void process(Event &event) { event.handled = true; } + virtual void dispatch(); + virtual void calcAngle(const Common::Point &pt); + virtual void removeObject(); + virtual GfxSurface getFrame(); + virtual void reposition(); + virtual void draw(); + virtual void proc19() {} + virtual void updateScreen(); + void setup(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority); +}; + +class SceneObjectExt: public SceneObject { +public: + int _state; + + virtual void synchronise(Serialiser &s) { + SceneObject::synchronise(s); + s.syncAsSint16LE(_state); + } + virtual Common::String getClassName() { return "SceneObjectExt"; } +}; + +class SceneText: public SceneObject { +public: + int _fontNumber; + int _width; + TextAlign _textMode; + int _colour1; + int _colour2; + int _colour3; + GfxSurface _textSurface; +public: + SceneText(); + ~SceneText(); + + void setup(const Common::String &msg); + + virtual void synchronise(Serialiser &s); + virtual Common::String getClassName() { return "SceneText"; } + virtual GfxSurface getFrame() { return _textSurface; } +}; + +class Player: public SceneObject { +public: + bool _canWalk; + bool _uiEnabled; + int _field8C; +public: + Player(): SceneObject() {} + + virtual Common::String getClassName() { return "Player"; } + virtual void synchronise(Serialiser &s); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void process(Event &event); + + void disableControl(); + void enableControl(); +}; + +/*--------------------------------------------------------------------------*/ + +class LineSliceSet { +public: + Common::Array<LineSlice> items; + + void load(int size, const byte *srcP) { + for (int i = 0; i < size; ++i, srcP += 4) + items.push_back(LineSlice(READ_LE_UINT16(srcP), READ_LE_UINT16(srcP + 2))); + } + void load2(int size, ...) { + va_list va; + va_start(va, size); + + while (size-- > 0) { + int xs = va_arg(va, int); + int xe = va_arg(va, int); + items.push_back(LineSlice(xs, xe)); + } + } + + void add(LineSlice &slice) { items.push_back(slice); } + void add(int xs, int xe) { items.push_back(LineSlice(xs, xe)); } + static LineSliceSet mergeSlices(const LineSliceSet &set1, LineSliceSet &set2); +}; + +class Region { +public: + int _regionSize; + int _regionId; + Rect _bounds; + Common::Array<LineSliceSet> _ySlices; +public: + Region() { _regionSize = 0; _regionId = 0; } + Region(int resNum, int rlbNum, ResourceType ctlType = RES_CONTROL); + + bool contains(const Common::Point &pt); + bool empty() const; + void clear(); + void setRect(const Rect &r); + void setRect(int xs, int ys, int xe, int ye); + const LineSliceSet &getLineSlices(int yp); + LineSliceSet sectPoints(int yp, const LineSliceSet &sliceSet); + void draw(); + void uniteLine(int yp, LineSliceSet &sliceSet); + void uniteRect(const Rect &rect); + + static LineSliceSet mergeSlices(const LineSliceSet &set1, const LineSliceSet &set2); +}; + +class SceneRegions: public List<Region> { +public: + void load(int sceneNum); + + int indexOf(const Common::Point &pt); +}; + +class SceneObjectList: public SavedObject { +private: + void checkIntersection(Common::Array<SceneObject *> &ObjList, uint ObjIndex, int PaneNum); + + List<SceneObject *> _objList; + bool _listAltered; +public: + SceneObjectList() { _listAltered = false; } + void sortList(Common::Array<SceneObject *> &ObjList); + + virtual Common::String getClassName() { return "SceneObjectList"; } + virtual void synchronise(Serialiser &s); + + void draw(); + void activate(); + static void deactivate(); + + typedef void (*EventHandlerFn)(EventHandler *fn); + void recurse(EventHandlerFn Fn) { + // Loop through each object + _listAltered = false; + for (List<SceneObject *>::iterator i = _objList.begin(); i != _objList.end() && !_listAltered; ) { + SceneObject *o = *i; + ++i; + Fn(o); + } + } + List<SceneObject *>::iterator begin() { return _objList.begin(); } + List<SceneObject *>::iterator end() { return _objList.end(); } + bool contains(SceneObject *sceneObj) { return _objList.contains(sceneObj); } + void push_back(SceneObject *sceneObj) { _objList.push_back(sceneObj); } + void push_front(SceneObject *sceneObj) { _objList.push_front(sceneObj); } + void remove(SceneObject *sceneObj) { + _objList.remove(sceneObj); + _listAltered = true; + } +}; + +class ScenePriorities: public List<Region> { +public: + int _resNum; + int _field14; + int _field16; + Region _defaultPriorityRegion; +public: + void load(int resNum); + + Region *find(int priority); +}; + +/*--------------------------------------------------------------------------*/ + +class GameSoundHandler { +public: + void proc1() { + warning("TODO: GameSoundHandler::proc1"); + } + void proc5(int v) { + warning("TODO: GameSoundHandler::proc5"); + } + void proc11(int v1, int v2, int v3, int v4) { + warning("TODO: GameSoundHandler::proc11"); + } + int proc12() { + // TODO + return -1; + } + void proc2(int v) { + // TODO + } + int proc3() { + return 0; + } + void setVolume(int volume) { + warning("TODO GameSoundHandler::setVolume"); + } + void startSound(int soundNum) { + warning("TODO GameSoundHandler::startSound"); + } +}; + +class SoundHandler: public EventHandler { +public: + GameSoundHandler _sound; + Action *_action; + int _field280; +public: + SoundHandler(); + ~SoundHandler(); + + void startSound(int soundNum, Action *action = NULL, int volume = 127); + void proc1(Action *action) { + proc11(0, 5, 10, 1, action); + } + void proc2(int v) { + warning("TODO: SoundHandler::proc2"); + } + void proc3() { + warning("TODO: SoundHandler::proc5"); + } + void proc4() { + _sound.proc1(); + } + void proc5(int v) { + _sound.proc5(v); + } + void proc11(int v1, int v2, int v3, int v4, Action *action) { + if (action) + _action = action; + + _sound.proc11(v1, v2, v3, v4); + } + void setVolume(int volume) { _sound.setVolume(volume); } + + virtual Common::String getClassName() { return "SoundHandler"; } + virtual void dispatch(); +}; + +/*--------------------------------------------------------------------------*/ + +class SceneItemList: public List<SceneItem *> { +public: + void addItems(SceneItem *first, ...); +}; + +/*--------------------------------------------------------------------------*/ + +class RegionSupportRec { +public: + int _yp; + int _xp; + int _xDiff; + int _yDiff; + int _xDirection; + int _halfDiff; + int _yDiff2; + + void process(); +}; + +#define PROCESS_LIST_SIZE 100 + +class WalkRegion: public Region { +private: + static RegionSupportRec _processList[PROCESS_LIST_SIZE]; + void loadProcessList(byte *dataP, int dataSize, int &dataIndex, int ®ionHeight); + int process1(int idx, byte *dataP, int dataSize); + void process2(int dataIndex, int x1, int y1, int x2, int y2); + void process3(int yp, int dataCount, int &idx1, int &idx2); + void process4(int yp, int idx1, int idx2, int &count); + void process5(int idx1, int idx2); + void loadRecords(int yp, int size, int processIndex); + void process6(RegionSupportRec &rec); +public: + Common::Point _pt; + int _idxListIndex; + int _idxList2Index; +public: + void loadRegion(byte *dataP, int size); +}; + +class WRField18 { +public: + Common::Point _pt1, _pt2; + int _v; +public: + void load(byte *data); +}; + +class WalkRegions { +public: + int _resNum; + RouteEnds _routeEnds; + Common::Array<WalkRegion> _regionList; + Common::Array<WRField18> _field18; + Common::Array<int> _idxList; + Common::Array<int> _idxList2; +public: + WalkRegions() { _resNum = -1; } + + void clear(); + void load(int sceneNum); + int indexOf(const Common::Point &pt, List<int> *indexList = NULL); + WalkRegion &operator[](int idx) { + assert((idx >= 1) && (idx <= (int)_regionList.size())); + return _regionList[idx - 1]; + } +}; + +/*--------------------------------------------------------------------------*/ + +class FloatSet { +public: + double _float1, _float2, _float3, _float4; + + FloatSet() { _float1 = _float2 = _float3 = _float4 = 0; } + void add(double v1, double v2, double v3); + void proc1(double v); + double sqrt(FloatSet &floatSet); +}; + +/*--------------------------------------------------------------------------*/ + +class GameHandler: public EventHandler { +public: + RefCounter _lockCtr; + RefCounter _waitCtr; + int _nextWaitCtr; + int _field14; +public: + GameHandler(); + virtual ~GameHandler(); + void execute(); + + virtual void synchronise(Serialiser &s); + virtual Common::String getClassName() { return "GameHandler"; } + virtual void postInit(SceneObjectList *OwnerList = NULL) {} + virtual void dispatch() {} +}; + +class SceneHandler: public GameHandler { +public: + int _saveGameSlot; + int _loadGameSlot; + int _delayTicks; + Common::String _saveName; +public: + SceneHandler(); + void registerHandler(); + + virtual Common::String getClassName() { return "SceneHandler"; } + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void process(Event &event); + virtual void dispatch(); + + static void dispatchObject(EventHandler *obj); + static void saveListener(Serialiser &ser); +}; + +/*--------------------------------------------------------------------------*/ + +class Game { +private: + List<GameHandler *> _handlers; + + static bool notLockedFn(GameHandler *g); + void restart(); + void handleSaveLoad(bool saveFlag, int &saveSlot, Common::String &saveName); +public: + void addHandler(GameHandler *entry) { _handlers.push_back(entry); } + void removeHandler(GameHandler *entry) { _handlers.remove(entry); } + + void execute(); + void restartGame(); + void saveGame(); + void restoreGame(); + void quitGame(); + void endGame(int resNum, int lineNum); +}; + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/debugger.cpp b/engines/tsage/debugger.cpp new file mode 100644 index 0000000000..2c6c533125 --- /dev/null +++ b/engines/tsage/debugger.cpp @@ -0,0 +1,172 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/debugger.cpp $ + * $Id: debugger.cpp 223 2011-02-09 13:03:31Z dreammaster $ + * + */ + +#include "tsage/debugger.h" +#include "common/config-manager.h" +#include "common/endian.h" +#include "tsage/globals.h" +#include "tsage/graphics.h" + + +namespace tSage { + +Debugger::Debugger(): GUI::Debugger() { + DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); + DCmd_Register("scene", WRAP_METHOD(Debugger, Cmd_Scene)); + DCmd_Register("walk_regions", WRAP_METHOD(Debugger, Cmd_WalkRegions)); + DCmd_Register("priority_regions", WRAP_METHOD(Debugger, Cmd_PriorityRegions)); + DCmd_Register("item", WRAP_METHOD(Debugger, Cmd_Item)); +} + +static int strToInt(const char *s) { + if (!*s) + // No string at all + return 0; + else if (toupper(s[strlen(s) - 1]) != 'H') + // Standard decimal string + return atoi(s); + + // Hexadecimal string + uint tmp = 0; + int read = sscanf(s, "%xh", &tmp); + if (read < 1) + error("strToInt failed on string \"%s\"", s); + return (int)tmp; +} + +/** + * This command loads up the specified new scene number + */ +bool Debugger::Cmd_Scene(int argc, const char **argv) { + if (argc < 2) { + DebugPrintf("Usage: %s <scene number> [prior scene #]\n", argv[0]); + return true; + } else { + if (argc == 3) + _globals->_sceneManager._sceneNumber = strToInt(argv[2]); + + _globals->_sceneManager.changeScene(strToInt(argv[1])); + return false; + } +} + +/** + * This command draws the walk regions onto the screen + */ +bool Debugger::Cmd_WalkRegions(int argc, const char **argv) { + if (argc != 1) { + DebugPrintf("Usage: %s\n", argv[0]); + return true; + } + + // Colour index to use for the first walk region + int colour = 16; + + // Lock the background surface for access + Graphics::Surface destSurface = _globals->_sceneManager._scene->_backSurface.lockSurface(); + + // Loop through drawing each walk region in a different colour to the background surface + for (uint regionIndex = 0; regionIndex < _globals->_walkRegions._regionList.size(); ++regionIndex, ++colour) { + WalkRegion &wr = _globals->_walkRegions._regionList[regionIndex]; + + for (int yp = wr._bounds.top; yp < wr._bounds.bottom; ++yp) { + LineSliceSet sliceSet = wr.getLineSlices(yp); + + for (uint idx = 0; idx < sliceSet.items.size(); ++idx) + destSurface.hLine(sliceSet.items[idx].xs - _globals->_sceneOffset.x, yp, + sliceSet.items[idx].xe - _globals->_sceneOffset.x, colour); + } + } + + // Release the surface + _globals->_sceneManager._scene->_backSurface.unlockSurface(); + + // Mark the scene as requiring a full redraw + _globals->_paneRefreshFlag[0] = 2; + + return false; +} + +/* + * This command draws the priority regions onto the screen + */ +bool Debugger::Cmd_PriorityRegions(int argc, const char **argv) { + int regionNum = 0; + + // Check for an optional specific region to display + if (argc == 2) + regionNum = strToInt(argv[1]); + + // Colour index to use for the first priority region + int colour = 16; + int count = 0; + + // Lock the background surface for access + Graphics::Surface destSurface = _globals->_sceneManager._scene->_backSurface.lockSurface(); + + List<Region>::iterator i = _globals->_sceneManager._scene->_priorities.begin(); + Common::String regionsDesc; + + for (; i != _globals->_sceneManager._scene->_priorities.end(); ++i, ++colour, ++count) { + Region &r = *i; + + if ((regionNum == 0) || (regionNum == (count + 1))) { + for (int y = 0; y < destSurface.h; ++y) { + byte *destP = (byte *)destSurface.getBasePtr(0, y); + + for (int x = 0; x < destSurface.w; ++x) { + if (r.contains(Common::Point(_globals->_sceneManager._scene->_sceneBounds.left + x, + _globals->_sceneManager._scene->_sceneBounds.top + y))) + *destP = colour; + ++destP; + } + } + } + + regionsDesc += Common::String::format("Region Priority = %d bounds=%d,%d,%d,%d\n", + r._regionId, r._bounds.left, r._bounds.top, r._bounds.right, r._bounds.bottom); + } + + // Release the surface + _globals->_sceneManager._scene->_backSurface.unlockSurface(); + + // Mark the scene as requiring a full redraw + _globals->_paneRefreshFlag[0] = 2; + + DebugPrintf("Total regions = %d\n", count); + DebugPrintf("%s", regionsDesc.c_str()); + + return true; +} + +/** + * Give a specified item to the player + */ +bool Debugger::Cmd_Item(int argc, const char **argv) { + _globals->_inventory._infoDisk._sceneNumber = 1; + return true; +} + +} // End of namespace tSage diff --git a/engines/tsage/debugger.h b/engines/tsage/debugger.h new file mode 100644 index 0000000000..348d2cb821 --- /dev/null +++ b/engines/tsage/debugger.h @@ -0,0 +1,48 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/debugger.h $ + * $Id: debugger.h 176 2011-01-25 11:33:33Z dreammaster $ + * + */ + +#ifndef TSAGE_DEBUGGER_H +#define TSAGE_DEBUGGER_H + +#include "common/scummsys.h" +#include "gui/debugger.h" + +namespace tSage { + +class Debugger : public GUI::Debugger { +public: + Debugger(); + virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ + +protected: + bool Cmd_Scene(int argc, const char **argv); + bool Cmd_WalkRegions(int argc, const char **argv); + bool Cmd_PriorityRegions(int argc, const char **argv); + bool Cmd_Item(int argc, const char **argv); +}; + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/detection.cpp b/engines/tsage/detection.cpp new file mode 100644 index 0000000000..f2e61b0f84 --- /dev/null +++ b/engines/tsage/detection.cpp @@ -0,0 +1,186 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/detection.cpp $ + * $Id: detection.cpp 209 2011-02-06 00:46:36Z dreammaster $ + * + */ + +#include "common/config-manager.h" +#include "common/system.h" +#include "common/savefile.h" + +#include "engines/advancedDetector.h" + +#include "base/plugins.h" + +#include "tsage/tsage.h" + +namespace tSage { + +struct tSageGameDescription { + ADGameDescription desc; + + int gameID; + uint32 features; +}; + +const char *TSageEngine::getGameId() const { + return _gameDescription->desc.gameid; +} + +uint32 TSageEngine::getGameID() const { + return _gameDescription->gameID; +} + +uint32 TSageEngine::getFeatures() const { + return _gameDescription->features; +} + +} // End of namespace tSage + +static const PlainGameDescriptor tSageGameTitles[] = { + { "tsage", "Unknown Tsunami TSAGE-based Game" }, + { "ring", "Ringworld: Revenge of the Patriarch" }, + { "blueforce", "Blue Force" }, + { 0, 0 } +}; + +#include "engines/tsage/detection_tables.h" + +static const ADParams detectionParams = { + (const byte *)tSage::gameDescriptions, + sizeof(tSage::tSageGameDescription), + 0, + tSageGameTitles, + 0, + "tsage", + NULL, + NULL, + Common::GUIO_NONE, + 0, + NULL +}; + +#define MAX_SAVES 100 + +class TSageMetaEngine : public AdvancedMetaEngine { +public: + TSageMetaEngine() : AdvancedMetaEngine(detectionParams) { + } + + virtual const char *getName() const { + return "TsAGE Engine"; + } + + virtual const char *getOriginalCopyright() const { + return "(c) Tsunami Media"; + } + + virtual bool hasFeature(MetaEngineFeature f) const { + switch (f) { + case kSupportsListSaves: + case kSupportsDeleteSave: + case kSupportsLoadingDuringStartup: + case kSavesSupportMetaInfo: + case kSavesSupportThumbnail: + case kSavesSupportCreationDate: + case kSavesSupportPlayTime: + return true; + default: + return false; + } + } + + virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { + if (desc) { + *engine = new tSage::TSageEngine(syst, (const tSage::tSageGameDescription *)desc); + } + return desc != 0; + } + + static Common::String generateGameStateFileName(const char *target, int slot) { + return Common::String::format("%s.%03d", target, slot); + } + + virtual SaveStateList listSaves(const char *target) const { + Common::String pattern = target; + pattern += ".*"; + + Common::StringArray filenames = g_system->getSavefileManager()->listSavefiles(pattern); + tSage::tSageSavegameHeader header; + + SaveStateList saveList; + for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { + int slot; + const char *ext = strrchr(file->c_str(), '.'); + if (ext && (slot = atoi(ext + 1)) >= 0 && slot < MAX_SAVES) { + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); + + if (in) { + if (tSage::Saver::readSavegameHeader(in, header)) { + saveList.push_back(SaveStateDescriptor(slot, header.saveName)); + delete header.thumbnail; + } + + delete in; + } + } + } + + return saveList; + } + + virtual int getMaximumSaveSlot() const { + return MAX_SAVES - 1; + } + + virtual void removeSaveState(const char *target, int slot) const { + Common::String filename = Common::String::format("%s.%03d", target, slot); + g_system->getSavefileManager()->removeSavefile(filename); + } + + SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const { + Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading( + generateGameStateFileName(target, slot)); + assert(f); + + tSage::tSageSavegameHeader header; + tSage::Saver::readSavegameHeader(f, header); + delete f; + + // Create the return descriptor + SaveStateDescriptor desc(slot, header.saveName); + desc.setDeletableFlag(true); + desc.setWriteProtectedFlag(false); + desc.setThumbnail(header.thumbnail); + desc.setSaveDate(header.saveYear, header.saveMonth, header.saveDay); + desc.setSaveTime(header.saveHour, header.saveMinutes); + desc.setPlayTime(header.totalFrames * GAME_FRAME_TIME); + + return desc; + } +}; + +#if PLUGIN_ENABLED_DYNAMIC(TSAGE) +REGISTER_PLUGIN_DYNAMIC(TSAGE, PLUGIN_TYPE_ENGINE, TSageMetaEngine); +#else +REGISTER_PLUGIN_STATIC(TSAGE, PLUGIN_TYPE_ENGINE, TSageMetaEngine); +#endif diff --git a/engines/tsage/detection_tables.h b/engines/tsage/detection_tables.h new file mode 100644 index 0000000000..429d6aecdb --- /dev/null +++ b/engines/tsage/detection_tables.h @@ -0,0 +1,91 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +namespace tSage { + +static const tSageGameDescription gameDescriptions[] = { + + // Ringworld English CD version + { + { + "ring", + "CD", + AD_ENTRY1s("ring.rlb", "466f0e6492d9d0f34d35c5cd088de90f", 37847618), + Common::EN_ANY, + Common::kPlatformPC, + ADGF_NO_FLAGS, + Common::GUIO_NONE + }, + GType_Ringworld, + GF_CD + }, + // Ringworld First Wave English CD version + { + { + "ring", + "CD", + AD_ENTRY1s("ring.rlb", "0a25b4ee58d44a54425c0b47e5096bbc", 37847618), + Common::EN_ANY, + Common::kPlatformPC, + ADGF_NO_FLAGS, + Common::GUIO_NONE + }, + GType_Ringworld, + GF_CD + }, + // Ringworld English Floppy version + { + { + "ring", + "Floppy", + AD_ENTRY1s("ring.rlb", "61f78f68a56832ae95fe06748c403234", 8438770), + Common::EN_ANY, + Common::kPlatformPC, + ADGF_NO_FLAGS, + Common::GUIO_NONE + }, + GType_Ringworld, + GF_FLOPPY + }, + + // Blue Force + { + { + "blueforce", + "", + AD_ENTRY1s("blue.rlb", "467da43c848cc0e800b547c59d84ccb1", 10032614), + Common::EN_ANY, + Common::kPlatformPC, + ADGF_NO_FLAGS, + Common::GUIO_NONE + }, + GType_BlueForce, + GF_FLOPPY + }, + + { AD_TABLE_END_MARKER, 0, 0 } +}; + +} // End of namespace tSage diff --git a/engines/tsage/dialogs.cpp b/engines/tsage/dialogs.cpp new file mode 100644 index 0000000000..2ab06b44e7 --- /dev/null +++ b/engines/tsage/dialogs.cpp @@ -0,0 +1,598 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/dialogs.cpp $ + * $Id: dialogs.cpp 215 2011-02-07 12:06:13Z dreammaster $ + * + */ + +#include "common/translation.h" +#include "tsage/tsage.h" +#include "tsage/core.h" +#include "tsage/dialogs.h" +#include "tsage/graphics.h" +#include "tsage/core.h" +#include "tsage/staticres.h" +#include "tsage/globals.h" + +namespace tSage { + +/*--------------------------------------------------------------------------*/ + +/** + * This dialog class provides a simple message display with support for either one or two buttons. + */ +MessageDialog::MessageDialog(const Common::String &message, const Common::String &btn1Message, + const Common::String &btn2Message): GfxDialog() { + // Set up the message + addElements(&_msg, &_btn1, NULL); + + _msg.set(message, 200, ALIGN_LEFT); + _btn1._bounds.moveTo(_msg._bounds.left, _msg._bounds.bottom + 2); + _defaultButton = &_btn1; + + // Set up the first button + _btn1.setText(btn1Message); + _btn1._bounds.moveTo(_msg._bounds.right - _btn1._bounds.width(), _msg._bounds.bottom); + + if (!btn2Message.empty()) { + // Set up the second button + _defaultButton = &_btn2; + add(&_btn2); + _btn2.setText(btn2Message); + _btn2._bounds.moveTo(_msg._bounds.right - _btn2._bounds.width(), _msg._bounds.bottom); + _btn1._bounds.translate(-(_btn2._bounds.width() + 4), 0); + } + + // Do post setup for the dialog + setDefaults(); + + // Set the dialog's centre + setCentre(_globals->_dialogCentre.x, _globals->_dialogCentre.y); +} + +int MessageDialog::show(const Common::String &message, const Common::String &btn1Message, const Common::String &btn2Message) { + // Ensure that the cursor is the arrow + CursorType currentCursor = _globals->_events.getCursor(); + if (currentCursor != CURSOR_ARROW) + _globals->_events.setCursor(CURSOR_ARROW); + _globals->_events.showCursor(); + + int result = show2(message, btn1Message, btn2Message); + + // If the cursor was changed, change it back + if (currentCursor != CURSOR_ARROW) + _globals->_events.setCursor(currentCursor); + + return result; +} + +int MessageDialog::show2(const Common::String &message, const Common::String &btn1Message, const Common::String &btn2Message) { + MessageDialog *dlg = new MessageDialog(message, btn1Message, btn2Message); + dlg->draw(); + + GfxButton *selectedButton = dlg->execute(); + int result = (selectedButton == &dlg->_btn1) ? 0 : 1; + + delete dlg; + return result; +} + + +/*--------------------------------------------------------------------------*/ + +ConfigDialog::ConfigDialog(): GUI::OptionsDialog("", "GlobalConfig") { + // + // Sound controllers + // + + addVolumeControls(this, "GlobalConfig."); + setVolumeSettingsState(true); // could disable controls by GUI options + + // + // Add the buttons + // + + new GUI::ButtonWidget(this, "GlobalConfig.Ok", _("~O~K"), 0, GUI::kOKCmd); + new GUI::ButtonWidget(this, "GlobalConfig.Cancel", _("~C~ancel"), 0, GUI::kCloseCmd); +} + +/*--------------------------------------------------------------------------*/ + +#define BUTTON_WIDTH 28 +#define BUTTON_HEIGHT 29 + +RightClickButton::RightClickButton(int buttonIndex, int xp, int yp): GfxButton() { + _buttonIndex = buttonIndex; + this->_bounds.left = xp; + this->_bounds.top = yp; + this->_bounds.setWidth(BUTTON_WIDTH); + this->_bounds.setHeight(BUTTON_HEIGHT); + _savedButton = NULL; +} + +void RightClickButton::highlight() { + if (_savedButton) { + // Button was previously highlighted, so de-highlight by restoring saved area + _globals->gfxManager().copyFrom(*_savedButton, _bounds.left, _bounds.top); + delete _savedButton; + _savedButton = NULL; + } else { + // Highlight button by getting the needed highlighted image resource + _savedButton = Surface_getArea(_globals->gfxManager().getSurface(), _bounds); + + uint size; + byte *imgData = _vm->_dataManager->getSubResource(7, 2, _buttonIndex, &size); + + GfxSurface btnSelected = surfaceFromRes(imgData); + _globals->gfxManager().copyFrom(btnSelected, _bounds.left, _bounds.top); + + DEALLOCATE(imgData); + } +} + +/*--------------------------------------------------------------------------*/ + +/** + * This dialog implements the right-click dialog + */ +RightClickDialog::RightClickDialog(): GfxDialog(), + _walkButton(1, 48, 12), _lookButton(2, 31, 29), _useButton(3, 65, 29), + _talkButton(4, 14, 47), _inventoryButton(5, 48, 47), _optionsButton(6, 83, 47) { + Rect rectArea, dialogRect; + + // Set the palette and change the cursor + _gfxManager.setDialogPalette(); + _globals->_events.setCursor(CURSOR_ARROW); + + // Get the dialog image + _surface = surfaceFromRes(7, 1, 1); + + // Set the dialog position + dialogRect.resize(_surface, 0, 0, 100); + dialogRect.centre(_globals->_events._mousePos.x, _globals->_events._mousePos.y); + + // Ensure the dialog will be entirely on-screen + Rect screenRect = _globals->gfxManager()._bounds; + screenRect.collapse(4, 4); + dialogRect.contain(screenRect); + + _bounds = dialogRect; + _gfxManager._bounds = _bounds; + + _highlightedButton = NULL; + _selectedAction = -1; +} + +RightClickDialog::~RightClickDialog() { +} + +RightClickButton *RightClickDialog::findButton(const Common::Point &pt) { + RightClickButton *btnList[] = { &_walkButton, &_lookButton, &_useButton, &_talkButton, &_inventoryButton, &_optionsButton }; + + for (int i = 0; i < 6; ++i) { + btnList[i]->_owner = this; + + if (btnList[i]->_bounds.contains(pt)) + return btnList[i]; + } + + return NULL; +} + +void RightClickDialog::draw() { + // Save the covered background area + _savedArea = Surface_getArea(_globals->_gfxManagerInstance.getSurface(), _bounds); + + // Draw the dialog image + _globals->gfxManager().copyFrom(_surface, _bounds.left, _bounds.top); +} + +bool RightClickDialog::process(Event &event) { + switch (event.eventType) { + case EVENT_MOUSE_MOVE: { + // Check whether a button is highlighted + RightClickButton *btn = findButton(event.mousePos); + + if (btn != _highlightedButton) { + // De-highlight any previously selected button + if (_highlightedButton) { + _highlightedButton->highlight(); + _highlightedButton = NULL; + } + if (btn) { + // Highlight the new button + btn->highlight(); + _highlightedButton = btn; + } + } + event.handled = true; + return true; + } + + case EVENT_BUTTON_DOWN: + // If a button is highlighted, then flag the selected button index + if (_highlightedButton) + _selectedAction = _highlightedButton->_buttonIndex; + else + _selectedAction = _lookButton._buttonIndex; + event.handled = true; + return true; + + default: + break; + } + + return false; +} + +void RightClickDialog::execute() { + // Draw the dialog + draw(); + + // Dialog event handler loop + _gfxManager.activate(); + + while (!_vm->getEventManager()->shouldQuit() && (_selectedAction == -1)) { + Event evt; + while (_globals->_events.getEvent(evt, EVENT_MOUSE_MOVE | EVENT_BUTTON_DOWN)) { + evt.mousePos.x -= _bounds.left; + evt.mousePos.y -= _bounds.top; + + process(evt); + } + + g_system->delayMillis(10); + g_system->updateScreen(); + } + + // Execute the specified action + switch (_selectedAction) { + case 1: + // Look action + _globals->_events.setCursor(CURSOR_LOOK); + break; + case 2: + // Walk action + _globals->_events.setCursor(CURSOR_WALK); + break; + case 3: + // Use cursor + _globals->_events.setCursor(CURSOR_USE); + break; + case 4: + // Talk cursor + _globals->_events.setCursor(CURSOR_TALK); + break; + case 5: + // Inventory dialog + InventoryDialog::show(); + break; + case 6: + // Dialog options + OptionsDialog::show(); + break; + } + + _gfxManager.deactivate(); +} + +/*--------------------------------------------------------------------------*/ + +void ModalDialog::draw() { + // Set the palette for use in the dialog + setPalette(); + + // Make a backup copy of the area the dialog will occupy + Rect tempRect = _bounds; + tempRect.collapse(-10, -10); + _savedArea = Surface_getArea(_globals->_gfxManagerInstance.getSurface(), tempRect); + + _gfxManager.activate(); + + // Fill in the contents of the entire dialog + _gfxManager._bounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + drawFrame(); + + // Draw each element in the dialog in order + GfxElementList::iterator i; + for (i = _elements.begin(); i != _elements.end(); ++i) { + (*i)->draw(); + } + + _gfxManager.deactivate(); +} + +void ModalDialog::drawFrame() { + Rect origRect = _bounds; + _bounds.collapse(-10, -10); + + // Fill the dialog area + _globals->gfxManager().fillRect(origRect, 54); + + // Draw top line + GfxSurface surface = surfaceFromRes(8, 1, 7); + for (int xp = _bounds.left + 10; xp < (_bounds.right - 20); xp += 10) + surface.draw(Common::Point(xp, _bounds.top)); + surface.draw(Common::Point(_bounds.right - 20, _bounds.top)); + + surface = surfaceFromRes(8, 1, 1); + surface.draw(Common::Point(_bounds.left, _bounds.top)); + + surface = surfaceFromRes(8, 1, 4); + surface.draw(Common::Point(_bounds.right - 10, _bounds.top)); + + // Draw vertical edges + surface = surfaceFromRes(8, 1, 2); + for (int yp = _bounds.top + 10; yp < (_bounds.bottom - 20); yp += 10) + surface.draw(Common::Point(_bounds.left, yp)); + surface.draw(Common::Point(_bounds.left, _bounds.bottom - 20)); + + surface = surfaceFromRes(8, 1, 5); + for (int yp = _bounds.top + 10; yp < (_bounds.bottom - 20); yp += 10) + surface.draw(Common::Point(_bounds.right - 10, yp)); + surface.draw(Common::Point(_bounds.right - 10, _bounds.bottom - 20)); + + // Draw bottom line + surface = surfaceFromRes(8, 1, 8); + for (int xp = _bounds.left + 10; xp < (_bounds.right - 20); xp += 10) + surface.draw(Common::Point(xp, _bounds.bottom - 10)); + surface.draw(Common::Point(_bounds.right - 20, _bounds.bottom - 10)); + + surface = surfaceFromRes(8, 1, 3); + surface.draw(Common::Point(_bounds.left, _bounds.bottom - 10)); + + surface = surfaceFromRes(8, 1, 6); + surface.draw(Common::Point(_bounds.right - 10, _bounds.bottom - 10)); + + // Set the dialog's manager bounds + _gfxManager._bounds = origRect; +} + +/*--------------------------------------------------------------------------*/ + +bool GfxInvImage::process(Event &event) { + if (!event.handled && (event.eventType == EVENT_BUTTON_DOWN)) { + event.handled = _bounds.contains(event.mousePos); + return event.handled; + } + + return false; +} + +/*--------------------------------------------------------------------------*/ + +void InventoryDialog::show(bool allFlag) { + if (!allFlag) { + // Determine how many items are in the player's inventory + int itemCount = 0; + List<InvObject *>::iterator i; + for (i = _globals->_inventory._itemList.begin(); i != _globals->_inventory._itemList.end(); ++i) { + if ((*i)->inInventory()) + ++itemCount; + } + + if (itemCount == 0) { + MessageDialog::show(INV_EMPTY_MSG, OK_BTN_STRING); + return; + } + } + + InventoryDialog *dlg = new InventoryDialog(allFlag); + dlg->draw(); + dlg->execute(); + delete dlg; +} + +InventoryDialog::InventoryDialog(bool allFlag) { + // Determine the maximum size of the image of any item in the player's inventory + int imgWidth = 0, imgHeight = 0; + + List<InvObject *>::iterator i; + for (i = _globals->_inventory._itemList.begin(); i != _globals->_inventory._itemList.end(); ++i) { + InvObject *invObject = *i; + if (allFlag || invObject->inInventory()) { + // Get the image for the item + GfxSurface itemSurface = surfaceFromRes(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum); + + // Maintain the dimensions of the largest item image + imgWidth = MAX(imgWidth, (int)itemSurface.getBounds().width()); + imgHeight = MAX(imgHeight, (int)itemSurface.getBounds().height()); + + // Add the item to the display list + _images.push_back(GfxInvImage()); + _images[_images.size() - 1].setDetails(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum); + _images[_images.size() - 1]._invObject = invObject; + add(&_images[_images.size() - 1]); + } + } + assert(_images.size() > 0); + + // Figure out the number of columns/rows to show all the items + int cellsSize = 3; + while ((cellsSize * cellsSize) < (int)_images.size()) + ++cellsSize; + + // Set the position of each inventory item to be displayed + int cellX = 0; + Common::Point pt(0, 0); + + for (uint idx = 0; idx < _images.size(); ++idx) { + if (cellX == cellsSize) { + // Move to the start of the next line + pt.x = 0; + pt.y += imgHeight + 2; + cellX = 0; + } + + _images[idx]._bounds.moveTo(pt.x, pt.y); + + pt.x += imgWidth + 2; + ++cellX; + } + + // Set up the buttons + pt.y += imgHeight + 2; + _btnOk.setText(OK_BTN_STRING); + _btnOk._bounds.moveTo((imgWidth + 2) * cellsSize - _btnOk._bounds.width(), pt.y); + _btnLook.setText(LOOK_BTN_STRING); + _btnLook._bounds.moveTo(_btnOk._bounds.left - _btnLook._bounds.width() - 2, _btnOk._bounds.top); + addElements(&_btnLook, &_btnOk, NULL); + + frame(); + setCentre(SCREEN_CENTRE_X, SCREEN_CENTRE_Y); +} + +void InventoryDialog::execute() { + if ((_globals->_inventory._selectedItem) && _globals->_inventory._selectedItem->inInventory()) + _globals->_inventory._selectedItem->setCursor(); + + GfxElement *hiliteObj; + bool lookFlag = false; + + while (!_vm->getEventManager()->shouldQuit()) { + // Get events + Event event; + while (!_globals->_events.getEvent(event) && !_vm->getEventManager()->shouldQuit()) + ; + if (_vm->getEventManager()->shouldQuit()) + return; + + hiliteObj = NULL; + if ((event.eventType == EVENT_BUTTON_DOWN) && !_bounds.contains(event.mousePos)) + break; + + // Pass event to elements + event.mousePos.x -= _gfxManager._bounds.left; + event.mousePos.y -= _gfxManager._bounds.top; + + for (GfxElementList::iterator i = _elements.begin(); i != _elements.end(); ++i) { + if ((*i)->process(event)) + hiliteObj = *i; + } + + if (!event.handled && event.eventType == EVENT_KEYPRESS) { + if ((event.kbd.keycode == Common::KEYCODE_RETURN) || (event.kbd.keycode == Common::KEYCODE_ESCAPE)) { + // Exit the dialog + hiliteObj = &_btnOk; + break; + } + } + + if (hiliteObj == &_btnOk) { + // Ok button clicked + if (lookFlag) + _globals->_events.setCursor(CURSOR_WALK); + break; + } else if (hiliteObj == &_btnLook) { + // Look button clicked + if (_btnLook._message == LOOK_BTN_STRING) { + _btnLook._message = PICK_BTN_STRING; + lookFlag = 1; + _globals->_events.setCursor(CURSOR_LOOK); + } else { + _btnLook._message = LOOK_BTN_STRING; + lookFlag = 0; + _globals->_events.setCursor(CURSOR_WALK); + } + + _gfxManager.activate(); + hiliteObj->draw(); + _gfxManager.deactivate(); + } else if (hiliteObj) { + // Inventory item selected + InvObject *invObject = static_cast<GfxInvImage *>(hiliteObj)->_invObject; + if (lookFlag) { + _globals->_screenSurface.displayText(invObject->_description); + } else { + _globals->_inventory._selectedItem = invObject; + invObject->setCursor(); + } + } + } +} + +/*--------------------------------------------------------------------------*/ + +void OptionsDialog::show() { + OptionsDialog *dlg = new OptionsDialog(); + dlg->draw(); + + GfxButton *btn = dlg->execute(); + + if (btn == &dlg->_btnQuit) { + // Quit game + if (MessageDialog::show(QUIT_CONFIRM_MSG, CANCEL_BTN_STRING, QUIT_BTN_STRING) == 1) { + _vm->quitGame(); + } + } else if (btn == &dlg->_btnRestart) { + // Restart game + _globals->_game.restartGame(); + } else if (btn == &dlg->_btnSound) { + // Sound dialog + } else if (btn == &dlg->_btnSave) { + // Save button + _globals->_game.saveGame(); + } else if (btn == &dlg->_btnRestore) { + // Restore button + _globals->_game.restoreGame(); + } + + dlg->remove(); + delete dlg; +} + +OptionsDialog::OptionsDialog() { + // Set the element text + _gfxMessage.set(OPTIONS_MSG, 140, ALIGN_LEFT); + _btnRestore.setText(RESTORE_BTN_STRING); + _btnSave.setText(SAVE_BTN_STRING); + _btnRestart.setText(RESTART_BTN_STRING); + _btnQuit.setText(QUIT_BTN_STRING); + _btnSound.setText(SOUND_BTN_STRING); + _btnResume.setText(RESUME_BTN_STRING); + + // Set position of the elements + _gfxMessage._bounds.moveTo(0, 1); + _btnRestore._bounds.moveTo(0, _gfxMessage._bounds.bottom + 1); + _btnSave._bounds.moveTo(0, _btnRestore._bounds.bottom + 1); + _btnRestart._bounds.moveTo(0, _btnSave._bounds.bottom + 1); + _btnQuit._bounds.moveTo(0, _btnRestart._bounds.bottom + 1); + _btnSound._bounds.moveTo(0, _btnQuit._bounds.bottom + 1); + _btnResume._bounds.moveTo(0, _btnSound._bounds.bottom + 1); + + // Set all the buttons to the widest button + GfxButton *btnList[6] = {&_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume}; + int16 btnWidth = 0; + for (int idx = 0; idx < 6; ++idx) + btnWidth = MAX(btnWidth, btnList[idx]->_bounds.width()); + for (int idx = 0; idx < 6; ++idx) + btnList[idx]->_bounds.setWidth(btnWidth); + + // Add the items to the dialog + addElements(&_gfxMessage, &_btnRestore, &_btnSave, &_btnRestart, &_btnQuit, &_btnSound, &_btnResume, NULL); + + // Set the dialog size and position + frame(); + setCentre(160, 100); +} + + +} // End of namespace tSage diff --git a/engines/tsage/dialogs.h b/engines/tsage/dialogs.h new file mode 100644 index 0000000000..0fece89781 --- /dev/null +++ b/engines/tsage/dialogs.h @@ -0,0 +1,136 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/dialogs.h $ + * $Id: dialogs.h 215 2011-02-07 12:06:13Z dreammaster $ + * + */ + +#ifndef TSAGE_DIALOGS_H +#define TSAGE_DIALOGS_H + +#include "gui/options.h" +#include "tsage/events.h" +#include "tsage/graphics.h" +#include "common/list.h" +#include "common/rect.h" +#include "common/system.h" + +namespace tSage { + +class MessageDialog: public GfxDialog { +public: + GfxButton _btn1, _btn2; + GfxDialog _dialog; + GfxMessage _msg; +public: + MessageDialog(const Common::String &message, const Common::String &btn1Message, const Common::String &btn2Message = Common::String()); + + static int show(const Common::String &message, const Common::String &btn1Message, const Common::String &btn2Message = Common::String()); + static int show2(const Common::String &message, const Common::String &btn1Message, const Common::String &btn2Message = Common::String()); +}; + +class ConfigDialog : public GUI::OptionsDialog { +public: + ConfigDialog(); +}; + +class RightClickButton: public GfxButton { +private: + GfxSurface *_savedButton; +public: + int _buttonIndex; + + RightClickButton(int buttonIndex, int xp, int yp); + ~RightClickButton() { delete _savedButton; } + + virtual void highlight(); +}; + +class RightClickDialog: public GfxDialog { +private: + GfxSurface _surface; + RightClickButton *_highlightedButton; + int _selectedAction; + RightClickButton _walkButton, _lookButton, _useButton, _talkButton, _inventoryButton, _optionsButton; + + RightClickButton *findButton(const Common::Point &pt); +public: + RightClickDialog(); + ~RightClickDialog(); + + virtual void draw(); + virtual bool process(Event &event); + void execute(); +}; + +/*--------------------------------------------------------------------------*/ + +class ModalDialog: public GfxDialog { +protected: + void drawFrame(); +public: + virtual void draw(); +}; + +/*--------------------------------------------------------------------------*/ + +class GfxInvImage: public GfxImage { +public: + InvObject *_invObject; +public: + GfxInvImage(): GfxImage(), _invObject(NULL) {} + + virtual bool process(Event &event); +}; + +#define MAX_INVOBJECT_DISPLAY 20 + +class InventoryDialog: public ModalDialog { +private: + Common::Array<GfxInvImage> _images; + GfxButton _btnOk, _btnLook; +public: + InventoryDialog(bool allFlag = false); + virtual ~InventoryDialog() {} + void execute(); + + static void show(bool allFlag = false); +}; + +/*--------------------------------------------------------------------------*/ + +class OptionsDialog: public ModalDialog { +private: + GfxButton _btnSave, _btnRestore, _btnRestart; + GfxButton _btnQuit, _btnResume; + GfxButton _btnSound; + GfxMessage _gfxMessage; +public: + OptionsDialog(); + virtual ~OptionsDialog() {} + GfxButton *execute() { return GfxDialog::execute(&_btnResume); } + + static void show(); +}; + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp new file mode 100644 index 0000000000..7b02683226 --- /dev/null +++ b/engines/tsage/events.cpp @@ -0,0 +1,247 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/events.cpp $ + * $Id: events.cpp 224 2011-02-10 10:58:52Z dreammaster $ + * + */ + +#include "common/events.h" +#include "common/singleton.h" +#include "graphics/cursorman.h" +#include "common/system.h" + +#include "tsage/events.h" +#include "tsage/core.h" +#include "tsage/staticres.h" +#include "tsage/tsage.h" +#include "tsage/globals.h" + +namespace tSage { + +EventsClass::EventsClass() { + _currentCursor = CURSOR_NONE; + _frameNumber = 0; + _priorFrameTime = 0; + _prevDelayFrame = 0; + _saver->addListener(this); +} + +bool EventsClass::pollEvent() { + uint32 milli = g_system->getMillis(); + if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) { + _priorFrameTime = milli; + ++_frameNumber; + + g_system->updateScreen(); + } + + if (!g_system->getEventManager()->pollEvent(_event)) return false; + + // Handle keypress + switch (_event.type) { + case Common::EVENT_QUIT: + case Common::EVENT_RTL: + break; + + case Common::EVENT_MOUSEMOVE: + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONDOWN: + case Common::EVENT_RBUTTONUP: + // Keep a copy of the current mouse position + _mousePos = _event.mouse; + break; + + default: + break; + } + + return true; +} + +void EventsClass::waitForPress(int eventMask) { + Event evt; + while (!_vm->getEventManager()->shouldQuit() && !getEvent(evt, eventMask)) + g_system->delayMillis(10); +} + +/** + * Standard event retrieval, which only returns keyboard and mouse clicks + */ +bool EventsClass::getEvent(Event &evt, int eventMask) { + while (pollEvent() && !_vm->getEventManager()->shouldQuit()) { + evt.handled = false; + evt.eventType = EVENT_NONE; + evt.mousePos = _event.mouse; + evt.kbd = _event.kbd; + + switch (_event.type) { + case Common::EVENT_MOUSEMOVE: + evt.eventType = EVENT_MOUSE_MOVE; + break; + case Common::EVENT_LBUTTONDOWN: + evt.eventType = EVENT_BUTTON_DOWN; + evt.btnState = BTNSHIFT_LEFT; + break; + case Common::EVENT_RBUTTONDOWN: + evt.eventType = EVENT_BUTTON_DOWN; + evt.btnState = BTNSHIFT_RIGHT; + break; + case Common::EVENT_MBUTTONDOWN: + evt.eventType = EVENT_BUTTON_DOWN; + evt.btnState = BTNSHIFT_MIDDLE; + break; + case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONUP: + case Common::EVENT_MBUTTONUP: + evt.eventType = EVENT_BUTTON_UP; + evt.btnState = 0; + break; + case Common::EVENT_KEYDOWN: + evt.eventType = EVENT_KEYPRESS; + evt.kbd = _event.kbd; + break; + default: + break; + } + + if (evt.eventType & eventMask) + return true; + } + + return false; +} + +/** + * Sets the specified cursor + * + * @cursorType Specified cursor number + */ +void EventsClass::setCursor(CursorType cursorType) { + _globals->clearFlag(122); + + if ((_currentCursor == cursorType) && CursorMan.isVisible()) + return; + + if (cursorType == CURSOR_NONE) { + if (CursorMan.isVisible()) + CursorMan.showMouse(false); + return; + } + + CursorMan.showMouse(true); + + const byte *cursor; + bool delFlag = true; + uint size; + + switch (cursorType) { + case CURSOR_CROSSHAIRS: + // Crosshairs cursor + cursor = _vm->_dataManager->getSubResource(4, 1, 6, &size); + _globals->setFlag(122); + break; + + case CURSOR_LOOK: + // Look cursor + cursor = _vm->_dataManager->getSubResource(4, 1, 5, &size); + _currentCursor = CURSOR_LOOK; + break; + + case CURSOR_USE: + // Use cursor + cursor = _vm->_dataManager->getSubResource(4, 1, 4, &size); + _currentCursor = CURSOR_USE; + break; + + case CURSOR_TALK: + // Talk cursor + cursor = _vm->_dataManager->getSubResource(4, 1, 3, &size); + _currentCursor = CURSOR_TALK; + break; + + case CURSOR_ARROW: + // Arrow cursor + cursor = CURSOR_ARROW_DATA; + delFlag = false; + break; + + case CURSOR_WALK: + default: + // Walk cursor + cursor = CURSOR_WALK_DATA; + _currentCursor = CURSOR_WALK; + delFlag = false; + break; + } + + // Decode the cursor + GfxSurface s = surfaceFromRes(cursor); + + Graphics::Surface surface = s.lockSurface(); + const byte *cursorData = (const byte *)surface.getBasePtr(0, 0); + CursorMan.replaceCursor(cursorData, surface.w, surface.h, s._centroid.x, s._centroid.y, s._transColour); + s.unlockSurface(); + + if (delFlag) + DEALLOCATE(cursor); +} + +void EventsClass::setCursor(Graphics::Surface &cursor, int transColour, const Common::Point &hotspot, CursorType cursorId) { + const byte *cursorData = (const byte *)cursor.getBasePtr(0, 0); + CursorMan.replaceCursor(cursorData, cursor.w, cursor.h, hotspot.x, hotspot.y, transColour); + + _currentCursor = cursorId; +} + +void EventsClass::setCursorFromFlag() { + setCursor(_globals->getFlag(122) ? CURSOR_CROSSHAIRS : _currentCursor); +} + +void EventsClass::showCursor() { + CursorMan.showMouse(true); +} + +void EventsClass::hideCursor() { + CursorMan.showMouse(false); +} + +/** + * Delays the game for the specified number of frames, if necessary, from the + * previous time the delay method was called + */ +void EventsClass::delay(int numFrames) { + while (_frameNumber < (_prevDelayFrame + numFrames)) { + uint32 delayAmount = CLIP(_priorFrameTime + GAME_FRAME_TIME - g_system->getMillis(), + (uint32)0, (uint32)GAME_FRAME_TIME); + if (delayAmount > 0) + g_system->delayMillis(delayAmount); + + ++_frameNumber; + _priorFrameTime = g_system->getMillis(); + } + + g_system->updateScreen(); + _prevDelayFrame = _frameNumber; + _priorFrameTime = g_system->getMillis(); +} + +} // end of namespace tSage diff --git a/engines/tsage/events.h b/engines/tsage/events.h new file mode 100644 index 0000000000..d8f58a4ce2 --- /dev/null +++ b/engines/tsage/events.h @@ -0,0 +1,109 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/events.h $ + * $Id: events.h 212 2011-02-06 10:19:01Z dreammaster $ + * + */ + +#ifndef TSAGE_EVENTS_H +#define TSAGE_EVENTS_H + +#include "common/events.h" +#include "common/array.h" +#include "common/str.h" +#include "graphics/surface.h" +#include "tsage/saveload.h" + +namespace tSage { + +enum EventType {EVENT_NONE = 0, EVENT_BUTTON_DOWN = 1, EVENT_BUTTON_UP = 2, EVENT_KEYPRESS = 4, + EVENT_MOUSE_MOVE = 8}; + +enum ButtonShiftFlags {BTNSHIFT_LEFT = 0, BTNSHIFT_RIGHT = 3, BTNSHIFT_MIDDLE = 4}; + +// Intrinisc game delay between execution frames. This runs at 60Hz +#define GAME_FRAME_TIME (1000 / 60) + +class GfxManager; + +class Event { +public: + EventType eventType; + Common::Point mousePos; + int btnState; + Common::KeyState kbd; + int ctr; + GfxManager *gfxMan; + bool handled; +}; + +enum CursorType { + OBJECT_STUNNER = 0, OBJECT_SCANNER = 1, OBJECT_STASIS_BOX = 2, + OBJECT_INFODISK = 3, OBJECT_STASIS_NEGATOR = 4, OBJECT_KEY_DEVICE = 5, OBJECT_MEDKIT = 6, + OBJECT_LADDER = 7, OBJECT_ROPE = 8, OBJECT_KEY = 9, OBJECT_TRANSLATOR = 10, OBJECT_ALE = 11, + OBJECT_PAPER = 12, OBJECT_WALDOS = 13, OBJECT_STASIS_BOX2 = 14, OBJECT_RING = 15, + OBJECT_CLOAK = 16, OBJECT_TUNIC = 17, OBJECT_CANDLE = 18, OBJECT_STRAW = 19, OBJECT_SCIMITAR = 20, + OBJECT_SWORD = 21, OBJECT_HELMET = 22, OBJECT_ITEMS = 23, OBJECT_CONCENTRATOR = 24, + OBJECT_NULLIFIER = 25, OBJECT_PEG = 26, OBJECT_VIAL = 27, OBJECT_JACKET = 28, + OBJECT_TUNIC2 = 29, OBJECT_BONE = 30, OBJECT_EMPTY_JAR = 31, OBJECT_JAR = 32, + + CURSOR_WALK = 0x100, CURSOR_LOOK = 0x200, CURSOR_700 = 700, CURSOR_USE = 0x400, CURSOR_TALK = 0x800, + CURSOR_NONE = -1, CURSOR_CROSSHAIRS = -2, CURSOR_ARROW = -3 +}; + +class EventsClass: public SaveListener { +private: + Common::Event _event; + uint32 _frameNumber; + uint32 _prevDelayFrame; + uint32 _priorFrameTime; +public: + EventsClass(); + + Common::Point _mousePos; + CursorType _currentCursor; + + void setCursor(CursorType cursorType); + void setCursor(Graphics::Surface &cursor, int transColour, const Common::Point &hotspot, CursorType cursorId); + void setCursorFromFlag(); + CursorType getCursor() const { return _currentCursor; } + void showCursor(); + void hideCursor(); + + bool pollEvent(); + void waitForPress(int eventMask = EVENT_BUTTON_DOWN | EVENT_KEYPRESS); + + bool getEvent(Event &evt, int eventMask = ~EVENT_MOUSE_MOVE); + Common::Event event() { return _event; } + Common::EventType type() { return _event.type; } + uint32 getFrameNumber() const { return _frameNumber; } + void delay(int numFrames); + + virtual void listenerSynchronise(Serialiser &s) { + s.syncAsUint32LE(_frameNumber); + s.syncAsUint32LE(_prevDelayFrame); + // TODO: Synchronise unknown stuff + } +}; + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp new file mode 100644 index 0000000000..2bf47a3ed7 --- /dev/null +++ b/engines/tsage/globals.cpp @@ -0,0 +1,103 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/globals.cpp $ + * $Id: globals.cpp 229 2011-02-12 06:50:14Z dreammaster $ + * + */ + +#include "tsage/globals.h" + +namespace tSage { + +Globals *_globals = NULL; + +/*--------------------------------------------------------------------------*/ + +/** + * Instantiates a saved object that can be instantiated + */ +static SavedObject *classFactoryProc(const Common::String &className) { + if (className == "ObjectMover") return new ObjectMover(); + if (className == "NpcMover") return new NpcMover(); + if (className == "ObjectMover2") return new ObjectMover2(); + if (className == "ObjectMover3") return new ObjectMover3(); + if (className == "PlayerMover") return new PlayerMover(); + + return NULL; +} + +/*--------------------------------------------------------------------------*/ + +Globals::Globals(): + _dialogCentre(160, 140), + _gfxManagerInstance(_screenSurface) { + reset(); + _stripNum = 0; + _gfxFontNumber = 50; + _gfxColours.background = 53; + _gfxColours.foreground = 18; + _fontColours.background = 51; + _fontColours.foreground = 54; + + _screenSurface.setScreenSurface(); + _gfxManagers.push_back(&_gfxManagerInstance); + + _sceneObjects = &_sceneObjectsInstance; + _sceneObjects_queue.push_front(_sceneObjects); + + _prevSceneOffset = Common::Point(-1, -1); + _sceneListeners.push_back(&_soundHandler); + _sceneListeners.push_back(&_sequenceManager._soundHandler); +} + +Globals::~Globals() { + _globals = NULL; +} + +void Globals::reset() { + Common::set_to(&_flags[0], &_flags[MAX_FLAGS], false); + _saver->addFactory(classFactoryProc); +} + +void Globals::synchronise(Serialiser &s) { + assert(_gfxManagers.size() == 1); + + _sceneItems.synchronise(s); + SYNC_POINTER(_sceneObjects); + _sceneObjects_queue.synchronise(s); + s.syncAsSint32LE(_gfxFontNumber); + s.syncAsSint32LE(_gfxColours.background); + s.syncAsSint32LE(_gfxColours.foreground); + s.syncAsSint32LE(_fontColours.background); + s.syncAsSint32LE(_fontColours.foreground); + + s.syncAsSint16LE(_dialogCentre.x); s.syncAsSint16LE(_dialogCentre.y); + _sceneListeners.synchronise(s); + for (int i = 0; i < 256; ++i) + s.syncAsByte(_flags[i]); + + s.syncAsSint16LE(_sceneOffset.x); s.syncAsSint16LE(_sceneOffset.y); + s.syncAsSint16LE(_prevSceneOffset.x); s.syncAsSint16LE(_prevSceneOffset.y); + SYNC_POINTER(_scrollFollower); + s.syncAsSint32LE(_stripNum); +} + +} // end of namespace tSage diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h new file mode 100644 index 0000000000..1696ae300d --- /dev/null +++ b/engines/tsage/globals.h @@ -0,0 +1,100 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/globals.h $ + * $Id: globals.h 229 2011-02-12 06:50:14Z dreammaster $ + * + */ + +#ifndef TSAGE_GLOBALS_H +#define TSAGE_GLOBALS_H + +#include "common/random.h" +#include "tsage/core.h" +#include "tsage/dialogs.h" +#include "tsage/scenes.h" +#include "tsage/events.h" +#include "tsage/saveload.h" + +namespace tSage { + +class Globals: public SavedObject { +public: + GfxSurface _screenSurface; + GfxManager _gfxManagerInstance; + List<GfxManager *> _gfxManagers; + SceneHandler _sceneHandler; + Game _game; + EventsClass _events; + SceneManager _sceneManager; + ScenePalette _scenePalette; + SceneRegions _sceneRegions; + SceneItemList _sceneItems; + SceneObjectList _sceneObjectsInstance; + SceneObjectList *_sceneObjects; + List<SceneObjectList *> _sceneObjects_queue; + SceneText _sceneText; + int _gfxFontNumber; + GfxColours _gfxColours; + GfxColours _fontColours; + SoundManager _soundManager; + Common::Point _dialogCentre; + WalkRegions _walkRegions; + List<EventHandler *> _sceneListeners; + bool _flags[256]; + Player _player; + SoundHandler _soundHandler; + InvObjectList _inventory; + Region _paneRegions[2]; + int _paneRefreshFlag[2]; + Common::Point _sceneOffset; + Common::Point _prevSceneOffset; + SceneObject *_scrollFollower; + SequenceManager _sequenceManager; + Common::RandomSource _randomSource; + int _stripNum; +public: + Globals(); + ~Globals(); + + void reset(); + void setFlag(int flagNum) { + assert((flagNum > 0) && (flagNum < MAX_FLAGS)); + _flags[flagNum] = true; + } + void clearFlag(int flagNum) { + assert((flagNum > 0) && (flagNum < MAX_FLAGS)); + _flags[flagNum] = false; + } + bool getFlag(int flagNum) const { + assert((flagNum > 0) && (flagNum < MAX_FLAGS)); + return _flags[flagNum]; + } + + GfxManager &gfxManager() { return **_gfxManagers.begin(); } + virtual Common::String getClassName() { return "Globals"; } + virtual void synchronise(Serialiser &s); +}; + +extern Globals *_globals; + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp new file mode 100644 index 0000000000..9a13abcf59 --- /dev/null +++ b/engines/tsage/graphics.cpp @@ -0,0 +1,1430 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/graphics.cpp $ + * $Id: graphics.cpp 225 2011-02-10 11:00:11Z dreammaster $ + * + */ + +#include "tsage/events.h" +#include "tsage/graphics.h" +#include "tsage/resources.h" +#include "tsage/tsage.h" +#include "tsage/core.h" +#include "common/algorithm.h" +#include "graphics/surface.h" +#include "tsage/globals.h" + +namespace tSage { + +/** + * Creates a new graphics surface with the specified area of another surface + * + * @src Source surface + * @bounds Area to backup + */ +GfxSurface *Surface_getArea(GfxSurface &src, const Rect &bounds) { + assert(bounds.isValidRect()); + GfxSurface *dest = new GfxSurface(); + dest->create(bounds.width(), bounds.height()); + + Graphics::Surface srcSurface = src.lockSurface(); + Graphics::Surface destSurface = dest->lockSurface(); + + byte *srcP = (byte *)srcSurface.getBasePtr(bounds.left, bounds.top); + byte *destP = (byte *)destSurface.getBasePtr(0, 0); + + for (int y = bounds.top; y < bounds.bottom; ++y, srcP += srcSurface.pitch, destP += destSurface.pitch) + Common::copy(srcP, srcP + destSurface.pitch, destP); + + src.unlockSurface(); + dest->unlockSurface(); + return dest; +} + +/** + * Translates a raw image resource into a graphics surface. The caller is then responsible + * for managing and destroying the surface when done with it + * + * @imgData Raw image resource + * @size Size of the resource + */ +GfxSurface surfaceFromRes(const byte *imgData) { + Rect r(0, 0, READ_LE_UINT16(imgData), READ_LE_UINT16(imgData + 2)); + GfxSurface s; + s.create(r.width(), r.height()); + s._centroid.x = READ_LE_UINT16(imgData + 4); + s._centroid.y = READ_LE_UINT16(imgData + 6); + s._transColour = *(imgData + 8); + + bool rleEncoded = (imgData[9] & 2) != 0; + + const byte *srcP = imgData + 10; + Graphics::Surface destSurface = s.lockSurface(); + byte *destP = (byte *)destSurface.getBasePtr(0, 0); + + if (!rleEncoded) { + Common::copy(srcP, srcP + (r.width() * r.height()), destP); + } else { + Common::set_to(destP, destP + (r.width() * r.height()), s._transColour); + + for (int yp = 0; yp < r.height(); ++yp) { + int width = r.width(); + destP = (byte *)destSurface.getBasePtr(0, yp); + + while (width > 0) { + uint8 controlVal = *srcP++; + if ((controlVal & 0x80) == 0) { + // Copy specified number of bytes + + Common::copy(srcP, srcP + controlVal, destP); + width -= controlVal; + srcP += controlVal; + destP += controlVal; + } else if ((controlVal & 0x40) == 0) { + // Skip a specified number of output pixels + destP += controlVal & 0x3f; + width -= controlVal & 0x3f; + } else { + // Copy a specified pixel a given number of times + controlVal &= 0x3f; + int pixel = *srcP++; + + Common::set_to(destP, destP + controlVal, pixel); + destP += controlVal; + width -= controlVal; + } + } + assert(width == 0); + } + } + + s.unlockSurface(); + return s; +} + +GfxSurface surfaceFromRes(int resNum, int rlbNum, int subNum) { + uint size; + byte *imgData = _vm->_dataManager->getSubResource(resNum, rlbNum, subNum, &size); + GfxSurface surface = surfaceFromRes(imgData); + DEALLOCATE(imgData); + + return surface; +} +/*--------------------------------------------------------------------------*/ + +void Rect::set(int16 x1, int16 y1, int16 x2, int16 y2) { + left = x1; top = y1; + right = x2; bottom = y2; +} + +/** + * Collapses the rectangle in all four directions by the given x and y amounts + * + * @dx x amount to collapse x edges by + * @dy y amount to collapse y edges by + */ +void Rect::collapse(int dx, int dy) { + left += dx; right -= dx; + top += dy; bottom -= dy; +} + +/** + * Centres the rectangle at a given position + * + * @xp x position for new centre + * @yp y position for new centre + */ +void Rect::centre(int xp, int yp) { + moveTo(xp - (width() / 2), yp - (height() / 2)); +} + +/** + * Centres the rectangle at the centre of a second passed rectangle + * + * @r Second rectangle whose centre to use + */ +void Rect::centre(const Rect &r) { + centre(r.left + (r.width() / 2), r.top + (r.height() / 2)); +} + +/* + * Repositions the bounds if necessary so it falls entirely within the passed bounds + * + * @r The bounds the current rect should be within + */ +void Rect::contain(const Rect &r) { + if (left < r.left) translate(r.left - left, 0); + if (right > r.right) translate(r.right - right, 0); + if (top < r.top) translate(0, r.top - top); + if (bottom > r.bottom) translate(0, r.bottom - bottom); +} + +/** + * Resizes and positions a given rect based on raw image data and a passed scaling percentage + * + * @frame Raw image frame + * @xp New x position + * @yp New y position + * @percent Scaling percentage + */ +void Rect::resize(const GfxSurface &surface, int xp, int yp, int percent) { + int xe = surface.getBounds().width() * percent / 100; + int ye = surface.getBounds().height() * percent / 100; + this->set(0, 0, xe, ye); + + if (!right) ++right; + if (!bottom) ++bottom; + + this->moveTo(xp, yp); + + int xd = surface._centroid.x * percent / 100; + int yd = surface._centroid.y * percent / 100; + this->translate(-xd, -yd); +} + +/** + * Expands the pane region to contain the specified Rect + */ +void Rect::expandPanes() { + _globals->_paneRegions[0].uniteRect(*this); + _globals->_paneRegions[1].uniteRect(*this); +} + +/** + * Serialises the given rect + */ +void Rect::synchronise(Serialiser &s) { + s.syncAsSint16LE(left); + s.syncAsSint16LE(top); + s.syncAsSint16LE(right); + s.syncAsSint16LE(bottom); +} + +/*--------------------------------------------------------------------------*/ + +GfxSurface::GfxSurface(): _bounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) { + _disableUpdates = false; + _screenSurface = false; + _lockSurfaceCtr = 0; + _customSurface = NULL; + _screenSurfaceP = NULL; +} + +GfxSurface::GfxSurface(const GfxSurface &s) { + _lockSurfaceCtr = 0; + _customSurface = NULL; + this->operator =(s); +} + +GfxSurface::~GfxSurface() { + if (_customSurface) { + _customSurface->free(); + delete _customSurface; + } +} + +/** + * Specifies that the surface will encapsulate the ScummVM screen surface + */ +void GfxSurface::setScreenSurface() { + _screenSurface = true; + _customSurface = NULL; + _lockSurfaceCtr = 0; +} + +/** + * Specifies that the surface should maintain it's own internal surface + */ +void GfxSurface::create(int width, int height) { + assert((width >= 0) && (height >= 0)); + _screenSurface = false; + _customSurface = new Graphics::Surface(); + _customSurface->create(width, height, 1); + _bounds = Rect(0, 0, width, height); +} + +/** + * Locks the surface for access, and returns a raw ScummVM surface to manipulate it + */ +Graphics::Surface GfxSurface::lockSurface() { + ++_lockSurfaceCtr; + + Graphics::Surface *src; + if (_screenSurface) { + if (_lockSurfaceCtr == 1) + _screenSurfaceP = g_system->lockScreen(); + src = _screenSurfaceP; + } else + src = _customSurface; + assert(src); + + // Setup the returned surface either as one pointing to the same pixels as the source, or + // as a subset of the source one based on the currently set bounds + Graphics::Surface result; + result.w = _bounds.width(); + result.h = _bounds.height(); + result.pitch = src->pitch; + result.bytesPerPixel = src->bytesPerPixel; + result.pixels = src->getBasePtr(_bounds.left, _bounds.top); + + return result; +} + +/** + * Unlocks the surface after having accessed it with the lockSurface method + */ +void GfxSurface::unlockSurface() { + assert(_lockSurfaceCtr > 0); + --_lockSurfaceCtr; + + if ((_lockSurfaceCtr == 0) && _screenSurface) { + g_system->unlockScreen(); + } +} + +/** + * Fills a specified rectangle on the surface with the specified colour + * + * @bounds Area to fill + * @colour Colour to use + */ +void GfxSurface::fillRect(const Rect &bounds, int colour) { + Graphics::Surface surface = lockSurface(); + surface.fillRect(bounds, colour); + unlockSurface(); +} + +GfxSurface &GfxSurface::operator=(const GfxSurface &s) { + assert(_lockSurfaceCtr == 0); + assert(s._lockSurfaceCtr == 0); + + if (_customSurface) { + _customSurface->free(); + delete _customSurface; + } + + _customSurface = s._customSurface; + _screenSurface = s._screenSurface; + _disableUpdates = s._disableUpdates; + _bounds = s._bounds; + _centroid = s._centroid; + _transColour = s._transColour; + + if (_customSurface) { + // Surface owns the internal data, so replicate it so new surface owns it's own + _customSurface = new Graphics::Surface(); + _customSurface->create(s._customSurface->w, s._customSurface->h, 1); + const byte *srcP = (const byte *)s._customSurface->getBasePtr(0, 0); + byte *destP = (byte *)_customSurface->getBasePtr(0, 0); + + Common::copy(srcP, srcP + (_bounds.width() * _bounds.height()), destP); + } + + return *this; +} + +/** + * Displays a message on-screen until either a mouse or keypress + */ +bool GfxSurface::displayText(const Common::String &msg, const Common::Point &pt) { + // Set up a new graphics manager + GfxManager gfxManager; + gfxManager.activate(); + gfxManager._font._colours.background = 0; + gfxManager._font._colours.foreground = 7; + gfxManager._font.setFontNumber(2); + + // Get the area for text display + Rect textRect; + gfxManager.getStringBounds(msg.c_str(), textRect, 200); + textRect.centre(pt.x, pt.y); + + // Make a backup copy of the area the text will occupy + Rect saveRect = textRect; + saveRect.collapse(-20, -8); + GfxSurface *savedArea = Surface_getArea(gfxManager.getSurface(), saveRect); + + // Display the text + gfxManager._font.writeLines(msg.c_str(), textRect, ALIGN_LEFT); + + // Write for a mouse or keypress + Event event; + while (!_globals->_events.getEvent(event, EVENT_BUTTON_DOWN | EVENT_KEYPRESS) && !_vm->getEventManager()->shouldQuit()) + ; + + // Restore the display area + gfxManager.copyFrom(*savedArea, saveRect.left, saveRect.top); + delete savedArea; + + gfxManager.deactivate(); + return (event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_RETURN); +} + +/** + * Loads a quarter of a screen from a resource + */ +void GfxSurface::loadScreenSection(Graphics::Surface &dest, int xHalf, int yHalf, int xSection, int ySection) { + int screenNum = _globals->_sceneManager._scene->_activeScreenNumber; + Rect updateRect(0, 0, 160, 100); + updateRect.translate(xHalf * 160, yHalf * 100); + int xHalfCount = (_globals->_sceneManager._scene->_backgroundBounds.right + 159) / 160; + int yHalfCount = (_globals->_sceneManager._scene->_backgroundBounds.bottom + 99) / 100; + + if (xSection < xHalfCount && ySection < yHalfCount) { + int rlbNum = xSection * yHalfCount + ySection; + byte *data = _vm->_dataManager->getResource(RES_BITMAP, screenNum, rlbNum); + + for (int y = 0; y < updateRect.height(); ++y) { + byte *pSrc = data + y * 160; + byte *pDest = (byte *)dest.getBasePtr(updateRect.left, updateRect.top + y); + + for (int x = 0; x < updateRect.width(); ++x, ++pSrc, ++pDest) { + *pDest = *pSrc; + } + } + + DEALLOCATE(data); + } +} + +/** + * Returns an array indicating which pixels of a source image horizontally or vertically get + * included in a scaled image + */ +static int *scaleLine(int size, int srcSize) { + int scale = 100 * size / srcSize; + assert(scale >= 0); + int *v = new int[size]; + Common::set_to(v, &v[size], 0); + + int distCtr = 0; + int *destP = v; + for (int distIndex = 0; distIndex < srcSize; ++distIndex) { + distCtr += scale; + while (distCtr >= 100) { + assert(destP < &v[size]); + *destP++ = distIndex; + distCtr -= 100; + } + } + + return v; +} + +/** + * Scales a passed surface, creating a new surface with the result + * @param srcImage Source image to scale + * @param NewWidth New width for scaled image + * @param NewHeight New height for scaled image + * @remarks Caller is responsible for freeing the returned surface + */ +static GfxSurface ResizeSurface(GfxSurface &src, int xSize, int ySize) { + GfxSurface s; + s.create(xSize, ySize); + + Graphics::Surface srcImage = src.lockSurface(); + Graphics::Surface destImage = s.lockSurface(); + + int *horizUsage = scaleLine(xSize, srcImage.w); + int *vertUsage = scaleLine(ySize, srcImage.h); + + // Loop to create scaled version + for (int yp = 0; yp < ySize; ++yp) { + const byte *srcP = (const byte *)srcImage.getBasePtr(0, vertUsage[yp]); + byte *destP = (byte *)destImage.getBasePtr(0, yp); + + for (int xp = 0; xp < xSize; ++xp) { + const byte *tempSrcP = srcP + horizUsage[xp]; + *destP++ = *tempSrcP++; + } + } + + // Unlock surfaces + src.unlockSurface(); + s.unlockSurface(); + + // Delete arrays and return surface + delete[] horizUsage; + delete[] vertUsage; + return s; +} + +/** + * Copys an area from one GfxSurface to another + */ +void GfxSurface::copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Region *priorityRegion) { + GfxSurface srcImage; + + if (srcBounds == src.getBounds()) + srcImage = src; + else { + // Set the source image to be the subset specified by the source bounds + Graphics::Surface srcSurface = src.lockSurface(); + + srcImage.create(srcBounds.width(), srcBounds.height()); + Graphics::Surface destSurface = srcImage.lockSurface(); + + const byte *srcP = (const byte *)srcSurface.getBasePtr(srcBounds.left, srcBounds.top); + byte *destP = (byte *)destSurface.pixels; + for (int yp = srcBounds.top; yp < srcBounds.bottom; ++yp, srcP += srcSurface.pitch, destP += destSurface.pitch) { + Common::copy(srcP, srcP + srcBounds.width(), destP); + } + + srcImage.unlockSurface(); + src.unlockSurface(); + } + + if ((destBounds.width() != srcBounds.width()) || (destBounds.height() != srcBounds.height())) + srcImage = ResizeSurface(srcImage, destBounds.width(), destBounds.height()); + + Graphics::Surface srcSurface = srcImage.lockSurface(); + Graphics::Surface destSurface = lockSurface(); + + // Adjust bounds to ensure destination will be on-screen + int srcX = 0, srcY = 0; + if (destBounds.left < 0) { + srcX = -destBounds.left; + destBounds.left = 0; + } + if (destBounds.top < 0) { + srcY = -destBounds.top; + destBounds.top = 0; + } + if (destBounds.right > destSurface.w) + destBounds.right = destSurface.w; + if (destBounds.bottom > destSurface.h) + destBounds.bottom = destSurface.h; + + if (destBounds.isValidRect()) { + const byte *pSrc = (const byte *)srcSurface.getBasePtr(srcX, srcY); + byte *pDest = (byte *)destSurface.getBasePtr(destBounds.left, destBounds.top); + + for (int y = 0; y < destBounds.height(); ++y, pSrc += srcSurface.pitch, pDest += destSurface.pitch) { + + if (!priorityRegion && (src._transColour == -1)) + Common::copy(pSrc, pSrc + destBounds.width(), pDest); + else { + const byte *tempSrc = pSrc; + byte *tempDest = pDest; + int xp = destBounds.left; + + while (tempSrc < (pSrc + destBounds.width())) { + if (!priorityRegion || !priorityRegion->contains(Common::Point( + xp + _globals->_sceneManager._scene->_sceneBounds.left, + destBounds.top + y + _globals->_sceneManager._scene->_sceneBounds.top))) { + if (*tempSrc != src._transColour) + *tempDest = *tempSrc; + } + ++tempSrc; + ++tempDest; + ++xp; + } + } + } + } + + unlockSurface(); + srcImage.unlockSurface(); +} + +void GfxSurface::draw(const Common::Point &pt, Rect *rect) { + Rect tempRect = getBounds(); + tempRect.translate(-_centroid.x, -_centroid.y); + tempRect.translate(pt.x, pt.y); + + if (rect) { + // Only copy needed rect out without drawing + *rect = tempRect; + } else { + // Draw image + _globals->gfxManager().copyFrom(*this, tempRect, NULL); + } +} + +/*--------------------------------------------------------------------------*/ + +GfxElement::GfxElement() { + _owner = NULL; + _keycode = 0; + _flags = 0; +} + +void GfxElement::setDefaults() { + _flags = 0; + _fontNumber = _globals->_gfxFontNumber; + _colours = _globals->_gfxColours; + _fontColours = _globals->_fontColours; +} + +/** + * Highlights the specified graphics element + */ +void GfxElement::highlight() { + // Get a lock on the surface + GfxManager &gfxManager = _globals->gfxManager(); + Graphics::Surface surface = gfxManager.lockSurface(); + + // Scan through the contents of the element, switching any occurances of the foreground + // colour with the background colour and vice versa + Rect tempRect(_bounds); + tempRect.collapse(2, 2); + + for (int yp = tempRect.top; yp < tempRect.bottom; ++yp) { + byte *lineP = (byte *)surface.getBasePtr(tempRect.left, yp); + for (int xp = tempRect.left; xp < tempRect.right; ++xp, ++lineP) { + if (*lineP == _colours.background) *lineP = _colours.foreground; + else if (*lineP == _colours.foreground) *lineP = _colours.background; + } + } + + // Release the surface + gfxManager.unlockSurface(); +} + +/** + * Fills the background of the specified element with a border frame + */ +void GfxElement::drawFrame() { + // Get a lock on the surface and save the active font + GfxManager &gfxManager = _globals->gfxManager(); + gfxManager.lockSurface(); + + uint8 bgColour, fgColour; + if (_flags & GFXFLAG_THICK_FRAME) { + bgColour = 0; + fgColour = 0; + } else { + bgColour = _fontColours.background; + fgColour = _fontColours.foreground; + } + + Rect tempRect = _bounds; + tempRect.collapse(3, 3); + tempRect.collapse(-1, -1); + gfxManager.fillRect(tempRect, _colours.background); + + --tempRect.bottom; --tempRect.right; + gfxManager.fillArea(tempRect.left, tempRect.top, bgColour); + gfxManager.fillArea(tempRect.left, tempRect.bottom, fgColour); + gfxManager.fillArea(tempRect.right, tempRect.top, fgColour); + gfxManager.fillArea(tempRect.right, tempRect.bottom, fgColour); + + tempRect.collapse(-1, -1); + gfxManager.fillRect2(tempRect.left + 1, tempRect.top, tempRect.width() - 1, 1, bgColour); + gfxManager.fillRect2(tempRect.left, tempRect.top + 1, 1, tempRect.height() - 1, bgColour); + gfxManager.fillRect2(tempRect.left + 1, tempRect.bottom, tempRect.width() - 1, 1, fgColour); + gfxManager.fillRect2(tempRect.right, tempRect.top + 1, 1, tempRect.height() - 1, fgColour); + + gfxManager.fillArea(tempRect.left, tempRect.top, 0); + gfxManager.fillArea(tempRect.left, tempRect.bottom, 0); + gfxManager.fillArea(tempRect.right, tempRect.top, 0); + gfxManager.fillArea(tempRect.right, tempRect.bottom, 0); + + tempRect.collapse(-1, -1); + gfxManager.fillRect2(tempRect.left + 2, tempRect.top, tempRect.width() - 3, 1, 0); + gfxManager.fillRect2(tempRect.left, tempRect.top + 2, 1, tempRect.height() - 3, 0); + gfxManager.fillRect2(tempRect.left + 2, tempRect.bottom, tempRect.width() - 3, 1, 0); + gfxManager.fillRect2(tempRect.right, tempRect.top + 2, 1, tempRect.height() - 3, 0); + + gfxManager.unlockSurface(); +} + +/** + * Handles events when the control has focus + * + * @event Event to process + */ +bool GfxElement::focusedEvent(Event &event) { + bool highlightFlag = false; + + while (!_vm->getEventManager()->shouldQuit()) { + g_system->delayMillis(10); + + if (_bounds.contains(event.mousePos)) { + if (!highlightFlag) { + // First highlight call to show the highlight + highlightFlag = true; + highlight(); + } + } else if (highlightFlag) { + // Mouse is outside the element, so remove the highlight + highlightFlag = false; + highlight(); + } + + if (_globals->_events.getEvent(event, EVENT_BUTTON_UP)) + break; + } + + if (highlightFlag) { + // Mouse is outside the element, so remove the highlight + highlight(); + } + + return highlightFlag; +} + +/*--------------------------------------------------------------------------*/ + +GfxImage::GfxImage(): GfxElement() { + _resNum = 0; + _rlbNum = 0; + _cursorNum = 0; +} + +void GfxImage::setDetails(int resNum, int rlbNum, int cursorNum) { + _resNum = resNum; + _rlbNum = rlbNum; + _cursorNum = cursorNum; + setDefaults(); +} + +void GfxImage::setDefaults() { + GfxElement::setDefaults(); + + // Decode the image + uint size; + byte *imgData = _vm->_dataManager->getSubResource(_resNum, _rlbNum, _cursorNum, &size); + _surface = surfaceFromRes(imgData); + DEALLOCATE(imgData); + + // Set up the display bounds + Rect imgBounds = _surface.getBounds(); + imgBounds.moveTo(_bounds.left, _bounds.top); + _bounds = imgBounds; +} + +void GfxImage::draw() { + Rect tempRect = _bounds; + tempRect.translate(_globals->gfxManager()._topLeft.x, _globals->gfxManager()._topLeft.y); + + _globals->gfxManager().copyFrom(_surface, tempRect); +} + +/*--------------------------------------------------------------------------*/ + +GfxMessage::GfxMessage(): GfxElement() { + _textAlign = ALIGN_LEFT; + _width = 0; +} + +void GfxMessage::set(const Common::String &s, int width, TextAlign textAlign) { + _message = s; + _width = width; + _textAlign = textAlign; + + setDefaults(); +} + +void GfxMessage::setDefaults() { + GfxElement::setDefaults(); + + GfxFontBackup font; + GfxManager &gfxManager = _globals->gfxManager(); + Rect tempRect; + + gfxManager._font.setFontNumber(this->_fontNumber); + gfxManager.getStringBounds(_message.c_str(), tempRect, _width); + + tempRect.collapse(-1, -1); + tempRect.moveTo(_bounds.left, _bounds.top); + _bounds = tempRect; +} + +void GfxMessage::draw() { + GfxFontBackup font; + GfxManager &gfxManager = _globals->gfxManager(); + + // Set the font and colour + gfxManager.setFillFlag(false); + gfxManager._font.setFontNumber(_fontNumber); + gfxManager._font._colours.foreground = this->_colours.foreground; + + // Display the text + gfxManager._font.writeLines(_message.c_str(), _bounds, _textAlign); +} + +/*--------------------------------------------------------------------------*/ + +void GfxButton::setDefaults() { + GfxElement::setDefaults(); + + GfxFontBackup font; + GfxManager &gfxManager = _globals->gfxManager(); + Rect tempRect; + + // Get the string bounds and round up the x end to a multiple of 16 + gfxManager._font.setFontNumber(this->_fontNumber); + gfxManager._font.getStringBounds(_message.c_str(), tempRect, 240); + tempRect.right = ((tempRect.right + 15) / 16) * 16; + + // Set the button bounds to a reduced area + tempRect.collapse(-3, -3); + tempRect.moveTo(_bounds.left, _bounds.top); + _bounds = tempRect; +} + +void GfxButton::draw() { + // Get a lock on the surface and save the active font + GfxFontBackup font; + GfxManager &gfxManager = _globals->gfxManager(); + gfxManager.lockSurface(); + + // Draw a basic frame for the button + drawFrame(); + + // Set the font and colour + gfxManager._font.setFontNumber(_fontNumber); + gfxManager._font._colours.foreground = this->_colours.foreground; + + // Display the button's text + Rect tempRect(_bounds); + tempRect.collapse(3, 3); + gfxManager._font.writeLines(_message.c_str(), tempRect, ALIGN_CENTRE); + + gfxManager.unlockSurface(); +} + +bool GfxButton::process(Event &event) { + switch (event.eventType) { + case EVENT_BUTTON_DOWN: + if (!event.handled) { + if (_bounds.contains(event.mousePos)) { + bool result = focusedEvent(event); + event.handled = true; + return result; + } + } + break; + + case EVENT_KEYPRESS: + if (!event.handled && (event.kbd.keycode == _keycode)) { + // TODO: Ensure momentary click operation displays + highlight(); + g_system->delayMillis(20); + highlight(); + + event.handled = true; + return true; + } + + default: + break; + } + + return false; +} + +/*--------------------------------------------------------------------------*/ + +GfxDialog::GfxDialog() { + _savedArea = NULL; + _defaultButton = NULL; +} + +GfxDialog::~GfxDialog() { + remove(); +} + +void GfxDialog::setDefaults() { + GfxElement::setDefaults(); + + // Initialise the embedded graphics manager + _gfxManager.setDefaults(); + + // Figure out a rect needed for all the added elements + GfxElementList::iterator i; + Rect tempRect; + for (i = _elements.begin(); i != _elements.end(); ++i) + tempRect.extend((*i)->_bounds); + + // Set the dialog boundaries + _gfxManager._bounds = tempRect; + tempRect.collapse(-6, -6); + _bounds = tempRect; +} + +void GfxDialog::remove() { + if (_savedArea) { + // Restore the area the dialog covered + _globals->_gfxManagerInstance.copyFrom(*_savedArea, _bounds.left, _bounds.top); + + delete _savedArea; + _savedArea = NULL; + } +} + +void GfxDialog::draw() { + Rect tempRect(_bounds); + + // Make a backup copy of the area the dialog will occupy + _savedArea = Surface_getArea(_globals->_gfxManagerInstance.getSurface(), _bounds); + + // Set the palette for use in the dialog + setPalette(); + + _gfxManager.activate(); + + // Fill in the contents of the entire dialog + _gfxManager._bounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + drawFrame(); + + // Reset the dialog's graphics manager to only draw within the dialog boundaries + tempRect.translate(6, 6); + _gfxManager._bounds = tempRect; + + // Draw each element in the dialog in order + GfxElementList::iterator i; + for (i = _elements.begin(); i != _elements.end(); ++i) { + (*i)->draw(); + } + + // If there's a default button, then draw it + if (_defaultButton) { + _defaultButton->_flags |= GFXFLAG_THICK_FRAME; + _defaultButton->draw(); + } + + _gfxManager.deactivate(); +} + +void GfxDialog::add(GfxElement *element) { + _elements.push_back(element); + element->_owner = this; +} + +void GfxDialog::addElements(GfxElement *ge, ...) { + va_list va; + va_start(va, ge); + GfxElement *gfxElement = ge; + while (gfxElement) { + add(gfxElement); + + gfxElement = va_arg(va, GfxElement *); + } + + va_end(va); +} + +void GfxDialog::setTopLeft(int xp, int yp) { + _bounds.moveTo(xp - 6, yp - 6); +} + +void GfxDialog::setCentre(int xp, int yp) { + setTopLeft(xp - (_bounds.width() / 2), yp - (_bounds.height() / 2)); +} + +GfxButton *GfxDialog::execute(GfxButton *defaultButton) { + _gfxManager.activate(); + + if (defaultButton != _defaultButton) { + if (_defaultButton) { + _defaultButton->_flags &= ~GFXFLAG_THICK_FRAME; + _defaultButton->draw(); + } + _defaultButton = defaultButton; + } + if (_defaultButton) { + _defaultButton->_flags |= GFXFLAG_THICK_FRAME; + _defaultButton->draw(); + } + + // Event loop + GfxButton *selectedButton = NULL; + + while (!_vm->getEventManager()->shouldQuit()) { + Event event; + while (_globals->_events.getEvent(event)) { + // Adjust mouse positions to be relative within the dialog + event.mousePos.x -= _gfxManager._bounds.left; + event.mousePos.y -= _gfxManager._bounds.top; + + for (GfxElementList::iterator i = _elements.begin(); i != _elements.end(); ++i) { + if ((*i)->process(event)) + selectedButton = static_cast<GfxButton *>(*i); + } + } + + if (selectedButton) + break; + else if (!event.handled) { + if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) { + selectedButton = NULL; + break; + } else if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_RETURN)) { + selectedButton = defaultButton; + break; + } + } + } + + _gfxManager.deactivate(); + if (_defaultButton) + _defaultButton->_flags &= ~GFXFLAG_THICK_FRAME; + + return selectedButton; +} + +void GfxDialog::setPalette() { + _globals->_scenePalette.loadPalette(0); + _globals->_scenePalette.setPalette(0, 1); + _globals->_scenePalette.setPalette(_globals->_scenePalette._colours.foreground, 1); + _globals->_scenePalette.setPalette(_globals->_fontColours.background, 1); + _globals->_scenePalette.setPalette(_globals->_fontColours.foreground, 1); + _globals->_scenePalette.setPalette(255, 1); +} + +/*--------------------------------------------------------------------------*/ + +GfxManager::GfxManager(): _surface(_globals->_screenSurface), _oldManager(NULL) { + _font.setOwner(this); + _font._fillFlag = false; + _bounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); +} + +GfxManager::GfxManager(GfxSurface &s): _surface(s), _oldManager(NULL) { + _font.setOwner(this); + _font._fillFlag = false; +} + +void GfxManager::setDefaults() { + Rect screenBounds(0, 0, g_system->getWidth(), g_system->getHeight()); + + _surface.setBounds(screenBounds); + _bounds = screenBounds; + _pane0Rect4 = screenBounds; + + _font._edgeSize = Common::Point(1, 1); + _font._colours = _globals->_fontColours; + _font.setFontNumber(_globals->_gfxFontNumber); +} + +void GfxManager::activate() { + assert(!_globals->_gfxManagers.contains(this)); + _globals->_gfxManagers.push_front(this); +} + +void GfxManager::deactivate() { + // Assert that there will still be another manager, and we're correctly removing our own + assert((_globals->_gfxManagers.size() > 1) && (&_globals->gfxManager() == this)); + _globals->_gfxManagers.pop_front(); +} + +int GfxManager::getStringWidth(const char *s, int numChars) { + return _font.getStringWidth(s, numChars); +} + +int GfxManager::getStringWidth(const char *s) { + return _font.getStringWidth(s); +} + +void GfxManager::getStringBounds(const char *s, Rect &bounds, int maxWidth) { + _font.getStringBounds(s, bounds, maxWidth); +} + +void GfxManager::fillArea(int xp, int yp, int colour) { + _surface.setBounds(_bounds); + Rect tempRect(xp, yp, xp + _font._edgeSize.x, yp + _font._edgeSize.y); + _surface.fillRect(tempRect, colour); +} + +void GfxManager::fillRect(const Rect &bounds, int colour) { + _surface.setBounds(_bounds); + _surface.fillRect(bounds, colour); +} + +void GfxManager::fillRect2(int xs, int ys, int width, int height, int colour) { + _surface.setBounds(_bounds); + _surface.fillRect(Rect(xs, ys, xs + width, ys + height), colour); +} + +/** + * Sets up the standard palette for dialog displays + */ +void GfxManager::setDialogPalette() { + // Get the main palette information + uint32 palData[256]; + uint count, start; + _vm->_dataManager->getPalette(0, (byte *)&palData[0], &start, &count); + g_system->getPaletteManager()->setPalette((byte *)&palData[0], start, count); + + // Miscellaneous + uint32 white = 0xffffffff; + g_system->getPaletteManager()->setPalette((const byte *)&white, 255, 1); +} + +/** + * Returns the angle of line connecting two points + */ +int GfxManager::getAngle(const Common::Point &p1, const Common::Point &p2) { + int xDiff = p2.x - p1.x, yDiff = p1.y - p2.y; + + if (!xDiff && !yDiff) + return -1; + else if (!xDiff) + return (p2.y >= p1.y) ? 180 : 0; + else if (!yDiff) + return (p2.x >= p1.x) ? 90 : 270; + else { + int result = (((xDiff * 100) / ((abs(xDiff) + abs(yDiff))) * 90) / 100); + + if (yDiff < 0) + result = 180 - result; + else if (xDiff < 0) + result += 360; + + return result; + } +} +/*--------------------------------------------------------------------------*/ + + +GfxFont::GfxFont() { + _fontNumber = 50; + _numChars = 0; + _bpp = 0; + _fontData = NULL; + _fillFlag = false; +} + +GfxFont::~GfxFont() { + DEALLOCATE(_fontData); +} + +/** + * Sets the current active font number + * + * @fontNumber New font number + */ +void GfxFont::setFontNumber(uint32 fontNumber) { + if ((_fontNumber == fontNumber) && (_fontData)) + return; + + DEALLOCATE(_fontData); + + _fontNumber = fontNumber; + + _fontData = _vm->_tSageManager->getResource(RES_FONT, _fontNumber, 0, true); + if (!_fontData) + _fontData = _vm->_dataManager->getResource(RES_FONT, _fontNumber, 0); + + _numChars = READ_LE_UINT16(_fontData + 4); + _fontSize.y = READ_LE_UINT16(_fontData + 6); + _fontSize.x = READ_LE_UINT16(_fontData + 8); + _bpp = READ_LE_UINT16(_fontData + 10); +} + +/** + * Returns the width of the given specified character + * + * @ch Character to return width of + */ +int GfxFont::getCharWidth(char ch) { + assert(_numChars > 0); + uint32 charOffset = READ_LE_UINT32(_fontData + 12 + (uint8)ch * 4); + return _fontData[charOffset] & 0x1f; +} + +/** + * Returns the width of the given string in the current font + * + * @s String to return the width of + * @numChars Number of characters within the string to use + */ +int GfxFont::getStringWidth(const char *s, int numChars) { + assert(_numChars > 0); + int width = 0; + + for (; numChars > 0; --numChars, ++s) { + uint32 charOffset = READ_LE_UINT32(_fontData + 12 + (uint8)*s * 4); + int charWidth = _fontData[charOffset] & 0x1f; + + width += charWidth; + } + + return width; +} + +/** + * Returns the width of the given string in the current font + * + * @s String to return the width of + */ +int GfxFont::getStringWidth(const char *s) { + return getStringWidth(s, strlen(s)); +} + +/** + * Returns the maximum number of characters for words that will fit into a given width + * + * @s Message to be analysed + * @maxWidth Maximum allowed width + */ +int GfxFont::getStringFit(const char *&s, int maxWidth) { + const char *nextWord = NULL; + const char *sStart = s; + int numChars = 1; + int strWidth = 1; + char nextChar; + + for (;;) { + nextChar = *s++; + + if ((nextChar == '\r') || (nextChar == '\0')) + break; + + // Check if it's a word end + if (nextChar == ' ') { + nextWord = s; + } + + strWidth = getStringWidth(sStart, numChars); + if (strWidth > maxWidth) { + if (nextWord) { + s = nextWord; + nextChar = ' '; + } + break; + } + + ++numChars; + } + + int totalChars = s - sStart; + if (nextChar == '\0') + --s; + if ((nextChar == ' ') || (nextChar == '\r') || (nextChar == '\0')) + --totalChars; + + return totalChars; +} + +/** + * Fills out the passed rect with the dimensions of a given string word-wrapped to a + * maximum specified width + * + * @s Message to be analysed + * @bounds Rectangle to put output size into + * @maxWidth Maximum allowed line width in pixels + */ +void GfxFont::getStringBounds(const char *s, Rect &bounds, int maxWidth) { + if (maxWidth == 0) { + // No maximum width, so set bounds for a single line + bounds.set(0, 0, getStringWidth(s), getHeight()); + } else { + int numLines = 0; + int lineWidth = 0; + + // Loop to figure out the number of lines required, and the maximum line width + while (*s) { + const char *msg = s; + int numChars = getStringFit(msg, maxWidth); + lineWidth = MAX(lineWidth, getStringWidth(s, numChars)); + + s = msg; + ++numLines; + } + + bounds.set(0, 0, lineWidth, numLines * getHeight()); + } +} + +/** + * Writes out a character at the currently set position using the active font + * + * @ch Character to display + */ +int GfxFont::writeChar(const char ch) { + assert((_fontData != NULL) && ((uint8)ch < _numChars)); + uint32 charOffset = READ_LE_UINT32(_fontData + 12 + (uint8)ch * 4); + int charWidth = _fontData[charOffset] & 0x1f; + int charHeight = (READ_LE_UINT16(_fontData + charOffset) >> 5) & 0x3f; + int yOffset = (_fontData[charOffset + 1] >> 3) & 0x1f; + const uint8 *dataP = &_fontData[charOffset + 2]; + + // Lock the surface for access + Graphics::Surface surfacePtr = _gfxManager->lockSurface(); + + Rect charRect; + charRect.set(0, 0, charWidth, _fontSize.y); + charRect.translate(_topLeft.x + _position.x, _topLeft.y + _position.y + yOffset); + + if (_fillFlag) + surfacePtr.fillRect(charRect, _colours.background); + + charRect.bottom = charRect.top + charHeight; + + // Display the character + int bitCtr = 0; + uint8 v = 0; + for (int yp = charRect.top; yp < charRect.bottom; ++yp) { + byte *destP = (byte *)surfacePtr.getBasePtr(charRect.left, yp); + + for (int xs = 0; xs < charRect.width(); ++xs, ++destP) { + // Get the next colour index to use + if ((bitCtr % 8) == 0) v = *dataP++; + int colIndex = 0; + for (int subCtr = 0; subCtr < _bpp; ++subCtr, ++bitCtr) { + colIndex = (colIndex << 1) | (v & 0x80 ? 1 : 0); + v <<= 1; + } + + switch (colIndex) { + //case 0: *destP = _colours.background; break; + case 1: *destP = _colours.foreground; break; + case 2: *destP = _colours2.background; break; + case 3: *destP = _colours2.foreground; break; + } + } + } + + _position.x += charWidth; + _gfxManager->unlockSurface(); + return charWidth; +} + +/** + * Writes the specified number of characters from the specified string at the current text position + * + * @s String to display + * @numChars Number of characters to print + */ +void GfxFont::writeString(const char *s, int numChars) { + // Lock the surface for access + _gfxManager->lockSurface(); + + while ((numChars-- > 0) && (*s != '\0')) { + writeChar(*s); + ++s; + } + + // Release the surface lock + _gfxManager->unlockSurface(); +} + +/** + * Writes the the specified string at the current text position + * + * @s String to display + */ +void GfxFont::writeString(const char *s) { + writeString(s, strlen(s)); +} + +/** + * Writes a specified string within a given area with support for word wrapping and text alignment types + * + * @s String to display + * @bounds Bounds to display the text within + * @align Text alignment mode + */ +void GfxFont::writeLines(const char *s, const Rect &bounds, TextAlign align) { + int lineNum = 0; + + // Lock the surface for access + _gfxManager->lockSurface(); + + while (*s) { + const char *msgP = s; + int numChars = getStringFit(msgP, bounds.width()); + + _position.y = bounds.top + lineNum * getHeight(); + + switch (align) { + case ALIGN_RIGHT: + // Right aligned text + _position.x = bounds.right - getStringWidth(s, numChars); + writeString(s, numChars); + break; + + case ALIGN_CENTRE: + // Center aligned text + _position.x = bounds.left + (bounds.width() / 2) - (getStringWidth(s, numChars) / 2); + writeString(s, numChars); + break; + + case ALIGN_JUSTIFIED: { + // Justified text + // Get the number of words in the string portion + int charCtr = 0, numWords = 0; + while (charCtr < numChars) { + if (s[charCtr] == ' ') + ++numWords; + ++charCtr; + } + // If end of string, count final word + if (*msgP == '\0') + ++numWords; + + // Display the words of the string + int spareWidth = bounds.width() - getStringWidth(s, numChars); + charCtr = 0; + _position.x = bounds.left; + + while (charCtr < numChars) { + writeChar(s[charCtr]); + if ((numWords > 0) && (s[charCtr] == ' ')) { + int separationWidth = spareWidth / numWords; + spareWidth -= separationWidth; + --numWords; + _position.x += separationWidth; + } + + ++charCtr; + } + break; + } + + case ALIGN_LEFT: + default: + // Standard text + _position.x = bounds.left; + writeString(s, numChars); + break; + } + + // Next line + s = msgP; + ++lineNum; + } + + // Release the surface lock + _gfxManager->unlockSurface(); +} + +/*--------------------------------------------------------------------------*/ + +GfxFontBackup::GfxFontBackup() { + _edgeSize = _globals->gfxManager()._font._edgeSize; + _position = _globals->gfxManager()._font._position; + _colours = _globals->gfxManager()._font._colours; + _fontNumber = _globals->gfxManager()._font._fontNumber; +} + +GfxFontBackup::~GfxFontBackup() { + _globals->gfxManager()._font.setFontNumber(_fontNumber); + _globals->gfxManager()._font._edgeSize = _edgeSize; + _globals->gfxManager()._font._position = _position; + _globals->gfxManager()._font._colours = _colours; +} + + +} // End of namespace tSage diff --git a/engines/tsage/graphics.h b/engines/tsage/graphics.h new file mode 100644 index 0000000000..e1527bdbcb --- /dev/null +++ b/engines/tsage/graphics.h @@ -0,0 +1,349 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/graphics.h $ + * $Id: graphics.h 184 2011-02-03 11:31:38Z dreammaster $ + * + */ + +#ifndef RING_GRAPHICS_H +#define RING_GRAPHICS_H + +#include "tsage/events.h" +#include "tsage/saveload.h" +#include "common/list.h" +#include "common/rect.h" +#include "common/system.h" +#include "graphics/surface.h" + +namespace tSage { + +class GfxSurface; +class Region; + +/** + * Extended Rect class with extra support methods + */ +class Rect: public Common::Rect, public Serialisable { +public: + Rect(): Common::Rect() {}; + Rect(int16 x1, int16 y1, int16 x2, int16 y2): Common::Rect(x1, y1, x2, y2) {}; + + void set(int16 x1, int16 y1, int16 x2, int16 y2); + void collapse(int dx, int dy); + void centre(int dx, int dy); + void centre(const Rect &r); + void centre(const Common::Point &pt) { centre(pt.x, pt.y); } + void contain(const Rect &r); + void resize(const GfxSurface &surface, int xp, int yp, int percent); + void expandPanes(); + + virtual void synchronise(Serialiser &s); +}; + +class GfxColours { +public: + uint8 foreground; + uint8 background; + + GfxColours(): foreground(0), background(0) {}; +}; + +class LineSlice { +public: + int xs, xe; + + LineSlice() { xs = 0; xe = 0; } + LineSlice(int xStart, int xEnd) { xs = xStart; xe = xEnd; } +}; + +class GfxSurface { +private: + Graphics::Surface *_customSurface; + Graphics::Surface *_screenSurfaceP; + int _lockSurfaceCtr; + bool _screenSurface; + + bool _disableUpdates; + Rect _bounds; +public: + Common::Point _centroid; + int _transColour; +public: + GfxSurface(); + GfxSurface(const GfxSurface &s); + ~GfxSurface(); + + void setScreenSurface(); + Graphics::Surface lockSurface(); + void unlockSurface(); + void create(int width, int height); + void setBounds(const Rect &bounds) { _bounds = bounds; }; + const Rect &getBounds() const { return _bounds; }; + + void copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Region *priorityRegion = NULL); + void copyFrom(GfxSurface &src, Rect destBounds, Region *priorityRegion = NULL) { + copyFrom(src, src.getBounds(), destBounds, priorityRegion); + } + void copyFrom(GfxSurface &src, int destX = 0, int destY = 0, Region *priorityRegion = NULL) { + Rect tempRect = src.getBounds(); + tempRect.moveTo(destX, destY); + copyFrom(src, tempRect, priorityRegion); + } + void draw(const Common::Point &pt, Rect *rect = NULL); + void fillRect(const Rect &bounds, int colour); + GfxSurface &operator=(const GfxSurface &s); + + static void loadScreenSection(Graphics::Surface &dest, int xHalf, int yHalf, int xSection, int ySection); + static bool displayText(const Common::String &msg, const Common::Point &pt = Common::Point(160, 100)); +}; + +enum TextAlign {ALIGN_LEFT = 0, ALIGN_CENTRE = 1, ALIGN_RIGHT = 2, ALIGN_JUSTIFIED = 3}; + +class GfxFont { + friend class GfxFontBackup; +private: + GfxManager *_gfxManager; + // Raw font details + const byte *_fontData; + int _numChars; + Common::Point _fontSize; + int _bpp; +public: + // Font fields + Common::Point _edgeSize; + Common::Point _position; + bool _fillFlag; + GfxColours _colours; + GfxColours _colours2; + uint32 _fontNumber; + Common::Point _topLeft; +public: + GfxFont(); + virtual ~GfxFont(); + + void setFontNumber(uint32 fontNumber); + int32 getHeight() const { return _fontSize.y; } + int getCharWidth(char ch); + int getStringWidth(const char *s, int numChars); + int getStringWidth(const char *s); + int getStringFit(const char *&s, int maxWidth); + void getStringBounds(const char *s, Rect &bounds, int maxWidth); + + void setOwner(GfxManager *owner) { _gfxManager = owner; } + void setPosition(int xp, int yp) { _position.x = xp; _position.y = yp; } + int writeChar(const char ch); + void writeString(const char *s); + void writeString(const char *s, int numChars); + void writeLines(const char *s, const Rect &bounds, TextAlign align); +}; + +class GfxFontBackup { +private: + GfxSurface *_surface; + Common::Point _edgeSize; + Common::Point _position; + GfxColours _colours; + uint32 _fontNumber; +public: + GfxFontBackup(); + ~GfxFontBackup(); +}; + +enum GFX_FLAGS {GFXFLAG_THICK_FRAME = 8}; + +class GfxManager; + +class GfxElement { +public: + GfxElement *_owner; + Rect _bounds; + uint16 _flags; + uint16 _fontNumber; + GfxColours _colours; + GfxColours _fontColours; + uint16 _keycode; +public: + GfxElement(); + virtual ~GfxElement() {} + + void drawFrame(); + + // Virtual table method + virtual void setDefaults(); + virtual void remove() { _owner = NULL; } + virtual void highlight(); + virtual void draw() {}; + virtual bool process(Event &event) { return false; }; + virtual bool focusedEvent(Event &event); +}; + +class GfxImage: public GfxElement { +public: + GfxSurface _surface; + int _resNum; + int _rlbNum; + int _cursorNum; +public: + GfxImage(); + + void setDetails(int resNum, int rlbNum, int cursorNum); + + virtual void setDefaults(); + virtual void draw(); + virtual bool process(Event &event) { return false; } +}; + +class GfxMessage: public GfxElement { +public: + Common::String _message; + TextAlign _textAlign; + int _width; +public: + GfxMessage(); + virtual ~GfxMessage() {} + + void set(const Common::String &s, int width, TextAlign textAlign); + + virtual void setDefaults(); + virtual void draw(); +}; + +class GfxButton: public GfxElement { +private: + void setFocus(); +public: + Common::String _message; +public: + GfxButton(): GfxElement() {}; + virtual ~GfxButton() {} + + void setText(const Common::String &s) { + _message = s; + setDefaults(); + } + + // Virtual table method + virtual void setDefaults(); + virtual void draw(); + virtual bool process(Event &event); +}; + +class GfxManager { +private: + GfxSurface &_surface; +public: + GfxManager *_oldManager; + Common::Point _topLeft; + Rect _bounds; + Rect _pane0Rect4; + GfxFont _font; +public: + GfxManager(); + GfxManager(GfxSurface &s); + virtual ~GfxManager() {} + + void setDefaults(); + void activate(); + void deactivate(); + + // Accessor methods + int getStringWidth(const char *s, int numChars); + int getStringWidth(const char *s); + void getStringBounds(const char *s, Rect &bounds, int maxWidth); + + void setDialogPalette(); + Graphics::Surface lockSurface() { + _surface.setBounds(_bounds); + return _surface.lockSurface(); + } + void unlockSurface() { _surface.unlockSurface(); }; + void fillArea(int xp, int yp, int colour); + void fillRect(const Rect &bounds, int colour); + void fillRect2(int xs, int ys, int width, int height, int colour); + void setFillFlag(bool v) { _font._fillFlag = v; } + + static int getAngle(const Common::Point &p1, const Common::Point &p2); + + // Virtual method table + virtual void xorArea(const Common::Rect &r, int colour, int fillMode) { + //_surface->xorArea(r, colour, fillMode); + } + virtual void draw(const Common::Rect &r, void *gfxData, int v1, GfxColours *colours) { + //_surface->draw(r, gfxData, v1, colours); + } + virtual void copy(const byte *src, byte *dest, int size) { + Common::copy(src, src + size, dest); + } + virtual void set(byte *dest, int size, byte val) { + Common::set_to(dest, dest + size, val); + } + void copyFrom(GfxSurface &src, Rect destBounds, Region *priorityRegion = NULL) { + _surface.setBounds(_bounds); + _surface.copyFrom(src, destBounds, priorityRegion); + } + void copyFrom(GfxSurface &src, int destX, int destY) { + _surface.setBounds(_bounds); + _surface.copyFrom(src, destX, destY); + g_system->updateScreen(); + } + GfxSurface &getSurface() { + _surface.setBounds(_bounds); + return _surface; + } +}; + +typedef Common::List<GfxElement *> GfxElementList; + +class GfxDialog: public GfxElement { +public: + GfxManager _gfxManager; + GfxElementList _elements; + GfxButton *_defaultButton; + GfxSurface *_savedArea; +public: + GfxDialog(); + virtual ~GfxDialog(); + + void add(GfxElement *element); + void addElements(GfxElement *ge, ...); + void setTopLeft(int xp, int yp); + void setCentre(int xp, int yp); + void frame() { + setDefaults(); + _bounds.collapse(6, 6); + } + GfxButton *execute(GfxButton *defaultButton = NULL); + + virtual void setDefaults(); + virtual void remove(); + virtual void draw(); + + static void setPalette(); +}; + +GfxSurface *Surface_getArea(GfxSurface &src, const Rect &bounds); + +GfxSurface surfaceFromRes(const byte *imgData); +GfxSurface surfaceFromRes(int resNum, int rlbNum, int subNum); + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/module.mk b/engines/tsage/module.mk new file mode 100644 index 0000000000..a15b342319 --- /dev/null +++ b/engines/tsage/module.mk @@ -0,0 +1,35 @@ +MODULE := engines/tsage + +MODULE_OBJS := \ + converse.o \ + core.o \ + debugger.o \ + detection.o \ + dialogs.o \ + events.o \ + globals.o \ + graphics.o \ + resources.o \ + ringworld_logic.o \ + ringworld_scenes1.o \ + ringworld_scenes2.o \ + ringworld_scenes3.o \ + ringworld_scenes4.o \ + ringworld_scenes5.o \ + ringworld_scenes6.o \ + ringworld_scenes8.o \ + ringworld_scenes10.o \ + saveload.o \ + scenes.o \ + sound.o \ + staticres.o \ + tsage.o + +# This module can be built as a plugin +ifdef BUILD_PLUGINS +PLUGIN := 1 +endif + +# Include common rules +include $(srcdir)/rules.mk + diff --git a/engines/tsage/resources.cpp b/engines/tsage/resources.cpp new file mode 100644 index 0000000000..619f818f6e --- /dev/null +++ b/engines/tsage/resources.cpp @@ -0,0 +1,414 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/resources.cpp $ + * $Id: resources.cpp 145 2011-01-08 11:41:39Z dreammaster $ + * + */ + +#include "common/scummsys.h" +#include "common/endian.h" +#include "common/file.h" +#include "common/stack.h" +#include "common/util.h" +#include "tsage/resources.h" + +namespace tSage { + + +MemoryManager::MemoryManager() { + _memoryPool = new MemoryHeader*[MEMORY_POOL_SIZE]; + Common::set_to(&_memoryPool[0], &_memoryPool[MEMORY_POOL_SIZE], (MemoryHeader *)NULL); +} + +MemoryManager::~MemoryManager() { + for (int i = 0; i < MEMORY_POOL_SIZE; ++i) { + if (_memoryPool[i] != NULL) + free(_memoryPool[i]); + } + delete[] _memoryPool; +} + +uint16 MemoryManager::allocate(uint32 size) { + int idx = 0; + while ((idx < MEMORY_POOL_SIZE) && (_memoryPool[idx] != NULL)) + ++idx; + if (idx == MEMORY_POOL_SIZE) + error("Out of memory handles"); + + // Create the new entry + _memoryPool[idx] = (MemoryHeader *)malloc(sizeof(MemoryHeader) + size); + _memoryPool[idx]->id = MEMORY_ENTRY_ID; + _memoryPool[idx]->index = idx; + _memoryPool[idx]->lockCtr = 0; + _memoryPool[idx]->criticalCtr = 0; + _memoryPool[idx]->tag = 0; + _memoryPool[idx]->size = size; + + // Return it's index + return idx; +} + +byte *MemoryManager::allocate2(uint32 size) { + uint32 idx = allocate(size); + return lock(idx); +} + +byte *MemoryManager::lock(uint32 handle) { + assert((int)handle < MEMORY_POOL_SIZE); + return (byte *)_memoryPool[handle] + sizeof(MemoryHeader); +} + +int MemoryManager::indexOf(const byte *p) { + for (int idx = 0; idx < MEMORY_POOL_SIZE; ++idx) { + if (((byte *)_memoryPool[idx] + sizeof(MemoryHeader)) == p) + return idx; + } + + return -1; +} + +void MemoryManager::deallocate(const byte *p) { + if (!p) + return; + + int idx = indexOf(p); + assert(idx != -1); + if (_memoryPool[idx]->lockCtr-- == 0) { + free(_memoryPool[idx]); + _memoryPool[idx] = NULL; + } +} + +uint32 MemoryManager::getSize(const byte *p) { + int idx = indexOf(p); + assert(idx >= 0); + return _memoryPool[idx]->size; +} + +void MemoryManager::incLocks(const byte *p) { + int idx = indexOf(p); + assert(idx >= 0); + _memoryPool[idx]->lockCtr++; +} + +/*-------------------------------------------------------------------------*/ + +static uint16 bitMasks[4] = {0x1ff, 0x3ff, 0x7ff, 0xfff}; + +uint16 BitReader::readToken() { + assert((numBits >= 9) && (numBits <= 12)); + uint16 result = _remainder; + int bitsLeft = numBits - _bitsLeft; + int bitOffset = _bitsLeft; + _bitsLeft = 0; + + while (bitsLeft >= 0) { + _remainder = readByte(); + result |= _remainder << bitOffset; + bitsLeft -= 8; + bitOffset += 8; + } + + _bitsLeft = -bitsLeft; + _remainder >>= 8 - _bitsLeft; + return result & bitMasks[numBits - 9]; +} + +/*-------------------------------------------------------------------------*/ + +RlbManager::RlbManager(MemoryManager &memManager, const Common::String filename): + _memoryManager(memManager) { + + // If the resource strings list isn't yet loaded, load them + if (_resStrings.size() == 0) { + Common::File f; + if (f.open("tsage.cfg")) { + while (!f.eos()) { + _resStrings.push_back(f.readLine()); + } + f.close(); + } + } + + if (!_file.open(filename)) + error("Missing file %s", filename.c_str()); + + loadIndex(); +} + +RlbManager::~RlbManager() { + _resStrings.clear(); +} + +void RlbManager::loadSection(uint32 fileOffset) { + _resources.clear(); + _file.seek(fileOffset); + _sections.fileOffset = fileOffset; + + if (_file.readUint32BE() != 0x544D492D) + error("Data block is not valid Rlb data"); + + /*uint8 unknown1 = */_file.readByte(); + uint16 numEntries = _file.readByte(); + + for (uint i = 0; i < numEntries; ++i) { + uint16 id = _file.readUint16LE(); + uint16 size = _file.readUint16LE(); + uint16 uncSize = _file.readUint16LE(); + uint8 sizeHi = _file.readByte(); + uint8 type = _file.readByte() >> 5; + assert(type <= 1); + uint32 offset = _file.readUint32LE(); + + ResourceEntry re; + re.id = id; + re.fileOffset = offset; + re.isCompressed = type != 0; + re.size = ((sizeHi & 0xF) << 16) | size; + re.uncompressedSize = ((sizeHi & 0xF0) << 12) | uncSize; + + _resources.push_back(re); + } +} + +struct DecodeReference { + uint16 vWord; + uint8 vByte; +}; + +/** + * Gets a resource from the currently loaded section + */ +byte *RlbManager::getResource(uint16 id, bool suppressErrors) { + // Scan for an entry for the given Id + ResourceEntry *re= NULL; + ResourceList::iterator i; + for (i = _resources.begin(); i != _resources.end(); ++i) { + if ((*i).id == id) { + re = &(*i); + break; + } + } + if (!re) { + if (suppressErrors) + return NULL; + error("Could not find resource Id #%d", id); + } + + if (!re->isCompressed) { + // Read in the resource data and return it + byte *dataP = _memoryManager.allocate2(re->size); + _file.seek(_sections.fileOffset + re->fileOffset); + _file.read(dataP, re->size); + + return dataP; + } + + /* + * Decompress the data block + */ + + _file.seek(_sections.fileOffset + re->fileOffset); + Common::ReadStream *compStream = _file.readStream(re->size); + BitReader bitReader(*compStream); + + byte *dataOut = _memoryManager.allocate2(re->uncompressedSize); + byte *destP = dataOut; + uint bytesWritten = 0; + + uint16 ctrCurrent = 0x102, ctrMax = 0x200; + uint16 word_48050 = 0, currentToken = 0, word_48054 =0; + byte byte_49068 = 0, byte_49069 = 0; + DecodeReference table[0x1000]; + Common::Stack<uint16> tokenList; + + for (;;) { + // Get the next decode token + uint16 token = bitReader.readToken(); + + // Handle the token + if (token == 0x101) { + // End of compressed stream + break; + } else if (token == 0x100) { + // Reset bit-rate + bitReader.numBits = 9; + ctrMax = 0x200; + ctrCurrent = 0x102; + + // Set variables with next token + currentToken = word_48050 = bitReader.readToken(); + byte_49069 = byte_49068 = (byte)currentToken; + + ++bytesWritten; + assert(bytesWritten <= re->uncompressedSize); + *destP++ = byte_49069; + } else { + word_48054 = word_48050 = token; + + if (token >= ctrCurrent) { + word_48050 = currentToken; + tokenList.push(byte_49068); + } + + while (word_48050 >= 0x100) { + assert(word_48050 < 0x1000); + tokenList.push(table[word_48050].vByte); + word_48050 = table[word_48050].vWord; + } + + byte_49069 = byte_49068 = (byte)word_48050; + tokenList.push(word_48050); + + // Write out any cached tokens + while (!tokenList.empty()) { + ++bytesWritten; + assert(bytesWritten <= re->uncompressedSize); + *destP++ = tokenList.pop(); + } + + assert(ctrCurrent < 0x1000); + table[ctrCurrent].vByte = byte_49069; + table[ctrCurrent].vWord = currentToken; + ++ctrCurrent; + + currentToken = word_48054; + if ((ctrCurrent >= ctrMax) && (bitReader.numBits != 12)) { + // Move to the next higher bit-rate + ++bitReader.numBits; + ctrMax <<= 1; + } + } + } + + assert(bytesWritten == re->uncompressedSize); + delete compStream; + return dataOut; +} + +/** + * Finds the correct section and loads the specified resource within it + */ +byte *RlbManager::getResource(ResourceType resType, uint16 resNum, uint16 rlbNum, bool suppressErrors) { + SectionList::iterator i = _sections.begin(); + while ((i != _sections.end()) && ((*i).resType != resType || (*i).resNum != resNum)) + ++i; + if (i == _sections.end()) { + if (suppressErrors) + return NULL; + error("Unknown resource type %d num %d", resType, resNum); + } + + loadSection((*i).fileOffset); + + return getResource(rlbNum, suppressErrors); +} + +void RlbManager::loadIndex() { + uint16 resNum, configId, fileOffset; + + // Load the root resources section + loadSection(0); + + // Get the single resource from it + const byte *pData = getResource(0); + const byte *p = pData; + + _sections.clear(); + + // Loop through reading the entries + while ((resNum = READ_LE_UINT16(p)) != 0xffff) { + configId = READ_LE_UINT16(p + 2); + fileOffset = READ_LE_UINT16(p + 4); + p += 6; + + SectionEntry se; + se.resNum = resNum; + se.resType = (ResourceType)(configId & 0x1f); + se.fileOffset = (((configId >> 5) & 0x7ff) << 16) | fileOffset; + + _sections.push_back(se); + } + + _memoryManager.deallocate(pData); +} + +/** + * Retrieves the specified palette resource and returns it's data + * + * @paletteNum Specefies the palette number + */ +void RlbManager::getPalette(int paletteNum, uint8 *palData, uint *startNum, uint *numEntries) { + // Get the specified palette + byte *dataIn = getResource(RES_PALETTE, 0, paletteNum); + assert(dataIn); + + *startNum = READ_LE_UINT16(dataIn); + *numEntries = READ_LE_UINT16(dataIn + 2); + assert((*startNum < 256) && ((*startNum + *numEntries) <= 256)); + + // Copy over the data + for (uint i = 0; i < *numEntries; ++i) { + *palData++ = dataIn[6 + i * 3]; + *palData++ = dataIn[7 + i * 3]; + *palData++ = dataIn[8 + i * 3]; + *palData++ = 0; + } + + _memoryManager.deallocate(dataIn); +} + +byte *RlbManager::getSubResource(int resNum, int rlbNum, int index, uint *size) { + // Get the specified image set + byte *dataIn = getResource(RES_VISAGE, resNum, rlbNum); + assert(dataIn); + + int numEntries = READ_LE_UINT16(dataIn); + uint32 entryOffset = READ_LE_UINT32(dataIn + 2 + (index - 1) * 4); + uint32 nextOffset = (index == numEntries) ? + _memoryManager.getSize(dataIn) : READ_LE_UINT32(dataIn + 2 + index * 4); + *size = nextOffset - entryOffset; + assert(*size < (1024 * 1024)); + + byte *entry = _memoryManager.allocate2(*size); + Common::copy(&dataIn[entryOffset], &dataIn[nextOffset], entry); + + _memoryManager.deallocate(dataIn); + return entry; +} + +/** + * Retrieves a given message resource, and returns the specified message number + */ +Common::String RlbManager::getMessage(int resNum, int lineNum) { + byte *msgData = getResource(RES_MESSAGE, resNum, 0); + assert(msgData); + + const char *srcP = (const char *)msgData; + while (lineNum-- > 0) + srcP += strlen(srcP) + 1; + + Common::String result(srcP); + _memoryManager.deallocate(msgData); + return result; +} + +} // end of namespace tSage diff --git a/engines/tsage/resources.h b/engines/tsage/resources.h new file mode 100644 index 0000000000..5d00e5f70c --- /dev/null +++ b/engines/tsage/resources.h @@ -0,0 +1,166 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/resources.h $ + * $Id: resources.h 145 2011-01-08 11:41:39Z dreammaster $ + * + */ + +#ifndef RING_RESOURCES_H +#define RING_RESOURCES_H + +#include "common/scummsys.h" +#include "common/file.h" +#include "common/list.h" +#include "common/str.h" +#include "common/str-array.h" +#include "common/util.h" +#include "graphics/surface.h" + +namespace tSage { + +// Magic number used by original game to identify valid memory blocks +const uint32 MEMORY_ENTRY_ID = 0xE11DA722; + +const int MEMORY_POOL_SIZE = 1000; + +enum ResourceType { RES_LIBRARY, RES_STRIP, RES_IMAGE, RES_PALETTE, RES_VISAGE, RES_SOUND, RES_MESSAGE, + RES_FONT, RES_POINTER, RES_BANK, RES_SND_DRIVER, RES_PRIORITY, RES_CONTROL, RES_WALKRGNS, + RES_BITMAP, RES_SAVE, RES_SEQUENCE }; + +class MemoryHeader { +public: + uint32 id; + int16 index; + int lockCtr; + int criticalCtr; + uint8 tag; + uint32 size; + + MemoryHeader() { + id = 0; + index = 0; + lockCtr = 0; + criticalCtr = 0; + tag = 0; + size = 0; + } +}; + +class SectionEntry { +public: + ResourceType resType; + uint16 resNum; + uint32 fileOffset; + + SectionEntry() { + resType = RES_LIBRARY; + resNum = 0; + fileOffset = 0; + } +}; + +class ResourceEntry { +public: + uint16 id; + bool isCompressed; + uint32 fileOffset; + uint32 size; + uint32 uncompressedSize; + + ResourceEntry() { + id = 0; + isCompressed = false; + fileOffset = 0; + size = 0; + uncompressedSize = 0; + } +}; + +typedef Common::List<ResourceEntry> ResourceList; + +class SectionList: public Common::List<SectionEntry> { +public: + uint32 fileOffset; + + SectionList() { + fileOffset = 0; + } +}; + +class MemoryManager { +private: + MemoryHeader **_memoryPool; +public: + MemoryManager(); + ~MemoryManager(); + + uint16 allocate(uint32 size); + byte *allocate2(uint32 size); + byte *lock(uint32 handle); + int indexOf(const byte *p); + void deallocate(const byte *p); + void deallocate(uint16 handle) { assert("TODO"); } + uint32 getSize(const byte *p); + void incLocks(const byte *p); +}; + +class BitReader { +private: + Common::ReadStream &_stream; + uint8 _remainder, _bitsLeft; + byte readByte() { return _stream.eos() ? 0 : _stream.readByte(); } +public: + BitReader(Common::ReadStream &s): _stream(s) { + numBits = 9; + _remainder = 0; + _bitsLeft = 0; + } + uint16 readToken(); + + int numBits; +}; + +class RlbManager { +private: + Common::StringArray _resStrings; + MemoryManager &_memoryManager; +private: + Common::File _file; + ResourceList _resources; + SectionList _sections; + + void loadSection(uint32 fileOffset); + void loadIndex(); +public: + RlbManager(MemoryManager &memManager, const Common::String filename); + ~RlbManager(); + + byte *getResource(uint16 id, bool suppressErrors = false); + byte *getResource(ResourceType resType, uint16 resNum, uint16 rlbNum, bool suppressErrors = false); + void getPalette(int paletteNum, uint8 *palData, uint *startNum, uint *numEntries); + byte *getSubResource(int resNum, int rlbNum, int index, uint *size); + Common::String getMessage(int resNum, int lineNum); +}; + + +} // end of namespace tSage + +#endif diff --git a/engines/tsage/ringworld_logic.cpp b/engines/tsage/ringworld_logic.cpp new file mode 100644 index 0000000000..82d1b02d6b --- /dev/null +++ b/engines/tsage/ringworld_logic.cpp @@ -0,0 +1,1162 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/scene_logic.cpp $ + * $Id: scene_logic.cpp 232 2011-02-12 11:56:38Z dreammaster $ + * + */ + +#include "tsage/ringworld_logic.h" +#include "tsage/scenes.h" +#include "tsage/tsage.h" +#include "tsage/staticres.h" +#include "tsage/ringworld_scenes1.h" +#include "tsage/ringworld_scenes2.h" +#include "tsage/ringworld_scenes3.h" +#include "tsage/ringworld_scenes4.h" +#include "tsage/ringworld_scenes5.h" +#include "tsage/ringworld_scenes6.h" +#include "tsage/ringworld_scenes8.h" +#include "tsage/ringworld_scenes10.h" + +namespace tSage { + +Scene *SceneFactory::createScene(int sceneNumber) { + switch (sceneNumber) { + /* Scene group 1 */ + // Kziniti Palace (Introduction) + case 10: return new Scene10(); + // Outer Space (Introduction) + case 15: return new Scene15(); + // Cut-scenes for Ch'mee house in distance + case 20: return new Scene20(); + // Outside Ch'mee residence + case 30: return new Scene30(); + // Chmeee Home + case 40: return new Scene40(); + // By Flycycles + case 50: return new Scene50(); + // Flycycle controls + case 60: return new Scene60(); + // Shipyard Entrance + case 90: return new Scene90(); + // Ship Close-up + case 95: return new Scene95(); + // Sunflower navigation sequence + case 6100: return new Scene6100(); + + /* Scene group 2 */ + // Title screen + case 1000: return new Scene1000(); + // Fleeing planet cutscene + case 1001: return new Scene1001(); + // Unused + case 1250: return new Scene1250(); + // Ringworld Wall + case 1400: return new Scene1400(); + // Ringworld Space-port + case 1500: return new Scene1500(); + + /* Scene group 3 - Part #1 */ + // Cockpit cutscenes + case 2000: return new Scene2000(); + // Starcraft - Cockpit + case 2100: return new Scene2100(); + // Encyclopedia + case 2120: return new Scene2120(); + // Starcraft - Level 2 + case 2150: return new Scene2150(); + // Starcraft - AutoDoc + case 2200: return new Scene2200(); + // Stasis Field Map + case 2222: return new Scene2222(); + // Starcraft - Quinn's Room + case 2230: return new Scene2230(); + + /* Scene group 3 - Part #2 */ + // Starcraft - Storage Room + case 2280: return new Scene2280(); + // Starcraft - Hanger Bay + case 2300: return new Scene2300(); + // Starcraft - Copy Protection Screen + case 2310: return new Scene2310(); + // Starcraft - Lander Bay + case 2320: return new Scene2320(); + // Scene 2400 - Descending in Lander + case 2400: return new Scene2400(); + + /* Scene group 4 */ + // Ringworld Scan + case 3500: return new Scene3500(); + // Remote Viewer + case 3700: return new Scene3700(); + + /* Scene group 5 */ + // Village + case 4000: return new Scene4000(); + // Village - Outside Lander + case 4010: return new Scene4010(); + // Village - Puzzle Board + case 4025: return new Scene4025(); + // Village - Temple Antechamber + case 4045: return new Scene4045(); + // Village - Temple + case 4050: return new Scene4050(); + // Village - Hut + case 4100: return new Scene4100(); + // Village - Bedroom + case 4150: return new Scene4150(); + // Village - Near Slaver Ship + case 4250: return new Scene4250(); + // Village - Slaver Ship + case 4300: return new Scene4300(); + // Village - Slaver Ship Keypad + case 4301: return new Scene4301(); + + /* Scene group 6 */ + // Caverns - Entrance + case 5000: return new Scene5000(); + // Caverns + case 5100: return new Scene5100(); + // Caverns - Throne-room + case 5200: return new Scene5200(); + // Caverns - Pit + case 5300: return new Scene5300(); + + /* Scene group 8 */ + // Scene 7000: Landing + case 7000: return new Scene7000(); + // Scene 7100: swimming under water + case 7100: return new Scene7100(); + // Scene 7200: Entering the underwater cave + case 7200: return new Scene7200(); + // Scene 7300: Discussion with Lord Poria + case 7300: return new Scene7300(); + case 7600: return new Scene7600(); + case 7700: return new Scene7700(); + + /* Scene group 10 */ + case 9100: return new Scene9100(); + case 9150: return new Scene9150(); + case 9200: return new Scene9200(); + case 9300: return new Scene9300(); + case 9350: return new Scene9350(); + case 9360: return new Scene9360(); + case 9400: return new Scene9400(); + case 9450: return new Scene9450(); + case 9500: return new Scene9500(); + case 9700: return new Scene9700(); + case 9750: return new Scene9750(); + case 9850: return new Scene9850(); + // Scene 9900: Ending + case 9900: return new Scene9900(); + case 9999: return new Scene9999(); + + default: + error("Unknown scene number - %d", sceneNumber); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +DisplayHotspot::DisplayHotspot(int regionId, ...) { + _sceneRegionId = regionId; + + // Load up the actions + va_list va; + va_start(va, regionId); + + int param = va_arg(va, int); + while (param != LIST_END) { + _actions.push_back(param); + param = va_arg(va, int); + } + + va_end(va); +} + +bool DisplayHotspot::performAction(int action) { + for (uint i = 0; i < _actions.size(); i += 3) { + if (_actions[i] == action) { + display(_actions[i + 1], _actions[i + 2], SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + return true; + } + } + + return false; +} + +/*--------------------------------------------------------------------------*/ + +DisplayObject::DisplayObject(int firstAction, ...) { + // Load up the actions + va_list va; + va_start(va, firstAction); + + int param = firstAction; + while (param != LIST_END) { + _actions.push_back(param); + param = va_arg(va, int); + } + + va_end(va); +} + +bool DisplayObject::performAction(int action) { + for (uint i = 0; i < _actions.size(); i += 3) { + if (_actions[i] == action) { + display(_actions[i + 1], _actions[i + 2], SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + return true; + } + } + + return false; +} + +/*--------------------------------------------------------------------------*/ + +SceneArea::SceneArea() { + _savedArea = NULL; + _pt.x = _pt.y = 0; +} + +SceneArea::~SceneArea() { + delete _savedArea; +} + +void SceneArea::setup(int resNum, int rlbNum, int subNum, int actionId) { + _resNum = resNum; + _rlbNum = rlbNum; + _subNum = subNum; + _actionId = actionId; + + _surface = surfaceFromRes(resNum, rlbNum, subNum); +} + +void SceneArea::draw2() { + _surface.draw(Common::Point(_bounds.left, _bounds.top)); +} + +void SceneArea::display() { + _bounds.left = _pt.x - (_surface.getBounds().width() / 2); + _bounds.top = _pt.y + 1 - _surface.getBounds().height(); + _bounds.setWidth(_surface.getBounds().width()); + _bounds.setHeight(_surface.getBounds().height()); + + _savedArea = Surface_getArea(_globals->_gfxManagerInstance.getSurface(), _bounds); + draw2(); +} + +void SceneArea::restore() { + assert(_savedArea); + _savedArea->draw(Common::Point(_bounds.left, _bounds.top)); + delete _savedArea; + _savedArea = NULL; +} + +void SceneArea::draw(bool flag) { + _surface = surfaceFromRes(_resNum, _rlbNum, flag ? _subNum + 1 : _subNum); + _surface.draw(Common::Point(_bounds.left, _bounds.top)); +} + +void SceneArea::wait() { + // Wait until a mouse or keypress + Event event; + while (!_vm->getEventManager()->shouldQuit() && !_globals->_events.getEvent(event)) { + g_system->updateScreen(); + g_system->delayMillis(10); + } + + List<SceneItem *>::iterator ii; + for (ii = _globals->_sceneItems.begin(); ii != _globals->_sceneItems.end(); ++ii) { + SceneItem *sceneItem = *ii; + if (sceneItem->contains(event.mousePos)) { + sceneItem->doAction(_actionId); + break; + } + } + + _globals->_events.setCursor(CURSOR_ARROW); +} + +void SceneArea::synchronise(Serialiser &s) { + s.syncAsSint16LE(_pt.x); + s.syncAsSint16LE(_pt.y); + s.syncAsSint32LE(_resNum); + s.syncAsSint32LE(_rlbNum); + s.syncAsSint32LE(_subNum); + s.syncAsSint32LE(_actionId); + _bounds.synchronise(s); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerGText::SpeakerGText() { + _speakerName = "GTEXT"; + _textWidth = 160; + _textPos = Common::Point(130, 10); + _colour1 = 42; + _hideObjects = false; +} + +void SpeakerGText::setText(const Common::String &msg) { + // Set the animation properties + _sceneObject.postInit(); + _sceneObject.setVisage(9405); + _sceneObject.setStrip2(3); + _sceneObject.setPriority2(255); + _sceneObject.changeZoom(100); + _sceneObject._frame = 1; + _sceneObject.setPosition(Common::Point(183, 71)); + _sceneObject.animate(ANIM_MODE_7, 0, NULL); + + // Set the text + Rect textRect; + _globals->gfxManager()._font.getStringBounds(msg.c_str(), textRect, _textWidth); + textRect.centre(_sceneObject._position.x, _sceneObject._position.y); + _textPos.x = textRect.left; + Speaker::setText(msg); +} + +void SpeakerGText::removeText() { + _sceneObject.remove(); + Speaker::removeText(); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerPOR::SpeakerPOR() { + _speakerName = "POR"; + _newSceneNumber = 7221; + _textPos = Common::Point(10, 30); + _colour1 = 41; +} + +void SpeakerPOR::SpeakerAction1::signal(){ + switch (_actionIndex++) { + case 0: + setDelay(_globals->_randomSource.getRandomNumber(60) + 60); + break; + case 1: + static_cast<SceneObject *>(_owner)->animate(ANIM_MODE_5, this, NULL); + break; + case 2: + setDelay(_globals->_randomSource.getRandomNumber(10)); + _actionIndex = 0; + break; + default: + break; + } +} + +void SpeakerPOR::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(7223); + _object1.setStrip2(2); + _object1.setPosition(Common::Point(191, 166), 0); + _object1.animate(ANIM_MODE_7, 0, 0); + + _object2.postInit(&_objectList); + _object2.setVisage(7223); + _object2.setPosition(Common::Point(159, 86), 0); + _object2.setAction(&_speakerAction, 0); + + _object3.postInit(&_objectList); + _object3.setVisage(7223); + _object3.setStrip(3); + _object3.setPosition(Common::Point(119, 107), 0); + _object3.setPriority2(199); + _object3.setAction(&_action2); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerOR::SpeakerOR() { + _speakerName = "OR"; + _newSceneNumber = 9430; + _textPos = Common::Point(8, 36); + _colour1 = 42; + _textWidth = 136; +} + +void SpeakerOR::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(9431); + _object1.setStrip2(2); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(202, 147), 0); + _object1.animate(ANIM_MODE_7, 0, 0); + + _object2.postInit(&_objectList); + _object2.setVisage(9431); + _object2.setStrip2(1); + _object2.setPriority2(255); + _object2.setZoom(100); + _object2._frame = 1; + _object2.setPosition(Common::Point(199, 85), 0); + _object2.setAction(&_speakerAction, 0); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerOText::SpeakerOText(): SpeakerGText() { + _speakerName = "OTEXT"; + _textWidth = 240; + _textPos = Common::Point(130, 10); + _colour1 = 42; + _hideObjects = false; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerQText::SpeakerQText(): ScreenSpeaker() { + _speakerName = "QTEXT"; + _textPos = Common::Point(160, 40); + _colour1 = 35; + _textWidth = 240; + _textMode = ALIGN_CENTRE; + _hideObjects = false; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerSText::SpeakerSText(): ScreenSpeaker() { + _speakerName = "STEXT"; + _colour1 = 13; + _textWidth = 240; + _textMode = ALIGN_CENTRE; + _hideObjects = false; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerPOText::SpeakerPOText(): ScreenSpeaker() { + _speakerName = "POTEXT"; + _textWidth = 240; + _textMode = ALIGN_CENTRE; + _colour1 = 41; + _hideObjects = false; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerMText::SpeakerMText() { + _speakerName = "MTEXT"; + _colour1 = 11; + _textWidth = 160; + _textMode = ALIGN_CENTRE; + _hideObjects = false; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerCText::SpeakerCText() { + _speakerName = "CTEXT"; + _colour1 = 4; + _textWidth = 240; + _textMode = ALIGN_CENTRE; + _hideObjects = false; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerEText::SpeakerEText() { + _speakerName = "ETEXT"; + _textPos = Common::Point(20, 20); + _colour1 = 22; + _hideObjects = false; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerGR::SpeakerGR() { + _speakerName = "GR"; + _newSceneNumber = 9220; + _textWidth = 136; + _textPos = Common::Point(168, 36); + _colour1 = 14; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerHText::SpeakerHText() { + _speakerName = "HTEXT"; + _textPos = Common::Point(160, 40); + _colour1 = 52; + _hideObjects = false; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerSKText::SpeakerSKText(): ScreenSpeaker() { + _speakerName = "SKTEXT"; + _textWidth = 240; + _textMode = ALIGN_CENTRE; + _colour1 = 5; + _hideObjects = false; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerPText::SpeakerPText() { + _speakerName = "PTEXT"; + _textWidth = 240; + _textMode = ALIGN_CENTRE; + _colour1 = 5; + _hideObjects = false; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerCHFText::SpeakerCHFText() { + _speakerName = "CHFTEXT"; + _textWidth = 240; + _textMode = ALIGN_CENTRE; + _colour1 = 56; + _hideObjects = false; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerCDRText::SpeakerCDRText() { + _speakerName = "CDRTEXT"; + _textWidth = 240; + _textMode = ALIGN_CENTRE; + _colour1 = 52; + _hideObjects = false; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerFLText::SpeakerFLText() { + _speakerName = "FLTEXT"; + _textPos = Common::Point(10, 40); + _colour1 = 17; + _hideObjects = false; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerBatText::SpeakerBatText() { + _speakerName = "BATTEXT"; + _textWidth = 240; + _textMode = ALIGN_CENTRE; + _colour1 = 3; + _hideObjects = false; +} + +/*--------------------------------------------------------------------------*/ + +SpeakerSKL::SpeakerSKL(): AnimatedSpeaker() { + _speakerName = "SKL"; + _newSceneNumber = 7011; + _textPos = Common::Point(10, 30); + _colour1 = 10; +} + +void SpeakerSKL::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(7013); + _object1.setStrip2(2); + _object1._frame = 1; + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1.setPosition(Common::Point(203, 120)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(7013); + _object2.setStrip2(1); + _object2.setPriority2(255); + _object2.changeZoom(100); + _object2._frame = 1; + _object2.setPosition(Common::Point(197, 80)); + _object2.setAction(&_speakerAction, NULL); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerQL::SpeakerQL(): AnimatedSpeaker() { + _speakerName = "QL"; + _newSceneNumber = 2610; + _textPos = Common::Point(160, 30); + _colour1 = 35; + _textMode = ALIGN_CENTRE; +} + +void SpeakerQL::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(2612); + _object1.setStrip2(2); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(128, 146)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(2612); + _object2.setStrip2(1); + _object2.setPriority2(255); + _object2.changeZoom(100); + _object2._frame = 1; + _object2.setPosition(Common::Point(122, 84)); + _object2.setAction(&_speakerAction, NULL); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerSR::SpeakerSR() { + _speakerName = "SR"; + _newSceneNumber = 2811; + _textPos = Common::Point(10, 30); + _colour1 = 13; + _textMode = ALIGN_CENTRE; +} + +void SpeakerSR::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(2813); + _object1.setStrip2(2); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(224, 198)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(2813); + _object2.setStrip2(1); + _object2.setPriority2(255); + _object2.changeZoom(100); + _object2._frame = 1; + _object2.setPosition(Common::Point(203, 96)); + _object2.setAction(&_speakerAction, NULL); + + _object3.postInit(&_objectList); + _object3.setVisage(2813); + _object3.setStrip(3); + _object3.setPosition(Common::Point(204, 91)); + _object3.setPriority2(199); + _object3._numFrames = 3; + _object3.animate(ANIM_MODE_7, 0, NULL); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerSL::SpeakerSL() { + _speakerName = "SL"; + _newSceneNumber = 2810; + _textPos = Common::Point(140, 30); + _textWidth = 160; + _colour1 = 13; + _textMode = ALIGN_CENTRE; +} + +void SpeakerSL::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(2812); + _object1.setStrip2(2); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(95, 198)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(2812); + _object2.setStrip2(1); + _object2.setPriority2(255); + _object2.changeZoom(100); + _object2._frame = 1; + _object2.setPosition(Common::Point(116, 96)); + _object2.setAction(&_speakerAction, NULL); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerQR::SpeakerQR() { + _speakerName = "QR"; + _newSceneNumber = 2611; + _textPos = Common::Point(10, 30); + _colour1 = 13; + _textMode = ALIGN_CENTRE; +} + +void SpeakerQR::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(2613); + _object1.setStrip2(2); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(191, 146)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(2613); + _object2.setStrip2(1); + _object2.setPriority2(255); + _object2.changeZoom(100); + _object2._frame = 1; + _object2.setPosition(Common::Point(197, 84)); + _object2.setAction(&_speakerAction, NULL); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerQU::SpeakerQU() { + _speakerName = "QU"; + _newSceneNumber = 7020; + _textPos = Common::Point(160, 30); + _colour1 = 35; + _textMode = ALIGN_CENTRE; +} + +void SpeakerQU::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(7021); + _object1.setStrip2(2); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(116, 120), 0); + _object1.animate(ANIM_MODE_7, 0, 0); + + _object2.postInit(&_objectList); + _object2.setVisage(7021); + _object2.setStrip2(1); + _object2.setPriority2(255); + _object2.changeZoom(100); + _object2._frame = 1; + _object2.setPosition(Common::Point(111, 84), 0); + _object2.setAction(&_speakerAction, 0); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerCR::SpeakerCR() { + _speakerName = "CR"; + _newSceneNumber = 9010; + _textPos = Common::Point(20, 40); + _colour1 = 4; +} + +void SpeakerCR::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(9011); + _object1.setStrip2(2); + _object1.setPriority2(255); + _object1.setPosition(Common::Point(219, 168)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(9011); + _object2.setStrip2(1); + _object2.setPriority2(255); + _object2.setPosition(Common::Point(232, 81)); + _object2.setAction(&_speakerAction, NULL); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerMR::SpeakerMR() { + _speakerName = "MR"; + _newSceneNumber = 2711; + _textPos = Common::Point(40, 10); + _colour1 = 22; +} + +void SpeakerMR::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(2713); + _object1.setStrip2(2); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(220, 143)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(2713); + _object2.setStrip2(1); + _object2.setPriority2(255); + _object2._frame = 1; + _object2.setPosition(Common::Point(215, 99)); + _object2.setAction(&_speakerAction, NULL); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerSAL::SpeakerSAL() { + _speakerName = "SAL"; + _newSceneNumber = 2851; + _textPos = Common::Point(10, 30); + _colour1 = 13; + _textMode = ALIGN_CENTRE; +} + +void SpeakerSAL::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(2853); + _object1.setStrip2(2); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(185, 200)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(2853); + _object2.setStrip2(1); + _object2.setPriority2(255); + _object2._frame = 1; + _object2.setPosition(Common::Point(170, 92)); + _object2.setAction(&_speakerAction, NULL); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerML::SpeakerML() { + _speakerName = "ML"; + _newSceneNumber = 2710; + _textPos = Common::Point(160, 40); + _colour1 = 22; +} + +void SpeakerML::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(2712); + _object1.setStrip2(2); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(99, 143)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(2712); + _object2.setStrip2(1); + _object2.setPriority2(255); + _object2._frame = 1; + _object2.setPosition(Common::Point(105, 99)); + _object2.setAction(&_speakerAction, NULL); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerCHFL::SpeakerCHFL() { + _speakerName = "CHFL"; + _newSceneNumber = 4111; + _textPos = Common::Point(10, 40); + _colour1 = 56; +} + +void SpeakerCHFL::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(4113); + _object1.setStrip2(2); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(205, 116)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(4113); + _object2.setStrip2(1); + _object2.setPriority2(255); + _object2._frame = 1; + _object2.setPosition(Common::Point(202, 71)); + _object2.setAction(&_speakerAction, NULL); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerCHFR::SpeakerCHFR() { + _speakerName = "CHFR"; + _newSceneNumber = 4110; + _textPos = Common::Point(160, 40); + _colour1 = 56; +} + +void SpeakerCHFR::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(4112); + _object1.setStrip2(2); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(103, 116)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(4112); + _object2.setStrip2(1); + _object2.setPriority2(255); + _object2._frame = 1; + _object2.setPosition(Common::Point(106, 71)); + _object2.setAction(&_speakerAction, NULL); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerPL::SpeakerPL() { + _speakerName = "PL"; + _newSceneNumber = 4060; + _textPos = Common::Point(160, 40); + _colour1 = 5; +} + +void SpeakerPL::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(4062); + _object1.setStrip2(2); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(107, 117)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(4062); + _object2.setStrip2(1); + _object2.setPriority2(200); + _object2._frame = 1; + _object2.setPosition(Common::Point(105, 62)); + _object2.setAction(&_speakerAction, NULL); + + _object3.postInit(&_objectList); + _object3.setVisage(4062); + _object3.setStrip2(3); + _object3.setPriority2(255); + _object3._frame = 1; + _object3.setPosition(Common::Point(105, 59)); + _object3.setAction(&_speakerAction2, NULL); + + Speaker::setText(msg); +} + +void SpeakerPL::removeText() { + _object3.remove(); + AnimatedSpeaker::removeText(); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerPR::SpeakerPR() { + _speakerName = "PR"; + _newSceneNumber = 4061; + _textPos = Common::Point(10, 40); + _colour1 = 5; +} + +void SpeakerPR::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(4063); + _object1.setStrip2(1); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(212, 117)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(4063); + _object2.setStrip2(2); + _object2.setPriority2(200); + _object2.changeZoom(100); + _object2._frame = 1; + _object2.setPosition(Common::Point(214, 62)); + _object2.setAction(&_speakerAction, NULL); + + _object3.postInit(&_objectList); + _object3.setVisage(4063); + _object3.setStrip2(3); + _object3.setPriority2(255); + _object3.changeZoom(100); + _object3._frame = 1; + _object3.setPosition(Common::Point(214, 59)); + _object3.setAction(&_speakerAction2, NULL); + + Speaker::setText(msg); +} + +void SpeakerPR::removeText() { + _object3.remove(); + AnimatedSpeaker::removeText(); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerCDR::SpeakerCDR() { + _speakerName = "CDR"; + _newSceneNumber = 4161; + _textPos = Common::Point(10, 40); + _colour1 = 52; +} + +void SpeakerCDR::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(4163); + _object1.setStrip2(1); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(208, 97)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(4163); + _object2.setStrip2(2); + _object2.setPriority2(255); + _object2.changeZoom(100); + _object2._frame = 1; + _object2.setPosition(Common::Point(200, 57)); + _object2.setAction(&_speakerAction, NULL); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerCDL::SpeakerCDL() { + _speakerName = "CDL"; + _newSceneNumber = 4160; + _textPos = Common::Point(160, 40); + _colour1 = 52; +} + +void SpeakerCDL::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(4162); + _object1.setStrip2(1); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(112, 97)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(4162); + _object2.setStrip2(2); + _object2.setPriority2(255); + _object2.changeZoom(100); + _object2._frame = 1; + _object2.setPosition(Common::Point(115, 57)); + _object2.setAction(&_speakerAction, NULL); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerFLL::SpeakerFLL() { + _speakerName = "FLL"; + _newSceneNumber = 5221; + _textPos = Common::Point(10, 40); + _colour1 = 17; +} + +void SpeakerFLL::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(5223); + _object1.setStrip2(2); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(216, 129)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(5223); + _object2.setStrip2(1); + _object2.setPriority2(255); + _object2.changeZoom(100); + _object2._frame = 1; + _object2.setPosition(Common::Point(210, 67)); + _object2.setAction(&_speakerAction, NULL); + + Speaker::setText(msg); +} + +/*--------------------------------------------------------------------------*/ + +SpeakerBatR::SpeakerBatR() { + _speakerName = "BATR"; + _newSceneNumber = 5360; + _textPos = Common::Point(140, 40); + _colour1 = 3; +} + +void SpeakerBatR::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(5361); + _object1.setStrip2(2); + _object1.setPriority2(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(137, 122)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + _object2.postInit(&_objectList); + _object2.setVisage(5361); + _object2.setStrip2(1); + _object2.setPriority2(255); + _object2.changeZoom(100); + _object2._frame = 1; + _object2.setPosition(Common::Point(137, 104)); + _object2.setAction(&_speakerAction, NULL); + + Speaker::setText(msg); +} + +} // End of namespace tSage diff --git a/engines/tsage/ringworld_logic.h b/engines/tsage/ringworld_logic.h new file mode 100644 index 0000000000..fd3264e403 --- /dev/null +++ b/engines/tsage/ringworld_logic.h @@ -0,0 +1,402 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/scene_logic.h $ + * $Id: scene_logic.h 232 2011-02-12 11:56:38Z dreammaster $ + * + */ + +#ifndef TSAGE_RINGWORLD_LOGIC_H +#define TSAGE_RINGWORLD_LOGIC_H + +#include "common/scummsys.h" +#include "tsage/events.h" +#include "tsage/core.h" +#include "tsage/scenes.h" +#include "tsage/globals.h" + +namespace tSage { + +#define ADD_PLAYER_MOVER(X, Y) { Common::Point pt(X, Y); PlayerMover *mover = new PlayerMover(); \ + _globals->_player.addMover(mover, &pt, this); } +#define ADD_PLAYER_MOVER_NULL(OBJ, X, Y) { Common::Point pt(X, Y); PlayerMover *mover = new PlayerMover(); \ + OBJ.addMover(mover, &pt, NULL); } +#define ADD_PLAYER_MOVER_THIS(OBJ, X, Y) { Common::Point pt(X, Y); PlayerMover *mover = new PlayerMover(); \ + OBJ.addMover(mover, &pt, this); } + +#define ADD_MOVER(OBJ, X, Y) { Common::Point pt(X, Y); NpcMover *mover = new NpcMover(); \ + OBJ.addMover(mover, &pt, this); } +#define ADD_MOVER_NULL(OBJ, X, Y) { Common::Point pt(X, Y); NpcMover *mover = new NpcMover(); \ + OBJ.addMover(mover, &pt, NULL); } + + +class SceneFactory { +public: + static Scene *createScene(int sceneNumber); +}; + +class DisplayHotspot: public SceneObject { +private: + Common::Array<int> _actions; + bool performAction(int action); +public: + DisplayHotspot(int regionId, ...); + + virtual void doAction(int action) { + if (!performAction(action)) + SceneHotspot::doAction(action); + } +}; + +class DisplayObject: public SceneObject { +private: + Common::Array<int> _actions; + bool performAction(int action); +public: + DisplayObject(int firstAction, ...); + + virtual void doAction(int action) { + if (!performAction(action)) + SceneHotspot::doAction(action); + } +}; + +class SceneArea: public SavedObject { +public: + GfxSurface _surface; + GfxSurface *_savedArea; + Common::Point _pt; + int _resNum; + int _rlbNum; + int _subNum; + int _actionId; + Rect _bounds; +public: + SceneArea(); + ~SceneArea(); + + void setup(int resNum, int rlbNum, int subNum, int actionId); + void draw2(); + void display(); + void restore(); + + virtual void synchronise(Serialiser &s); + virtual void draw(bool flag); + virtual void wait(); +}; + +/*--------------------------------------------------------------------------*/ +// Ringworld specific game speakers + +class SpeakerGText: public Speaker { +public: + SceneObject _sceneObject; +public: + SpeakerGText(); + + virtual Common::String getClassName() { return "SpeakerGText"; } + virtual void setText(const Common::String &msg); + virtual void removeText(); +}; + +class SpeakerPOR: public AnimatedSpeaker { + class SpeakerAction1: public SpeakerAction { + public: + virtual void signal(); + }; + +public: + SceneObject _object3; + SpeakerAction1 _action2; +public: + SpeakerPOR(); + virtual Common::String getClassName() { return "SpeakerPOR"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerOR: public AnimatedSpeaker { +public: + SpeakerOR(); + virtual Common::String getClassName() { return "SpeakerOR"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerOText: public SpeakerGText { +public: + SpeakerOText(); + + virtual Common::String getClassName() { return "SpeakerOText"; } +}; + +class SpeakerPOText: public ScreenSpeaker { +public: + SpeakerPOText(); + + virtual Common::String getClassName() { return "SpeakerPOText"; } +}; + +class SpeakerSText: public ScreenSpeaker { +public: + SpeakerSText(); + + virtual Common::String getClassName() { return "SpeakerSText"; } +}; + +class SpeakerQText: public ScreenSpeaker { +public: + SpeakerQText(); + + virtual Common::String getClassName() { return "SpeakerQText"; } +}; + +class SpeakerMText: public ScreenSpeaker { +public: + SpeakerMText(); + + virtual Common::String getClassName() { return "SpeakerMText"; } +}; + +class SpeakerCText: public ScreenSpeaker { +public: + SpeakerCText(); + + virtual Common::String getClassName() { return "SpeakerCText"; } +}; + +class SpeakerEText: public ScreenSpeaker { +public: + SpeakerEText(); + + virtual Common::String getClassName() { return "SpeakerEText"; } +}; + +class SpeakerGR: public AnimatedSpeaker { +public: + SpeakerGR(); + + virtual Common::String getClassName() { return "SpeakerGR"; } +}; + +class SpeakerHText: public ScreenSpeaker { +public: + SpeakerHText(); + + virtual Common::String getClassName() { return "SpeakerHText"; } +}; + +class SpeakerPText: public ScreenSpeaker { +public: + SpeakerPText(); + + virtual Common::String getClassName() { return "SpeakerPText"; } +}; + +class SpeakerCHFText: public ScreenSpeaker { +public: + SpeakerCHFText(); + + virtual Common::String getClassName() { return "SpeakerCHFText"; } +}; + +class SpeakerSKText: public ScreenSpeaker { +public: + SpeakerSKText(); + + virtual Common::String getClassName() { return "SpeakerSKText"; } +}; + +class SpeakerCDRText: public ScreenSpeaker { +public: + SpeakerCDRText(); + + virtual Common::String getClassName() { return "SpeakerCDRText"; } +}; + +class SpeakerFLText: public ScreenSpeaker { +public: + SpeakerFLText(); + + virtual Common::String getClassName() { return "SpeakerFLText"; } +}; + +class SpeakerBatText: public ScreenSpeaker { +public: + SpeakerBatText(); + + virtual Common::String getClassName() { return "SpeakerFLText"; } +}; + +class SpeakerQR: public AnimatedSpeaker { +public: + SpeakerQR(); + + virtual Common::String getClassName() { return "SpeakerQR"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerQU: public AnimatedSpeaker { +public: + SpeakerQU(); + + virtual Common::String getClassName() { return "SpeakerQU"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerSKL: public AnimatedSpeaker { +public: + SpeakerSKL(); + + virtual Common::String getClassName() { return "SpeakerQL"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerQL: public AnimatedSpeaker { +public: + SpeakerQL(); + + virtual Common::String getClassName() { return "SpeakerQL"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerSR: public AnimatedSpeaker { +public: + SceneObject _object3; +public: + SpeakerSR(); + + virtual Common::String getClassName() { return "SpeakerSR"; } + void setText(const Common::String &msg); +}; + +class SpeakerSL: public AnimatedSpeaker { +public: + SpeakerSL(); + + virtual Common::String getClassName() { return "SpeakerSL"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerCR: public AnimatedSpeaker { +public: + SpeakerCR(); + + virtual Common::String getClassName() { return "SpeakerCR"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerMR: public AnimatedSpeaker { +public: + SpeakerMR(); + + virtual Common::String getClassName() { return "SpeakerMR"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerSAL: public AnimatedSpeaker { +public: + SpeakerSAL(); + + virtual Common::String getClassName() { return "SpeakerSAL"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerML: public AnimatedSpeaker { +public: + SpeakerML(); + + virtual Common::String getClassName() { return "SpeakerML"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerCHFL: public AnimatedSpeaker { +public: + SpeakerCHFL(); + + virtual Common::String getClassName() { return "SpeakerCHFL"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerCHFR: public AnimatedSpeaker { +public: + SpeakerCHFR(); + + virtual Common::String getClassName() { return "SpeakerCHFR"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerPL: public AnimatedSpeaker { +public: + SceneObject _object3; + SpeakerAction _speakerAction2; + + SpeakerPL(); + + virtual Common::String getClassName() { return "SpeakerPL"; } + virtual void setText(const Common::String &msg); + virtual void removeText(); +}; + +class SpeakerPR: public AnimatedSpeaker { +public: + SceneObject _object3; + SpeakerAction _speakerAction2; + + SpeakerPR(); + + virtual Common::String getClassName() { return "SpeakerPR"; } + virtual void setText(const Common::String &msg); + virtual void removeText(); +}; + +class SpeakerCDR: public AnimatedSpeaker { +public: + SpeakerCDR(); + + virtual Common::String getClassName() { return "SpeakerCDR"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerCDL: public AnimatedSpeaker { +public: + SpeakerCDL(); + + virtual Common::String getClassName() { return "SpeakerCDL"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerFLL: public AnimatedSpeaker { +public: + SpeakerFLL(); + + virtual Common::String getClassName() { return "SpeakerFLL"; } + virtual void setText(const Common::String &msg); +}; + +class SpeakerBatR: public AnimatedSpeaker { +public: + SpeakerBatR(); + + virtual Common::String getClassName() { return "SpeakerBatR"; } + virtual void setText(const Common::String &msg); +}; + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/ringworld_scenes1.cpp b/engines/tsage/ringworld_scenes1.cpp new file mode 100644 index 0000000000..f847943bc5 --- /dev/null +++ b/engines/tsage/ringworld_scenes1.cpp @@ -0,0 +1,3263 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/scene_logic.cpp $ + * $Id: scene_logic.cpp 232 2011-02-12 11:56:38Z dreammaster $ + * + */ + +#include "tsage/ringworld_scenes1.h" +#include "tsage/scenes.h" +#include "tsage/tsage.h" +#include "tsage/staticres.h" + +namespace tSage { + +/*-------------------------------------------------------------------------- + * Scene 10 - Kziniti Palace (Introduction) + * + *--------------------------------------------------------------------------*/ + +void Scene10::Action1::signal() { + Scene10 *scene = (Scene10 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(6); + break; + case 1: + _globals->_scenePalette.addRotation(240, 254, -1); + scene->_stripManager.start(10, this); + break; + case 2: + scene->_speakerSText.setTextPos(Common::Point(20, 20)); + scene->_speakerSText._colour1 = 10; + scene->_speakerSText._textWidth = 160; + scene->_stripManager.start(11, this, scene); + break; + case 3: + scene->_object2.hide(); + scene->_object3.hide(); + scene->_object3.setAction(NULL); + scene->_object4.animate(ANIM_MODE_5, this); + break; + case 4: + case 9: + scene->_object1.animate(ANIM_MODE_5, this); + break; + case 5: + scene->_object2.setStrip(3); + scene->_object2.setFrame(1); + scene->_object2.setPosition(Common::Point(240, 51)); + scene->_object2.show(); + + scene->_object3.setStrip(6); + scene->_object3.setFrame(1); + scene->_object3.setPosition(Common::Point(200, 76)); + scene->_object3._numFrames = 20; + scene->_object3.show(); + + scene->_stripManager.start(12, this, scene); + break; + case 6: + scene->_object2.hide(); + scene->_object3.hide(); + scene->_object1.animate(ANIM_MODE_6, this); + break; + case 7: + scene->_object3.show(); + scene->_object3.setStrip2(5); + scene->_object3._numFrames = 10; + scene->_object3.setPosition(Common::Point(180, 87)); + scene->_object3.setAction(&scene->_action2); + + scene->_object2.setStrip(4); + scene->_object2.setFrame(1); + scene->_object2.setPosition(Common::Point(204, 59)); + scene->_object2.show(); + + scene->_stripManager.start(13, this, scene); + break; + case 8: + scene->_object2.hide(); + scene->_object3.hide(); + scene->_object4.animate(ANIM_MODE_6, this); + break; + case 10: + _globals->_soundHandler.proc1(this); + break; + case 11: + _globals->_scenePalette.clearListeners(); + _globals->_sceneManager.changeScene(15); + break; + } +} + +void Scene10::Action2::signal() { + Scene10 *scene = (Scene10 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(_globals->_randomSource.getRandomNumber(179)); + break; + case 1: + scene->_object3.setFrame(1); + scene->_object3.animate(ANIM_MODE_5, this); + _actionIndex = 0; + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene10::postInit(SceneObjectList *OwnerList) { + loadScene(10); + setZoomPercents(0, 100, 200, 100); + + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerQText); + _speakerSText._speakerName = "STEXT"; + _speakerQText._speakerName = "QTEXT"; + _speakerSText._hideObjects = false; + _speakerQText._hideObjects = false; + _speakerQText.setTextPos(Common::Point(140, 120)); + _speakerQText._colour1 = 4; + _speakerQText._textWidth = 160; + _speakerSText.setTextPos(Common::Point(20, 20)); + _speakerSText._colour1 = 7; + _speakerSText._textWidth = 320; + + _stripManager.setCallback(this); + + _object1.postInit(); + _object1.setVisage(10); + _object1.setPosition(Common::Point(232, 90)); + _object1.setPriority2(1); + + _object2.postInit(); + _object2.setVisage(10); + _object2.setStrip(4); + _object2.setFrame(1); + _object2.setPosition(Common::Point(204, 59)); + _object2.setPriority2(198); + + _object3.postInit(); + _object3.setVisage(10); + _object3.setStrip2(5); + _object3.setPosition(Common::Point(180, 87)); + _object3.setPriority2(196); + _object3.setAction(&_action2); + + _object4.postInit(); + _object4.setVisage(10); + _object4.setStrip(2); + _object4.setPosition(Common::Point(0, 209)); + _object4.animate(ANIM_MODE_1, NULL); + + _object5.postInit(); + _object5.setVisage(11); + _object5.setPosition(Common::Point(107, 146)); + _object5.animate(ANIM_MODE_2, NULL); + _object5._numFrames = 5; + + _object6.postInit(); + _object6.setVisage(11); + _object6.setStrip(2); + _object6.setPosition(Common::Point(287, 149)); + _object6.animate(ANIM_MODE_2, NULL); + _object6._numFrames = 5; + + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160; + + setAction(&_action1); + _globals->_soundHandler.startSound(5); +} + +void Scene10::stripCallback(int v) { + switch (v) { + case 1: + _object2.animate(ANIM_MODE_7, -1, NULL); + break; + case 2: + _object2.animate(ANIM_MODE_NONE); + break; + case 3: + _object2.animate(ANIM_MODE_7, -1, NULL); + _object3.animate(ANIM_MODE_5, NULL); + break; + default: + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 15 - Outer Space (Introduction) + * + *--------------------------------------------------------------------------*/ + +void Scene15::Action1::signal() { + Scene15 *scene = (Scene15 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(60); + break; + case 1: + SceneItem::display(15, 0, SET_Y, 20, SET_FONT, 2, SET_BG_COLOUR, -1, SET_EXT_BGCOLOUR, 7, + SET_WIDTH, 320, SET_KEEP_ONSCREEN, 1, LIST_END); + setDelay(300); + break; + case 2: { + SceneItem::display(15, 1, SET_Y, 20, SET_FONT, 2, SET_BG_COLOUR, -1, SET_EXT_BGCOLOUR, 7, + SET_WIDTH, 320, SET_KEEP_ONSCREEN, 1, LIST_END); + scene->_object1.postInit(); + scene->_object1.setVisage(15); + scene->_object1.setPosition(Common::Point(160, -10)); + scene->_object1.animate(ANIM_MODE_2, NULL); + Common::Point pt(160, 100); + NpcMover *mover = new NpcMover(); + scene->_object1.addMover(mover, &pt, this); + scene->_soundHandler.startSound(7); + break; + } + case 3: + SceneItem::display(0, 0); + _globals->_sceneManager.changeScene(20); + break; + } +} + +void Scene15::Action1::dispatch() { + Scene15 *scene = (Scene15 *)_globals->_sceneManager._scene; + + if (scene->_object1._position.y < 100) + scene->_object1.changeZoom(100 - scene->_object1._position.y); + Action::dispatch(); +} + +/*--------------------------------------------------------------------------*/ + +void Scene15::postInit(SceneObjectList *OwnerList) { + loadScene(15); + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + _globals->_soundHandler.startSound(6); + setAction(&_action1); +} + +/*-------------------------------------------------------------------------- + * Scene 20 - Cut-scenes where House Chmeee is in the distance + * + *--------------------------------------------------------------------------*/ + +void Scene20::Action1::signal() { + Scene20 *scene = (Scene20 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(120); + break; + case 1: + scene->_stripManager.start(20, this); + break; + case 2: + _globals->_soundHandler.proc1(this); + break; + case 3: + _globals->_sceneManager._fadeMode = FADEMODE_GRADUAL; + _globals->_sceneManager.changeScene(30); // First game scene + break; + default: + break; + } +} + +void Scene20::Action2::signal() { + Scene20 *scene = (Scene20 *)_globals->_sceneManager._scene; + NpcMover *npcMover; + + switch (_actionIndex++) { + case 0: + setDelay(10); + break; + case 1: + SceneItem::display(20, 1, SET_WIDTH, 200, SET_Y, 20, SET_X, 160, SET_KEEP_ONSCREEN, true, + SET_EXT_BGCOLOUR, 4, LIST_END); + setDelay(120); + break; + case 2: { + NpcMover *mover = new NpcMover(); + Common::Point pt(455, 77); + _globals->_player.addMover(mover, &pt, this); + ObjectMover2 *mover2 = new ObjectMover2(); + scene->_SceneObjectExt.addMover(mover2, 5, 10, &_globals->_player); + ObjectMover2 *mover3 = new ObjectMover2(); + scene->_sceneObject3.addMover(mover3, 10, 15, &_globals->_player); + break; + } + case 3: { + npcMover = new NpcMover(); + Common::Point pt(557, 100); + _globals->_player.addMover(npcMover, &pt, this); + break; + } + case 4: { + npcMover = new NpcMover(); + Common::Point pt(602, 90); + _globals->_player.addMover(npcMover, &pt, this); + break; + } + case 5: { + npcMover = new NpcMover(); + Common::Point pt(618, 90); + _globals->_player.addMover(npcMover, &pt, this); + break; + } + case 6: { + npcMover = new NpcMover(); + Common::Point pt(615, 81); + _globals->_player.addMover(npcMover, &pt, this); + break; + } + case 7: { + npcMover = new NpcMover(); + Common::Point pt(588, 79); + _globals->_player.addMover(npcMover, &pt, this); + break; + } + case 8: + scene->_sound.proc4(); + scene->_sound.proc1(this); + break; + case 9: + SceneItem::display(0, 0, LIST_END); + _globals->_sceneManager._fadeMode = FADEMODE_GRADUAL; + _globals->_sceneManager.changeScene(40); + break; + default: + break; + } +} + +void Scene20::Action3::signal() { + Scene20 *scene = (Scene20 *)_globals->_sceneManager._scene; + NpcMover *npcMover; + + switch (_actionIndex++) { + case 0: + setDelay(120); + break; + case 1: { + npcMover = new NpcMover(); + Common::Point pt(615, 81); + _globals->_player.addMover(npcMover, &pt, this); + ObjectMover2 *mover1 = new ObjectMover2(); + scene->_SceneObjectExt.addMover(mover1, 5, 10, &_globals->_player); + ObjectMover2 *mover2 = new ObjectMover2(); + scene->_sceneObject3.addMover(mover2, 20, 25, &_globals->_player); + break; + } + case 2: { + npcMover = new NpcMover(); + Common::Point pt(618, 90); + _globals->_player.addMover(npcMover, &pt, this); + break; + } + case 3: { + _globals->_player._moveDiff = Common::Point(10, 10); + scene->_SceneObjectExt._moveDiff = Common::Point(10, 10); + scene->_sceneObject3._moveDiff = Common::Point(10, 10); + npcMover = new NpcMover(); + Common::Point pt(445, 132); + _globals->_player.addMover(npcMover, &pt, this); + break; + } + case 4: { + npcMover = new NpcMover(); + Common::Point pt(151, 137); + _globals->_player.addMover(npcMover, &pt, this); + break; + } + case 5: { + npcMover = new NpcMover(); + Common::Point pt(-15, 137); + _globals->_player.addMover(npcMover, &pt, this); + break; + } + case 6: + scene->_sound.startSound(60, this, 127); + _globals->_soundHandler.proc4(); + break; + case 7: + _globals->_sceneManager._fadeMode = FADEMODE_GRADUAL; + _globals->_sceneManager.changeScene(90); + break; + default: + break; + } +} + +void Scene20::Action4::signal() { + Scene20 *scene = (Scene20 *)_globals->_sceneManager._scene; + NpcMover *npcMover; + + switch (_actionIndex++) { + case 0: + setDelay(60); + break; + case 1: { + npcMover = new NpcMover(); + Common::Point pt(486, 134); + _globals->_player.addMover(npcMover, &pt, this); + ObjectMover2 *mover1 = new ObjectMover2(); + scene->_SceneObjectExt.addMover(mover1, 20, 35, &_globals->_player); + break; + } + case 2: { + _globals->_player._moveDiff = Common::Point(12, 12); + scene->_SceneObjectExt._moveDiff = Common::Point(12, 12); + NpcMover *mover1 = new NpcMover(); + Common::Point pt(486, 134); + scene->_sceneObject3.addMover(mover1, &pt, this); + NpcMover *mover2 = new NpcMover(); + pt = Common::Point(-15, 134); + _globals->_player.addMover(mover2, &pt, NULL); + NpcMover *mover3 = new NpcMover(); + pt = Common::Point(-15, 134); + scene->_SceneObjectExt.addMover(mover3, &pt, NULL); + break; + } + case 3: { + scene->_sceneObject3._moveDiff = Common::Point(20, 20); + npcMover = new NpcMover(); + Common::Point pt(320, 134); + scene->_sceneObject3.addMover(npcMover, &pt, this); + break; + } + case 4: { + scene->_sound.startSound(28); + scene->_sceneObject4.postInit(); + scene->_sceneObject4.setVisage(21); + scene->_sceneObject4.setStrip(3); + scene->_sceneObject4.setPosition(Common::Point(scene->_sceneObject3._position.x - 36, + scene->_sceneObject3._position.y - 1)); + scene->_sceneObject4._moveDiff.x = 48; + + ObjectMover3 *mover = new ObjectMover3(); + scene->_sceneObject4.addMover(mover, &scene->_SceneObjectExt, 4, this); + break; + } + case 5: { + scene->_sound.startSound(42); + scene->_sceneObject4.remove(); + scene->_SceneObjectExt.setVisage(21); + scene->_SceneObjectExt.setStrip(1); + scene->_SceneObjectExt.setFrame(1); + scene->_SceneObjectExt.animate(ANIM_MODE_5, NULL); + + scene->_SceneObjectExt._moveDiff.x = 4; + NpcMover *mover1 = new NpcMover(); + Common::Point pt(scene->_SceneObjectExt._position.x - 12, scene->_SceneObjectExt._position.y + 5); + scene->_SceneObjectExt.addMover(mover1, &pt, NULL); + + scene->_sceneObject5.postInit(); + scene->_sceneObject5.setVisage(21); + scene->_sceneObject5.setStrip(3); + scene->_sceneObject5.setPosition(Common::Point(scene->_sceneObject3._position.x - 36, + scene->_sceneObject3._position.y - 1)); + scene->_sceneObject5._moveDiff.x = 48; + + ObjectMover3 *mover = new ObjectMover3(); + scene->_sceneObject5.addMover(mover, &_globals->_player, 4, this); + break; + } + case 6: { + scene->_sound.startSound(42); + scene->_SceneObjectExt.setStrip(2); + scene->_SceneObjectExt.animate(ANIM_MODE_2, NULL); + + scene->_sceneObject5.remove(); + _globals->_player.setVisage(21); + _globals->_player.setStrip(1); + _globals->_player.setFrame(1); + _globals->_player.animate(ANIM_MODE_5, this); + _globals->_player._moveDiff.x = 4; + + npcMover = new NpcMover(); + Common::Point pt(_globals->_player._position.x - 25, _globals->_player._position.y + 5); + _globals->_player.addMover(npcMover, &pt, this); + break; + } + case 7: + _globals->_player.setStrip(2); + _globals->_player.animate(ANIM_MODE_2, NULL); + scene->_sound.startSound(77, this, 127); + break; + case 8: + _globals->_game.endGame(20, 0); + break; + default: + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene20::Scene20() { +} + +void Scene20::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerGameText); + _speakerQText._npc = &_globals->_player; + + if (_globals->_sceneManager._previousScene == 30) { + _globals->_player.postInit(); + _globals->_player.setVisage(20); + _globals->_player.setPosition(Common::Point(405, 69)); + _globals->_player._moveDiff = Common::Point(10, 10); + _globals->_player.animate(ANIM_MODE_1, NULL); + + _SceneObjectExt.postInit(); + _SceneObjectExt.setVisage(20); + _SceneObjectExt.setPosition(Common::Point(400, 69)); + _SceneObjectExt.animate(ANIM_MODE_1, NULL); + + _sceneObject3.postInit(); + _sceneObject3.setVisage(20); + _sceneObject3.setPosition(Common::Point(395, 69)); + _sceneObject3.animate(ANIM_MODE_1, NULL); + + _SceneObjectExt._moveDiff = Common::Point(10, 10); + _sceneObject3._moveDiff = Common::Point(10, 10); + _globals->_soundHandler.startSound(20); + _sound.startSound(21); + _sound.proc5(1); + setAction(&_action2); + + _sceneBounds = Rect(320, 0, 640, 200); + } else if (_globals->_sceneManager._previousScene == 60) { + _globals->_player.postInit(); + _globals->_player.setVisage(2640); + _globals->_player.animate(ANIM_MODE_NONE, NULL); + _globals->_player.setStrip2(1); + _globals->_player.setFrame2(4); + _globals->_player.setPriority2(200); + _globals->_player.setPosition(Common::Point(425, 233)); + + setAction(&_action1); + _speakerQText.setTextPos(Common::Point(350, 20)); + _speakerQText._textWidth = 260; + _speakerGameText.setTextPos(Common::Point(350, 20)); + _speakerGameText._textWidth = 260; + + _globals->_soundHandler.startSound(8); + _sceneBounds = Rect(320, 0, 640, 200); + } else { + _sound.startSound(30); + _globals->_player.postInit(); + _globals->_player.setVisage(20); + _globals->_player.setPosition(Common::Point(588, 79)); + _globals->_player._moveDiff = Common::Point(5, 5); + _globals->_player.setPriority2(50); + _globals->_player.animate(ANIM_MODE_1, NULL); + + _SceneObjectExt.postInit(); + _SceneObjectExt.setVisage(20); + _SceneObjectExt.setPosition(Common::Point(583, 79)); + _SceneObjectExt.animate(ANIM_MODE_1, NULL); + + _sceneObject3.postInit(); + _sceneObject3.setVisage(20); + _sceneObject3.setStrip(2); + _SceneObjectExt.setPosition(Common::Point(595, 79)); + _SceneObjectExt.animate(ANIM_MODE_1, NULL); + + if ((_globals->getFlag(120) && _globals->getFlag(116)) || + (_globals->getFlag(117) && _globals->getFlag(119))) { + setAction(&_action3); + } else if (_globals->getFlag(104)) { + _sceneMode = 21; + setAction(&_sequenceManager, this, 21, &_globals->_player, &_SceneObjectExt, NULL); + } else { + _sceneObject3._moveDiff = Common::Point(8, 8); + setAction(&_action4); + } + + _sceneBounds.centre(_globals->_player._position.x, _globals->_player._position.y); + } + + _globals->_player.disableControl(); + loadScene(20); +} + +void Scene20::signal() { + if (_sceneMode == 21) + _globals->_sceneManager.changeScene(90); +} + +/*-------------------------------------------------------------------------- + * Scene 30 - First game scene (Outside Ch'mee house) + * + *--------------------------------------------------------------------------*/ + +void Scene30::BeamAction::signal() { + Scene30 *scene = (Scene30 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + // Disable control and move player to the doorway beam + _globals->_player.disableControl(); + NpcMover *mover = new NpcMover(); + Common::Point pt(114, 198); + _globals->_player.addMover(mover, &pt, this); + break; + } + + case 1: + // Perform the animation of player raising hand + _globals->_player.setVisage(31); + _globals->_player.setStrip(1); + _globals->_player.setFrame(1); + _globals->_player.animate(ANIM_MODE_5, this); + break; + + case 2: + // Hide the beam and lower the player's hand + scene->_sound.startSound(10, NULL, 127); + _globals->_player.animate(ANIM_MODE_6, this); + scene->_beam.remove(); + break; + + case 3: { + // Bring the Kzin to the doorway + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setStrip(7); + scene->_kzin.postInit(); + scene->_kzin.setVisage(2801); + scene->_kzin.animate(ANIM_MODE_1, NULL); + scene->_kzin.setObjectWrapper(new SceneObjectWrapper()); + scene->_kzin.setPosition(Common::Point(334, 1)); + NpcMover *mover = new NpcMover(); + Common::Point pt(158, 170); + scene->_kzin.addMover(mover, &pt, this); + _globals->_sceneItems.push_front(&scene->_kzin); + break; + } + + case 4: + // Open the door + scene->_sound.startSound(11, NULL, 127); + scene->_door.animate(ANIM_MODE_5, this); + break; + + case 5: + // Run the Kzin's talk sequence + scene->_sound.startSound(13, NULL, 127); + _globals->_soundHandler.startSound(12, NULL, 127); + scene->_stripManager.start((scene->_sceneMode == 0) ? 30 : 37, this); + break; + + case 6: + // Slight delay + setDelay(3); + break; + + case 7: + // Re-activate player control + scene->_sceneMode = 31; + scene->_kzin.setAction(&scene->_kzinAction); + _globals->_player.enableControl(); + + // End this action + remove(); + break; + + default: + break; + } +} + +void Scene30::KzinAction::signal() { + Scene30 *scene = (Scene30 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(1200); + break; + case 1: + _globals->_soundHandler.proc2(0); + _globals->_player.disableControl(); + setAction(&scene->_sequenceManager, _globals->_sceneManager._scene, 31, &scene->_kzin, &scene->_door, NULL); + break; + case 2: + _globals->_player.enableControl(); + remove(); + break; + default: + break; + } +} + +void Scene30::RingAction::signal() { + Scene30 *scene = (Scene30 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + _globals->_player.disableControl(); + scene->_kzin.setAction(NULL); + NpcMover *mover = new NpcMover(); + Common::Point pt(114, 198); + _globals->_player.addMover(mover, &pt, this); + break; + } + + case 1: + _globals->_player.checkAngle(&scene->_kzin); + scene->_stripManager.start(32, this); + break; + + case 2: { + _globals->_player.animate(ANIM_MODE_1, NULL); + NpcMover *mover = new NpcMover(); + Common::Point pt(143, 177); + _globals->_player.addMover(mover, &pt, this); + break; + } + + case 3: + scene->_sound.startSound(11, NULL, 127); + scene->_door.animate(ANIM_MODE_6, this); + break; + + case 4: { + scene->_sound.startSound(13, NULL, 127); + NpcMover *kzinMover = new NpcMover(); + Common::Point pt(354, 5); + scene->_kzin.addMover(kzinMover, &pt, this); + NpcMover *playerMover = new NpcMover(); + pt = Common::Point(335, 36); + _globals->_player.addMover(playerMover, &pt, this); + break; + } + + case 5: + break; + + case 6: + _globals->_sceneManager.changeScene(20); + break; + + default: + break; + } +} + +void Scene30::TalkAction::signal() { + Scene30 *scene = (Scene30 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + _globals->_player.disableControl(); + scene->_kzin.setAction(NULL); + NpcMover *mover = new NpcMover(); + Common::Point pt(114, 198); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 1: + _globals->_player.checkAngle(&scene->_kzin); + scene->_stripManager.start(34, this); + break; + case 2: + setDelay(5); + break; + case 3: + scene->_kzin.setAction(&scene->_kzinAction); + _globals->_player.enableControl(); + remove(); + break; + default: + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene30::KzinObject::doAction(int action) { + Scene30 *scene = (Scene30 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_STUNNER: + display2(30, 12); + break; + case OBJECT_SCANNER: + display2(30, 11); + break; + case OBJECT_RING: + _globals->_inventory._ring._sceneNumber = 30; + scene->setAction(&scene->_ringAction); + break; + case CURSOR_LOOK: + display2(30, 6); + break; + case CURSOR_USE: + display2(30, 10); + break; + case CURSOR_TALK: + _globals->_player.disableControl(); + scene->setAction(&scene->_talkAction); + break; + default: + SceneObject::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene30::Scene30(): + _groundHotspot(9, OBJECT_SCANNER, 50, 17, CURSOR_LOOK, 30, 3, CURSOR_USE, 30, 8, LIST_END), + _wallsHotspot(8, OBJECT_SCANNER, 50, 13, CURSOR_LOOK, 30, 0, CURSOR_USE, 30, 7, LIST_END), + _courtyardHotspot(0, CURSOR_LOOK, 30, 4, LIST_END), + _treeHotspot(10, OBJECT_SCANNER, 40, 39, CURSOR_LOOK, 30, 5, CURSOR_USE, 30, 9, LIST_END) { +} + +void Scene30::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + // Add the speaker classes to the strip manager + _stripManager.addSpeaker(&_speakerQL); + _stripManager.addSpeaker(&_speakerSR); + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerQText); + _speakerSText._npc = &_kzin; + _speakerQText._npc = &_globals->_player; + + + // Setup player + _globals->_player.postInit(); + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setStrip(7); + _globals->_player.setFrame(1); + _globals->_player.setPosition(Common::Point(114, 198)); + _globals->_player.changeZoom(75); + _globals->_player.enableControl(); + + // Set up beam object + _beam.postInit(); + _beam.setVisage(31); + _beam.setStrip(2); + _beam.setPosition(Common::Point(124, 178)); + _beam.setPriority2(188); + + // Set up door object + _door.postInit(); + _door.setVisage(30); + _door.setPosition(Common::Point(150, 183)); + + // Final processing and add of scene items + _courtyardHotspot.setBounds(Rect(0, 0, 320, 200)); + + // Add the objects and hotspots to the scene + _globals->_sceneItems.addItems(&_beam, &_wallsHotspot, &_door, &_treeHotspot, &_groundHotspot, + &_courtyardHotspot, NULL); + + // Load the scene data + loadScene(30); + _sceneMode = 0; +} + +void Scene30::signal() { + if (_sceneMode == 31) { + // Re-activate beam if the Kzin goes back inside + _beam.postInit(); + _beam.setVisage(31); + _beam.setStrip(2); + _beam.setPosition(Common::Point(124, 178)); + _beam.setPriority2(188); + _globals->_sceneItems.push_front(&_beam); + _globals->_player.enableControl(); + } else if (_sceneMode == 32) { + _globals->_player.disableControl(); + _sceneMode = 31; + setAction(&_sequenceManager, _globals->_sceneManager._scene, 31, &_kzin, &_door, NULL); + } +} + +/*-------------------------------------------------------------------------- + * Scene 40 - Chmeee Home + * + *--------------------------------------------------------------------------*/ + +void Scene40::Action1::signal() { + Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(120); + break; + case 1: + _globals->_events.setCursor(CURSOR_WALK); + scene->_stripManager.start(40, this); + break; + case 2: + scene->_doorway.postInit(); + scene->_doorway.setVisage(46); + scene->_doorway.setPosition(Common::Point(305, 61)); + scene->_doorway.animate(ANIM_MODE_5, this); + scene->_soundHandler.startSound(25); + break; + case 3: + scene->_doorway.hide(); + scene->_dyingKzin.setPosition(Common::Point(296, 62)); + _globals->_player.animate(ANIM_MODE_5, NULL); + scene->_object1.setVisage(43); + scene->_object1.setStrip(3); + scene->_object1.animate(ANIM_MODE_5, NULL); + scene->_object2.hide(); + scene->_object3.hide(); + scene->_stripManager.start(45, this); + break; + case 4: + scene->_object2.remove(); + scene->_object3.remove(); + scene->_assassin.setVisage(42); + scene->_assassin.setStrip(2); + scene->_assassin.setFrame(1); + scene->_assassin.setPosition(Common::Point(13, 171)); + scene->_assassin.animate(ANIM_MODE_5, this); + scene->_soundHandler.startSound(25); + break; + case 5: + scene->_doorway.show(); + scene->_doorway.setVisage(42); + scene->_doorway.setStrip(3); + scene->_doorway.setFrame(1); + scene->_doorway.setPosition(Common::Point(41, 144)); + scene->_assassin.animate(ANIM_MODE_6, NULL); + setDelay(6); + break; + case 6: + scene->_doorway.setPosition(Common::Point(178, 101)); + setDelay(6); + break; + case 7: + scene->_doorway.setPosition(Common::Point(271, 69)); + setDelay(6); + break; + case 8: + scene->_doorway.remove(); + scene->_dyingKzin.animate(ANIM_MODE_5, this); + break; + case 9: { + scene->_dyingKzin.setStrip(1); + scene->_dyingKzin.setFrame(1); + scene->_dyingKzin._moveDiff.y = 15; + scene->_dyingKzin.animate(ANIM_MODE_5, NULL); + Common::Point pt(223, 186); + NpcMover *mover = new NpcMover(); + scene->_dyingKzin.addMover(mover, &pt, this); + break; + } + case 10: { + scene->_soundHandler.startSound(27); + Common::Point pt(223, 184); + NpcMover *mover = new NpcMover(); + scene->_dyingKzin.addMover(mover, &pt, this); + break; + } + case 11: { + Common::Point pt(223, 186); + NpcMover *mover = new NpcMover(); + scene->_dyingKzin.addMover(mover, &pt, this); + break; + } + case 12: { + _globals->_soundHandler.startSound(26); + _globals->_player._uiEnabled = true; + scene->_assassin.setVisage(42); + scene->_assassin.setPosition(Common::Point(4, 191)); + scene->_assassin.setStrip(1); + scene->_assassin.animate(ANIM_MODE_1, NULL); + Common::Point pt(230, 187); + NpcMover *mover = new NpcMover(); + scene->_assassin.addMover(mover, &pt, this); + break; + } + case 13: + setDelay(180); + break; + case 14: + scene->_assassin.setVisage(45); + scene->_assassin.setStrip(1); + scene->_assassin.setFrame(1); + scene->_assassin.animate(ANIM_MODE_5, this); + scene->_soundHandler.startSound(28); + break; + case 15: + _globals->_player.disableControl(); + scene->_object1.setVisage(40); + scene->_object1.setStrip(4); + scene->_object1.setFrame(1); + scene->_object1.animate(ANIM_MODE_5, NULL); + _globals->_player.setVisage(40); + _globals->_player.setStrip(2); + _globals->_player.setFrame(1); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 16: + _globals->_soundHandler.startSound(77, this); + break; + case 17: + _globals->_game.endGame(40, 20); + remove(); + break; + } +} + +void Scene40::Action2::signal() { + Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + if (scene->_assassin._position.x < 229) + _actionIndex = 0; + setDelay(1); + break; + case 1: + scene->_assassin.animate(ANIM_MODE_NONE, NULL); + _globals->_player.setStrip(2); + _globals->_player.setFrame(1); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 2: { + scene->_soundHandler.startSound(28); + scene->_doorway.postInit(); + scene->_doorway.setVisage(16); + scene->_doorway.setStrip2(6); + scene->_doorway.setPriority2(200); + scene->_doorway.setPosition(Common::Point(159, 191)); + scene->_doorway._moveDiff = Common::Point(40, 40); + scene->_doorway._field7A = 60; + scene->_doorway.animate(ANIM_MODE_5, NULL); + + Common::Point pt(271, 165); + NpcMover *mover = new NpcMover(); + scene->_doorway.addMover(mover, &pt, this); + break; + } + case 3: + scene->_doorway.remove(); + scene->_assassin.setVisage(44); + scene->_assassin._frame = 1; + scene->_assassin.animate(ANIM_MODE_5, this); + scene->_soundHandler.startSound(29); + _globals->_inventory._infoDisk._sceneNumber = 40; + break; + case 4: + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 5: { + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setStrip(1); + Common::Point pt(230, 195); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 6: { + _globals->_player.setStrip(7); + scene->_object1.setVisage(2806); + scene->_object1.animate(ANIM_MODE_1, NULL); + SceneObjectWrapper *wrapper = new SceneObjectWrapper(); + scene->_object1.setObjectWrapper(wrapper); + Common::Point pt(200, 190); + NpcMover *mover = new NpcMover(); + scene->_object1.addMover(mover, &pt, this); + break; + } + case 7: + scene->_stripManager.start(44, this); + break; + case 8: { + Common::Point pt(170, 260); + NpcMover *mover = new NpcMover(); + scene->_object1.addMover(mover, &pt, this); + break; + } + case 9: + scene->_dyingKzin.setAction(&scene->_action7); + scene->_object1.remove(); + _globals->_stripNum = 88; + _globals->_events.setCursor(CURSOR_WALK); + _globals->_player.enableControl(); + scene->_assassin.setAction(&scene->_action8); + break; + } +} + +void Scene40::Action3::signal() { + Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + _globals->_player.setAction(NULL); + _globals->_stripNum = 99; + _globals->_player.disableControl(); + Common::Point pt(240, 195); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 1: + _globals->_player.setVisage(5010); + _globals->_player._strip = 2; + _globals->_player._frame = 1; + _globals->_player.animate(ANIM_MODE_4, 5, 1, this); + break; + case 2: + scene->_assassin.setStrip(2); + scene->_assassin.setFrame(1); + _globals->_inventory._infoDisk._sceneNumber = 1; + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 3: + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setStrip(7); + _globals->_stripNum = 88; + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene40::Action4::signal() { + switch (_actionIndex++) { + case 0: { + Common::Point pt(178, 190); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 1: + _globals->_stripNum = 88; + _globals->_player.enableControl(); + break; + } +} + +void Scene40::Action5::signal() { + Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(_globals->_randomSource.getRandomNumber(120)); + break; + case 1: + scene->_object2.animate(ANIM_MODE_8, 1, this); + _actionIndex = 0; + } +} + +void Scene40::Action6::signal() { + Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + scene->_object1.postInit(); + scene->_object1.setVisage(16); + scene->_object1.setStrip2(6); + scene->_object1.setPosition(Common::Point(313, 53)); + scene->_object1._field7A = 60; + + Common::Point pt(141, 194); + NpcMover *mover = new NpcMover(); + scene->_object1.addMover(mover, &pt, this); + scene->_object1.animate(ANIM_MODE_5, NULL); + + scene->_doorway.postInit(); + scene->_doorway.setVisage(46); + scene->_doorway.setPosition(Common::Point(305, 61)); + scene->_doorway.animate(ANIM_MODE_5, this); + scene->_soundHandler.startSound(25); + break; + } + case 1: + scene->_soundHandler.startSound(28); + scene->_doorway.setPosition(Common::Point(148, 74)); + scene->_doorway.setFrame(1); + scene->_doorway.setStrip(2); + scene->_doorway.animate(ANIM_MODE_5, this); + break; + case 2: + remove(); + break; + } +} + +void Scene40::Action7::signal() { + Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(_globals->_randomSource.getRandomNumber(500)); + break; + case 1: + scene->_object7.postInit(); + scene->_object7.setVisage(46); + + if (_globals->_randomSource.getRandomNumber(32767) >= 16384) { + scene->_object7.setStrip(3); + scene->_object7.setPosition(Common::Point(15, 185)); + } else { + scene->_object7.setPosition(Common::Point(305, 61)); + scene->_object7.setFrame(15); + } + break; + case 2: + scene->_object7.remove(); + _actionIndex = 0; + setDelay(60); + break; + } +} + +void Scene40::Action8::signal() { + Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(300); + break; + case 1: + _globals->_player.disableControl(); + + if ((_globals->_player._position.y >= 197) || (_globals->_player._visage)) { + _actionIndex = 1; + setDelay(30); + } else { + scene->_doorway.postInit(); + scene->_doorway.setVisage(16); + scene->_doorway.setStrip2(6); + scene->_doorway.setPriority2(200); + scene->_doorway._field7A = 60; + + if (_globals->_player._position.x >= 145) { + scene->_doorway.setPriority2(-1); + scene->_doorway.setPosition(Common::Point(6, 157)); + } else { + scene->_doorway.setPosition(Common::Point(313, 53)); + } + + scene->_doorway._moveDiff = Common::Point(40, 40); + Common::Point pt(_globals->_player._position.x, _globals->_player._position.y - 18); + NpcMover *mover = new NpcMover(); + scene->_doorway.addMover(mover, &pt, this); + scene->_doorway.animate(ANIM_MODE_5, NULL); + } + break; + case 2: + scene->_doorway.remove(); + _globals->_player.setVisage(40); + _globals->_player.setStrip(2); + _globals->_player.setFrame(1); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 3: + _globals->_soundHandler.startSound(77, this); + break; + case 4: + _globals->_game.endGame(40, 45); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene40::DyingKzin::doAction(int action) { + switch (action) { + case OBJECT_STUNNER: + SceneItem::display2(40, 43); + break; + case CURSOR_CROSSHAIRS: + SceneItem::display2(40, 44); + break; + case CURSOR_LOOK: + SceneItem::display2(40, 12); + break; + case CURSOR_USE: + SceneItem::display2(40, 18); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene40::Assassin::doAction(int action) { + Scene40 *scene = (Scene40 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_CROSSHAIRS: + if (scene->_assassin._visage == 44) + SceneItem::display2(40, 21); + else { + _globals->_player.disableControl(); + Common::Point pt(230, 187); + NpcMover *mover = new NpcMover(); + addMover(mover, &pt, NULL); + } + break; + case OBJECT_SCANNER: + SceneItem::display2(40, (scene->_assassin._visage == 44) ? 22 : 23); + break; + case CURSOR_LOOK: + if (scene->_assassin._visage != 44) + SceneItem::display2(40, 13); + else + SceneItem::display2(40, (_globals->_inventory._infoDisk._sceneNumber == 1) ? 19 : 14); + break; + case CURSOR_USE: + if (scene->_assassin._visage != 44) + SceneItem::display2(40, 15); + else if (_globals->_inventory._infoDisk._sceneNumber == 1) + SceneItem::display2(40, 19); + else { + _globals->_player.disableControl(); + setAction(&scene->_action3); + } + break; + case CURSOR_TALK: + SceneItem::display2(40, 38); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene40::Item2::doAction(int action) { + switch (action) { + case CURSOR_CROSSHAIRS: + SceneItem::display2(40, 35); + _globals->_events.setCursor(CURSOR_WALK); + break; + case OBJECT_SCANNER: + SceneItem::display2(40, 34); + break; + case CURSOR_LOOK: + SceneItem::display2(40, 8); + break; + case CURSOR_USE: + SceneItem::display2(40, 36); + break; + case CURSOR_TALK: + SceneItem::display2(40, 37); + break; + default: + SceneItem::doAction(action); + break; + } +} + +void Scene40::Item6::doAction(int action) { + switch (action) { + case CURSOR_CROSSHAIRS: + SceneItem::display2(40, 25); + _globals->_events.setCursor(CURSOR_WALK); + break; + case OBJECT_SCANNER: + SceneItem::display2(40, 42); + break; + case CURSOR_LOOK: + SceneItem::display2(40, 6); + break; + case CURSOR_USE: + SceneItem::display2(40, 36); + break; + default: + SceneItem::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene40::Scene40(): + _item1(2, OBJECT_SCANNER, 40, 24, CURSOR_CROSSHAIRS, 40, 25, CURSOR_LOOK, 40, 7, CURSOR_USE, 40, 16, LIST_END), + _item3(5, OBJECT_SCANNER, 40, 26, CURSOR_CROSSHAIRS, 40, 27, CURSOR_LOOK, 40, 9, CURSOR_USE, 40, 17, LIST_END), + _item4(6, OBJECT_SCANNER, 40, 31, CURSOR_CROSSHAIRS, 40, 32, CURSOR_LOOK, 40, 5, CURSOR_USE, 40, 33, LIST_END), + _item5(0, CURSOR_LOOK, 40, 11, LIST_END), + _item7(4, OBJECT_SCANNER, 40, 26, CURSOR_CROSSHAIRS, 40, 27, CURSOR_LOOK, 40, 9, CURSOR_USE, 40, 17, LIST_END), + _item8(8, OBJECT_SCANNER, 40, 39, CURSOR_CROSSHAIRS, 40, 40, CURSOR_LOOK, 40, 3, CURSOR_USE, 40, 41, LIST_END) { +} + +void Scene40::postInit(SceneObjectList *OwnerList) { + loadScene(40); + Scene::postInit(); + + setZoomPercents(0, 100, 200, 100); + _globals->_stripNum = 99; + + _stripManager.addSpeaker(&_speakerQR); + _stripManager.addSpeaker(&_speakerSL); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerGameText); + + _speakerGameText._colour1 = 9; + _speakerGameText.setTextPos(Common::Point(160, 30)); + _speakerQText._npc = &_globals->_player; + _speakerSText._npc = &_object1; + + _globals->_player.postInit(); + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setPosition(Common::Point(130, 220)); + _globals->_player.disableControl(); + + if (_globals->_sceneManager._previousScene == 20) { + _globals->_soundHandler.startSound(24); + _globals->_player.setVisage(43); + + _object1.postInit(); + _object1.setVisage(41); + _object1.setPosition(Common::Point(105, 220)); + _object2.postInit(); + _object2.setVisage(41); + _object2.setStrip(6); + _object2.setPriority2(200); + _object2.setPosition(Common::Point(94, 189)); + _object2.setAction(&_action5); + + _object3.postInit(); + _object3.setVisage(41); + _object3.setStrip(5); + _object3.setPriority2(205); + _object3.setPosition(Common::Point(110, 186)); + _object3._numFrames = 2; + _object3.animate(ANIM_MODE_8, NULL, NULL); + + _assassin.postInit(); + _assassin.setPosition(Common::Point(-40, 191)); + _globals->_sceneItems.push_back(&_assassin); + + _dyingKzin.postInit(); + _dyingKzin.setVisage(40); + _dyingKzin.setStrip(6); + _dyingKzin.setPosition(Common::Point(-90, 65)); + _dyingKzin.setPriority2(170); + + setAction(&_action1); + } else { + _doorway.postInit(); + _doorway.setVisage(46); + _doorway.setPosition(Common::Point(148, 74)); + _doorway.setStrip(2); + _doorway.setFrame(_doorway.getFrameCount()); + + _dyingKzin.postInit(); + _dyingKzin.setVisage(40); + _dyingKzin.setPosition(Common::Point(205, 183)); + _dyingKzin.setPriority2(170); + _dyingKzin._frame = 9; + _dyingKzin.setAction(&_action7); + + _assassin.postInit(); + _assassin.setVisage(44); + _assassin.setPosition(Common::Point(230, 187)); + _assassin.setAction(&_action8); + + if (_globals->_inventory._infoDisk._sceneNumber == 40) { + _assassin.setStrip(1); + _assassin.setFrame(_assassin.getFrameCount()); + } else { + _assassin.setStrip(2); + } + + _globals->_sceneItems.push_back(&_assassin); + _globals->_player.setPosition(Common::Point(170, 220)); + + setAction(&_action4); + } + + _item5.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + _item6._sceneRegionId = 3; + _item2._sceneRegionId = 7; + + _globals->_sceneItems.addItems(&_dyingKzin, &_item8, &_item1, &_item2, &_item3, &_item4, + &_item6, &_item7, &_item5, NULL); +} + +void Scene40::signal() { + if (_sceneMode == 41) + _globals->_sceneManager.changeScene(50); +} + +void Scene40::dispatch() { + if ((_globals->_stripNum == 88) && (_globals->_player._position.y >= 197)) { + _globals->_player.disableControl(); + _globals->_stripNum = 0; + _globals->_player.setAction(NULL); + _sceneMode = 41; + setAction(&_sequenceManager, this, 41, &_globals->_player, NULL); + + if (_globals->_sceneManager._previousScene == 20) { + _dyingKzin.setAction(&_action6); + } + } + + Scene::dispatch(); +} + +/*-------------------------------------------------------------------------- + * Scene 50 - By Flycycles + * + *--------------------------------------------------------------------------*/ + +void Scene50::Action1::signal() { + Scene50 *scene = (Scene50 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setAction(&scene->_sequenceManager, this, 54, &_globals->_player, NULL); + break; + case 1: + _globals->_events.setCursor(CURSOR_WALK); + scene->_stripManager.start(63, this); + break; + case 2: + if (scene->_stripManager._field2E8 != 107) { + _globals->_player.enableControl(); + remove(); + } else { + Common::Point pt(282, 139); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + } + break; + case 3: + _globals->_stripNum = -1; + _globals->_sceneManager.changeScene(60); + break; + } +} + +void Scene50::Action2::signal() { + Scene50 *scene = (Scene50 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + scene->_stripManager.start(66, this); + break; + case 1: { + Common::Point pt(141, 142); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 2: + _globals->_sceneManager.changeScene(40); + remove(); + break; + } +} + +void Scene50::Action3::signal() { + switch (_actionIndex++) { + case 0: { + _globals->_player.disableControl(); + Common::Point pt(136, 185); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 1: + _globals->_sceneManager.changeScene(60); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene50::Object1::doAction(int action) { + Scene50 *scene = (Scene50 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_STUNNER: + SceneItem::display2(50, 20); + break; + case OBJECT_SCANNER: + SceneItem::display2(50, 19); + break; + case CURSOR_LOOK: + SceneItem::display2(50, 4); + break; + case CURSOR_USE: + SceneItem::display2(50, 21); + break; + case CURSOR_TALK: + _globals->_player.disableControl(); + scene->_sceneMode = 52; + scene->setAction(&scene->_sequenceManager, scene, 52, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene50::Object2::doAction(int action) { + Scene50 *scene = (Scene50 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_STUNNER: + SceneItem::display2(50, 11); + break; + case OBJECT_SCANNER: + SceneItem::display2(50, 10); + break; + case CURSOR_LOOK: + SceneItem::display2(50, 1); + break; + case OBJECT_INFODISK: + case CURSOR_USE: + _globals->_stripNum = 50; + scene->setAction(&scene->_action3); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene50::Object3::doAction(int action) { + Scene50 *scene = (Scene50 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_STUNNER: + SceneItem::display2(50, 11); + break; + case OBJECT_SCANNER: + SceneItem::display2(50, 10); + break; + case CURSOR_LOOK: + SceneItem::display2(50, 1); + break; + case OBJECT_INFODISK: + case CURSOR_USE: + SceneItem::display2(50, 8); + break; + case CURSOR_TALK: + _globals->_player.disableControl(); + scene->_sceneMode = 52; + scene->setAction(&scene->_sequenceManager, scene, 52, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene50::Object4::doAction(int action) { + Scene50 *scene = (Scene50 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_STUNNER: + SceneItem::display2(50, 11); + break; + case OBJECT_SCANNER: + SceneItem::display2(50, 10); + break; + case CURSOR_LOOK: + SceneItem::display2(50, 1); + break; + case OBJECT_INFODISK: + case CURSOR_USE: + _globals->_player.disableControl(); + _globals->_stripNum = 0; + scene->_sceneMode = 51; + scene->setAction(&scene->_sequenceManager, scene, 51, &_globals->_player, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene50::Scene50(): + _item0(0, CURSOR_LOOK, 50, 3, LIST_END), + _item1(0, OBJECT_SCANNER, 50, 15, CURSOR_USE, 50, 16, CURSOR_LOOK, 50, 3, LIST_END), + _item2(0, CURSOR_LOOK, 50, 7, LIST_END), + _item3(8, OBJECT_STUNNER, 50, 14, OBJECT_SCANNER, 50, 13, CURSOR_LOOK, 50, 3, LIST_END), + _item4(9, OBJECT_SCANNER, 40, 39, OBJECT_STUNNER, 40, 40, CURSOR_USE, 40, 41, CURSOR_LOOK, 50, 5, LIST_END), + _item5(10, OBJECT_SCANNER, 50, 17, OBJECT_STUNNER, 50, 18, CURSOR_LOOK, 50, 6, CURSOR_USE, 30, 8, LIST_END) { +} + +void Scene50::postInit(SceneObjectList *OwnerList) { + loadScene(50); + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerSText); + + _globals->_player.postInit(); + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player._canWalk = false; + _globals->_player.changeZoom(75); + _globals->_player._moveDiff.y = 3; + + if (_globals->_sceneManager._previousScene == 40) { + _globals->_player.setPosition(Common::Point(128, 123)); + } else if (_globals->_stripNum == 50) { + _globals->_player.setPosition(Common::Point(136, 185)); + } else { + _globals->_player.setPosition(Common::Point(270, 143)); + } + + _object2.postInit(); + _object2.setVisage(2331); + _object2.setStrip(6); + _object2.setPosition(Common::Point(136, 192)); + _object2.setPriority2(200); + + _object3.postInit(); + _object3.setVisage(2337); + _object3.setStrip(6); + _object3.setPosition(Common::Point(260, 180)); + _object3.setPriority2(200); + + _object4.postInit(); + _object4.setVisage(2331); + _object4.setStrip(6); + _object4.setPosition(Common::Point(295, 144)); + _object4.setPriority2(178); + + _globals->_sceneItems.addItems(&_object2, &_object3, &_object4, NULL); + + if (!_globals->getFlag(101)) { + _globals->_player.disableControl(); + _globals->setFlag(101); + setAction(&_action1); + } else { + _globals->_player.enableControl(); + + if (_globals->_sceneManager._previousScene == 40) { + _globals->_player.disableControl(); + _sceneMode = 54; + setAction(&_sequenceManager, this, 54, &_globals->_player, NULL); + } + } + + _item0.setBounds(Rect(200, 0, 320, 200)); + _globals->_sceneItems.addItems(&_item3, &_item4, &_item5, &_item0, NULL); + _doorwayRect = Rect(80, 108, 160, 112); +} + +void Scene50::signal() { + switch (_sceneMode) { + case 51: + _globals->_sceneManager.changeScene(60); + break; + case 55: + _globals->_sceneManager.changeScene(40); + break; + case 52: + case 54: + _globals->_player.enableControl(); + break; + } +} + +void Scene50::dispatch() { + if ((_sceneMode != 55) && _doorwayRect.contains(_globals->_player._position)) { + // Player in house doorway, start player moving to within + _globals->_player.disableControl(); + _sceneMode = 55; + Common::Point pt(89, 111); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + } +} + +/*-------------------------------------------------------------------------- + * Scene 60 - Flycycle controls + * + *--------------------------------------------------------------------------*/ + +void Scene60::Action1::signal() { + Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(3); + break; + case 1: + scene->_object9.postInit(); + scene->_object9.setVisage(60); + scene->_object9.setStrip(7); + scene->_object9.setPosition(Common::Point(136, 65)); + scene->_object9.animate(ANIM_MODE_5, this); + + scene->_soundHandler1.startSound(35); + break; + case 2: + scene->_object10.postInit(); + scene->_object10.setVisage(60); + scene->_object10.setPosition(Common::Point(199, 186)); + scene->_object10.animate(ANIM_MODE_8, 0, NULL); + scene->_object10._numFrames = 5; + + scene->_object6.animate(ANIM_MODE_2, NULL); + + if (!_globals->getFlag(83)) { + scene->_object5.postInit(); + scene->_object5.setVisage(60); + scene->_object5.setStrip2(3); + scene->_object5.setFrame(2); + scene->_object5.setPosition(Common::Point(148, 85)); + scene->_object5.animate(ANIM_MODE_2, NULL); + scene->_object5._numFrames = 5; + + _globals->_sceneItems.push_front(&scene->_object5); + scene->_soundHandler2.startSound(38); + } + + _globals->_events.setCursor(CURSOR_USE); + break; + case 3: + scene->_soundHandler2.startSound(37); + scene->loadScene(65); + scene->_object5.remove(); + + if (_globals->_sceneObjects->contains(&scene->_object10)) + scene->_object10.remove(); + + scene->_object6.remove(); + scene->_slaveButton.remove(); + scene->_object8.remove(); + scene->_item1.remove(); + scene->_item2.remove(); + + scene->_object3.postInit(); + scene->_object3.setVisage(65); + scene->_object3.setPosition(Common::Point(118, 197)); + + scene->_object2.postInit(); + scene->_object2.setVisage(65); + scene->_object2.setStrip(2); + scene->_object2.setPosition(Common::Point(160, 197)); + + scene->_object4.postInit(); + scene->_object4.setVisage(65); + scene->_object4.setStrip(3); + scene->_object4.setPosition(Common::Point(202, 197)); + + scene->_object1.postInit(); + scene->_object1.setVisage(65); + scene->_object1.setStrip(4); + scene->_object1.setFrame(1); + scene->_object1.setPosition(Common::Point(145, 165)); + + _globals->_sceneItems.push_front(&scene->_object3); + _globals->_sceneItems.push_front(&scene->_object2); + _globals->_sceneItems.push_front(&scene->_object4); + setDelay(10); + + _globals->_events.setCursor(CURSOR_USE); + break; + case 4: + _globals->setFlag(90); + // Deliberate fall-through + case 5: + case 6: + case 7: + SceneItem::display(60, _actionIndex - 4, SET_Y, 40, SET_X, 25, SET_FONT, 75, + SET_EXT_BGCOLOUR, -1, SET_FG_COLOUR, 34, SET_POS_MODE, 0, + SET_WIDTH, 280, SET_KEEP_ONSCREEN, 1, LIST_END); + _globals->_events.setCursor(CURSOR_USE); + break; + case 9: + _globals->_player._uiEnabled = false; + _globals->_inventory._infoDisk._sceneNumber = 1; + + if (_globals->_sceneObjects->contains(&scene->_object5)) + scene->_object5.remove(); + + scene->_object6.animate(ANIM_MODE_NONE); + scene->_object6.setFrame(1); + scene->_object10.remove(); + + scene->_object9.postInit(); + scene->_object9.setVisage(60); + scene->_object9.setStrip(7); + scene->_object9.setPosition(Common::Point(136, 65)); + scene->_object9.setFrame(scene->_object9.getFrameCount()); + scene->_object9.animate(ANIM_MODE_6, this); + + scene->_soundHandler1.startSound(35); + scene->_soundHandler3.proc3(); + + scene->_object8.setFrame(1); + scene->_object8._state = 0; + + _globals->clearFlag(103); + _globals->clearFlag(!_globals->_stripNum ? 116 : 119); + break; + case 10: + setDelay(60); + break; + case 11: + _globals->_player._uiEnabled = true; + scene->_object9.remove(); + remove(); + break; + default: + break; + } +} + +void Scene60::Action2::signal() { + Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + case 2: + setDelay(3); + break; + case 1: + scene->_stripManager.start(66, this); + break; + case 3: + _globals->_sceneManager.changeScene(50); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene60::Object2::doAction(int action) { + Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene; + + if (action == CURSOR_LOOK) { + SceneItem::display2(60, 16); + } else if (action == CURSOR_USE) { + animate(ANIM_MODE_8, 1, NULL); + + if (scene->_action1.getActionIndex() > 5) { + scene->_soundHandler3.startSound(36); + scene->_action1.setActionIndex(scene->_action1.getActionIndex() - 2); + scene->_action1.setDelay(1); + } + } else { + SceneHotspot::doAction(action); + } +} + +void Scene60::Object3::doAction(int action) { + Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene; + + if (action == CURSOR_LOOK) { + SceneItem::display2(60, 17); + } else if (action == CURSOR_USE) { + animate(ANIM_MODE_8, 1, NULL); + + if (scene->_action1.getActionIndex() < 8) { + scene->_soundHandler3.startSound(36); + scene->_action1.setDelay(1); + } + } else { + SceneHotspot::doAction(action); + } +} + +void Scene60::Object4::doAction(int action) { + Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene; + + if (action == CURSOR_LOOK) { + SceneItem::display2(60, 18); + } else if (action == CURSOR_USE) { + scene->_soundHandler3.startSound(36); + animate(ANIM_MODE_8, 1, NULL); + scene->_object3.remove(); + scene->_object2.remove(); + scene->_object4.remove(); + scene->_object1.remove(); + + SceneItem::display(0, 0); + scene->loadScene(60); + + scene->_object6.setVisage(60); + scene->_object6.setPosition(Common::Point(233, 143)); + scene->_object6.animate(ANIM_MODE_2, NULL); + + scene->_slaveButton.postInit(); + scene->_slaveButton.setVisage(60); + scene->_slaveButton.setStrip(8); + scene->_slaveButton.setPosition(Common::Point(143, 125)); + + scene->_object8.postInit(); + scene->_object8.setVisage(60); + scene->_object8.setStrip(8); + scene->_object8.setPosition(Common::Point(143, 105)); + + _globals->_sceneItems.push_front(&scene->_object8); + _globals->_sceneItems.push_front(&scene->_slaveButton); + + scene->_object10.postInit(); + scene->_object10.setVisage(60); + scene->_object10.setPosition(Common::Point(199, 186)); + scene->_object10.animate(ANIM_MODE_8, 0, NULL); + scene->_object10._numFrames = 5; + scene->_object10.setAction(&scene->_sequenceManager, scene, 61, NULL); + + if (scene->_slaveButton._state) + scene->_slaveButton.setFrame(2); + if (scene->_object8._state) + scene->_object8.setFrame(2); + + _globals->_sceneItems.push_front(&scene->_item1); + _globals->_sceneItems.push_front(&scene->_object6); + _globals->_sceneItems.push_front(&scene->_slaveButton); + _globals->_sceneItems.push_front(&scene->_object8); + _globals->_sceneItems.push_back(&scene->_item2); + + _globals->gfxManager()._font.setFontNumber(2); + _globals->_sceneText._fontNumber = 2; + + scene->_action1.setActionIndex(2); + scene->_action1.setDelay(1); + scene->_sceneMode = 9999; + scene->signal(); + } else { + SceneHotspot::doAction(action); + } +} + +void Scene60::Object5::doAction(int action) { + Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene; + + if (action == CURSOR_LOOK) { + SceneItem::display2(60, 9); + } else if (action == CURSOR_USE) { + scene->_action1.setDelay(1); + _globals->setFlag(83); + } else { + SceneHotspot::doAction(action); + } +} + +void Scene60::Object6::doAction(int action) { + Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene; + + if (action == CURSOR_LOOK) { + SceneItem::display2(60, 11); + } else if (action == CURSOR_USE) { + if (_animateMode == ANIM_MODE_NONE) + SceneItem::display2(60, 14); + else if (!scene->_slaveButton._state) { + _globals->_soundHandler.startSound(40); + _globals->_soundHandler.proc5(1); + _globals->_sceneManager.changeScene(20); + } else { + scene->_sceneMode = 15; + setAction(&scene->_sequenceManager, scene, 62, NULL); + } + } else { + SceneHotspot::doAction(action); + } +} + +void Scene60::SlaveObject::doAction(int action) { + Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene; + + if (action == CURSOR_LOOK) { + SceneItem::display2(60, 8); + } else if (action == CURSOR_USE) { + if (scene->_object8._state) + scene->_sceneMode = 19; + else if (_state) { + scene->_soundHandler3.proc3(); + animate(ANIM_MODE_6, NULL); + _globals->clearFlag(102); + _globals->clearFlag(!_globals->_stripNum ? 117 : 120); + _state = 0; + scene->_sceneMode = 9998; + } else { + scene->_soundHandler3.startSound(39); + _globals->setFlag(102); + _globals->setFlag(!_globals->_stripNum ? 117 : 120); + animate(ANIM_MODE_5, NULL); + _state = 1; + scene->_sceneMode = 9998; + } + + setAction(&scene->_sequenceManager, scene, 62, NULL); + } else { + SceneHotspot::doAction(action); + } +} + +void Scene60::Object8::doAction(int action) { + Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene; + + if (action == CURSOR_LOOK) { + SceneItem::display2(60, 7); + } else if (action == CURSOR_USE) { + if (!scene->_object8._state) + scene->_sceneMode = 14; + else if (_state) { + scene->_soundHandler3.proc3(); + animate(ANIM_MODE_6, NULL); + _globals->clearFlag(103); + _globals->clearFlag(!_globals->_stripNum ? 116 : 119); + _state = 0; + scene->_sceneMode = 9998; + } else { + scene->_soundHandler3.startSound(39); + animate(ANIM_MODE_5, NULL); + _state = 1; + _globals->setFlag(103); + _globals->setFlag(!_globals->_stripNum ? 116 : 119); + scene->_sceneMode = 9998; + } + + setAction(&scene->_sequenceManager, scene, 62, NULL); + } else { + SceneHotspot::doAction(action); + } +} + +void Scene60::Object9::doAction(int action) { + Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene; + + if (action == CURSOR_LOOK) { + SceneItem::display2(60, 13); + } else if (action == CURSOR_USE) { + _globals->setFlag(!_globals->_stripNum ? 118 : 121); + scene->setAction(&scene->_action1); + } else { + SceneHotspot::doAction(action); + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene60::Item1::doAction(int action) { + Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_INFODISK: + _globals->_inventory._infoDisk._sceneNumber = 60; + _globals->setFlag(!_globals->_stripNum ? 118 : 121); + scene->_sceneMode = 0; + scene->setAction(&scene->_action1); + break; + case CURSOR_LOOK: + SceneItem::display2(60, 10); + break; + case CURSOR_USE: + if (_globals->_inventory._infoDisk._sceneNumber == 60) { + if (_globals->getFlag(118) && !_globals->_stripNum) { + _globals->clearFlag(118); + scene->setAction(&scene->_action1); + scene->_action1.setActionIndex(9); + scene->_action1.setDelay(1); + } + if (_globals->getFlag(121) && !_globals->_stripNum) { + _globals->clearFlag(121); + scene->setAction(&scene->_action1); + scene->_action1.setActionIndex(9); + scene->_action1.setDelay(1); + } + } else if (_globals->_inventory._infoDisk._sceneNumber == 1) { + scene->_sceneMode = 0; + setAction(&scene->_sequenceManager, scene, 62, NULL); + } else { + scene->setAction(&scene->_action2); + } + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene60::Item::doAction(int action) { + Scene60 *scene = (Scene60 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(60, _messageNum); + break; + case CURSOR_USE: + scene->_sceneMode = _sceneMode; + setAction(&scene->_sequenceManager, this, 62, NULL); + break; + default: + SceneItem::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene60::Scene60(): + _item2(0, 12, 12), + _item3(8, 22, 23), + _item4(9, 24, 25), + _item5(10, 26, 27), + _item6(11, 28, 29) { +} + +void Scene60::postInit(SceneObjectList *OwnerList) { + loadScene(60); + Scene::postInit(); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerSText); + + _globals->_player._uiEnabled = true; + _globals->_events.setCursor(CURSOR_USE); + + _slaveButton.postInit(); + _slaveButton.setVisage(60); + _slaveButton.setStrip(8); + _slaveButton.setPosition(Common::Point(143, 125)); + _slaveButton._state = 0; + + _object8.postInit(); + _object8.setVisage(60); + _object8.setStrip(8); + _object8.setPosition(Common::Point(143, 105)); + _object8._state = 0; + + _globals->_sceneItems.push_back(&_object8); + _globals->_sceneItems.push_back(&_slaveButton); + + _object6.postInit(); + _object6.setVisage(60); + _object6.setStrip(5); + _object6.setPosition(Common::Point(233, 143)); + _globals->_sceneItems.push_back(&_object6); + + if (_globals->_stripNum == -1) { + _globals->_stripNum = 0; + } else { + _globals->_player.disableControl(); + _sceneMode = 9999; + setAction(&_sequenceManager, this, 61, NULL); + } + + _item1.setBounds(Rect(130, 55, 174, 70)); + _item2.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + + if (_globals->_stripNum == 0) { + if (_globals->getFlag(117)) { + _slaveButton._state = 1; + _slaveButton.setFrame(2); + } + + if (_globals->getFlag(116)) { + _object8._state = 1; + _object8.setFrame(2); + } + + if (_globals->getFlag(118)) { + _object6.animate(ANIM_MODE_2, NULL); + + _object10.postInit(); + _object10.setVisage(60); + _object10.setPosition(Common::Point(199, 186)); + _object10.animate(ANIM_MODE_8, 0, NULL); + + _soundHandler1.startSound(35); + + if (!_globals->getFlag(83)) { + _object5.postInit(); + _object5.setVisage(60); + _object5.setStrip2(3); + _object5.setFrame(2); + _object5.setPosition(Common::Point(148, 85)); + _object5.animate(ANIM_MODE_2, NULL); + _object5._numFrames = 5; + _globals->_sceneItems.push_front(&_object5); + + _soundHandler2.startSound(38); + } + } + } else { + if (_globals->getFlag(120)) { + _slaveButton._state = 1; + _slaveButton.setFrame(2); + } + + if (_globals->getFlag(119)) { + _object8._state = 1; + _object8.setFrame(2); + } + + if (_globals->getFlag(121)) { + _object6.animate(ANIM_MODE_2, NULL); + + _object10.postInit(); + _object10.setVisage(60); + _object10.setPosition(Common::Point(199, 186)); + _object10.animate(ANIM_MODE_8, 0, NULL); + _object10._numFrames = 5; + + _soundHandler1.startSound(35); + + if (!_globals->getFlag(83)) { + _object5.postInit(); + _object5.setVisage(60); + _object5.setStrip2(3); + _object5.setFrame(2); + _object5.setPosition(Common::Point(148, 85)); + _object5.animate(ANIM_MODE_2, NULL); + _object5._numFrames = 5; + _globals->_sceneItems.push_front(&_object5); + + _soundHandler2.startSound(38); + } + } + } + + _globals->_sceneItems.addItems(&_item3, &_item4, &_item5, &_item6, + &_item1, &_item2, NULL); +} + +void Scene60::signal() { + if (_sceneMode != 0) { + if (_sceneMode == 9998) { + _globals->_events.setCursor(CURSOR_USE); + } else if (_sceneMode == 9999) { + _globals->_player._uiEnabled = true; + _globals->_events.setCursor(CURSOR_USE); + + _gfxButton.setText(EXIT_MSG); + _gfxButton._bounds.centre(160, 193); + _gfxButton.draw(); + _gfxButton._bounds.expandPanes(); + } else { + SceneItem::display2(60, _sceneMode); + _globals->_events.setCursor(CURSOR_USE); + } + } +} + +void Scene60::process(Event &event) { + Scene::process(event); + + if (_sceneNumber == 60) { + if (_gfxButton.process(event)) + _globals->_sceneManager.changeScene(50); + } +} + +/*-------------------------------------------------------------------------- + * Scene 90 - Shipyard Entrance + * + *--------------------------------------------------------------------------*/ + +void Scene90::Action1::signal() { + Scene90 *scene = (Scene90 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(10); + break; + case 1: + _globals->_scenePalette.addRotation(64, 72, -1); + _globals->_events.setCursor(CURSOR_WALK); + scene->_stripManager.start(90, this); + break; + case 2: + setDelay(2); + break; + case 3: { + Common::Point pt(278, 191); + NpcMover *mover = new NpcMover(); + scene->_object2.addMover(mover, &pt, this); + break; + } + case 4: + scene->_object2.setStrip(3); + setDelay(2); + break; + case 5: + scene->_soundHandler2.startSound(58); + + if (scene->_stripManager._field2E8 == 220) + scene->_stripManager.start(91, this, scene); + else { + scene->_stripManager.start(_globals->getFlag(104) ? 93 : 92, this, scene); + _actionIndex = 7; + } + break; + case 6: + scene->_object2.animate(ANIM_MODE_NONE); + _globals->_player._uiEnabled = true; + break; + case 7: + scene->_object2.animate(ANIM_MODE_NONE); + _globals->_soundHandler.startSound(56); + scene->_object3.animate(ANIM_MODE_5, this); + break; + case 8: { + Common::Point pt(215, 127); + PlayerMover *mover = new PlayerMover(); + scene->_object5.addMover(mover, &pt, this); + break; + } + case 9: { + Common::Point pt1(215, 127); + PlayerMover *mover1 = new PlayerMover(); + scene->_object1.addMover(mover1, &pt1, this); + Common::Point pt2(86, 62); + PlayerMover *mover2 = new PlayerMover(); + scene->_object5.addMover(mover2, &pt2, this); + break; + } + case 10: { + PlayerMover2 *mover = new PlayerMover2(); + scene->_object1.addMover(mover, 10, 15, &scene->_object5); + + if (!_globals->getFlag(104)) { + mover = new PlayerMover2(); + scene->_object4.addMover(mover, 10, 15, &scene->_object1); + } + setDelay(60); + break; + } + case 11: + _globals->_soundHandler.startSound(57); + _globals->_soundHandler.startSound(68); + scene->_object3.animate(ANIM_MODE_6, NULL); + + SceneItem::display(90, _globals->getFlag(104) ? 15 : 14, + SET_EXT_BGCOLOUR, 13, SET_KEEP_ONSCREEN, -1, SET_X, 120, SET_Y, 20, LIST_END); + break; + case 12: + SceneItem::display(0, 0); + _globals->_scenePalette.clearListeners(); + _globals->_sceneManager.changeScene(95); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene90::Object1::doAction(int action) { + Scene90 *scene = (Scene90 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(90, 7); + break; + case CURSOR_USE: + _globals->_player.disableControl(); + scene->_sceneMode = 97; + setAction(&scene->_sequenceManager, scene, 97, this, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene90::Object2::doAction(int action) { + Scene90 *scene = (Scene90 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_STUNNER: + case CURSOR_USE: + _globals->_player.disableControl(); + scene->_object6.postInit(); + scene->_object6.setVisage(90); + scene->_object6.setStrip(6); + scene->_object6.setPosition(Common::Point(184, 210)); + scene->_object6.hide(); + + scene->_sceneMode = 91; + scene->_soundHandler1.startSound(59); + scene->_soundHandler1.proc5(1); + scene->setAction(&scene->_sequenceManager, scene, 91, this, &scene->_object6, NULL); + break; + case CURSOR_LOOK: + SceneItem::display2(90, 8); + break; + case CURSOR_TALK: + _globals->_player.disableControl(); + setAction(&scene->_sequenceManager, scene, 96, this, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene90::Scene90(): + _item1(0, CURSOR_LOOK, 90, 9, LIST_END), + _item2(0, CURSOR_LOOK, 90, 10, LIST_END), + _item3(0, CURSOR_LOOK, 90, 11, LIST_END), + _object3(OBJECT_STUNNER, 90, 13, CURSOR_LOOK, 90, 12, CURSOR_USE, 90, 16, LIST_END), + _object4(CURSOR_LOOK, 90, 17, LIST_END), + _object5(CURSOR_LOOK, 90, 18, CURSOR_USE, 90, 19, LIST_END) { +} + +void Scene90::stripCallback(int v) { + Scene90 *scene = (Scene90 *)_globals->_sceneManager._scene; + + if (v == 1) + scene->_object2.animate(ANIM_MODE_7, NULL); + else if (v == 2) + scene->_object2.animate(ANIM_MODE_NONE); +} + +void Scene90::postInit(SceneObjectList *OwnerList) { + loadScene(90); + Scene::postInit(); + + setZoomPercents(70, 10, 180, 100); + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerMText); + _stripManager.addSpeaker(&_speakerQL); + _stripManager.addSpeaker(&_speakerSR); + + _speakerMText._npc = &_object2; + _speakerQText._textWidth = 160; + _speakerQText._npc = &_object5; + _speakerSText._npc = &_object1; + + _object5.postInit(); + _object5.setVisage(2333); + _object5.setObjectWrapper(new SceneObjectWrapper()); + _object5._strip = 7; + _object5._moveDiff = Common::Point(22, 22); + _object5.setPosition(Common::Point(151, 177)); + _object5.changeZoom(-1); + _globals->_sceneItems.push_back(&_object5); + + _object1.postInit(); + _object1.setVisage(2337); + _object1.setObjectWrapper(new SceneObjectWrapper()); + _object1._strip = 4; + _object1._moveDiff = Common::Point(20, 20); + _object1.setPosition(Common::Point(212, 183)); + _object1.changeZoom(-1); + _globals->_sceneItems.push_back(&_object1); + + if (!_globals->getFlag(104)) { + _object4.postInit(); + _object4.setVisage(2331); + _object4.setObjectWrapper(new SceneObjectWrapper()); + _object4._strip = 4; + _object4._moveDiff = Common::Point(20, 20); + _object4.setPosition(Common::Point(251, 207)); + _object4.changeZoom(-1); + _globals->_sceneItems.push_back(&_object4); + } + + _object2.postInit(); + _object2.setVisage(90); + _object2.animate(ANIM_MODE_1, NULL); + _object2.setPosition(Common::Point(315, 185)); + _object2._strip = 2; + _globals->_sceneItems.push_back(&_object2); + + _object3.postInit(); + _object3.setVisage(90); + _object3.animate(ANIM_MODE_1, NULL); + _object3.setPosition(Common::Point(196, 181)); + _object3.setPriority2(175); + _globals->_sceneItems.push_back(&_object3); + + _globals->_player.disableControl(); + _globals->_soundHandler.startSound(55); + _soundHandler1.startSound(52); + _soundHandler1.proc5(1); + + setAction(&_action1); + + _item3.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + _item1.setBounds(Rect(271, 65, 271, 186)); + _item2.setBounds(Rect(0, 17, 124, 77)); + + _globals->_sceneItems.addItems(&_item1, &_item2, &_item3, NULL); +} + +void Scene90::signal() { + switch (_sceneMode) { + case 91: + _sceneMode = 92; + _globals->_soundHandler.startSound(77, this); + break; + case 92: + _globals->_scenePalette.clearListeners(); + _globals->_game.endGame(90, 6); + break; + case 96: + _globals->_player.enableControl(); + break; + case 97: + _stripManager._field2E8 = 0; + _action1.setActionIndex(5); + _action1.setDelay(1); + break; + default: + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 95 - Ship Close-up + * + *--------------------------------------------------------------------------*/ + +void Scene95::Action1::signal() { + Scene95 *scene = (Scene95 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _state = 6; + setDelay(60); + break; + case 1: + if (_state) { + SceneItem::display(95, _state % 2, SET_FONT, 2, + SET_EXT_BGCOLOUR, -1, SET_EXT_BGCOLOUR, 20, + SET_WIDTH, 200, SET_KEEP_ONSCREEN, 1, SET_TEXT_MODE, 1, LIST_END); + --_state; + _actionIndex = 1; + } + setDelay(60); + break; + case 2: { + scene->_soundHandler.startSound(66); + scene->_object3._numFrames = 5; + scene->_object3.animate(ANIM_MODE_5, NULL); + SceneItem::display(0, 0); + + Common::Point pt1(5, 198); + NpcMover *mover1 = new NpcMover(); + _globals->_player.addMover(mover1, &pt1, this); + + Common::Point pt2(9, 190); + NpcMover *mover2 = new NpcMover(); + scene->_object1.addMover(mover2, &pt2, NULL); + break; + } + case 3: { + scene->_soundHandler.startSound(21); + + Common::Point pt1(235, 72); + PlayerMover *mover1 = new PlayerMover(); + _globals->_player.addMover(mover1, &pt1, NULL); + + Common::Point pt2(235, 72); + PlayerMover *mover2 = new PlayerMover(); + scene->_object1.addMover(mover2, &pt2, NULL); + + SceneItem::display(95, 2, SET_Y, 45, SET_FONT, 2, + SET_BG_COLOUR, -1, SET_EXT_BGCOLOUR, 13, SET_WIDTH, 200, + SET_KEEP_ONSCREEN, 1, LIST_END); + setDelay(240); + break; + } + case 4: + scene->_object3.remove(); + + SceneItem::display(95, 3, SET_Y, 45, SET_FONT, 2, + SET_BG_COLOUR, -1, SET_EXT_BGCOLOUR, 35, SET_WIDTH, 200, + SET_KEEP_ONSCREEN, 1, LIST_END); + setDelay(240); + break; + case 5: + SceneItem::display(95, 4, SET_Y, 45, SET_FONT, 2, + SET_BG_COLOUR, -1, SET_EXT_BGCOLOUR, 35, SET_WIDTH, 200, + SET_KEEP_ONSCREEN, 1, LIST_END); + setDelay(240); + break; + case 6: + setDelay(20); + break; + case 7: { + SceneItem::display(0, 0); + _globals->_player.setVisage(92); + _globals->_player.setPosition(Common::Point(-25, 200)); + scene->_object1.setVisage(91); + scene->_object1.setPosition(Common::Point(-22, 220)); + + scene->_soundHandler.startSound(21); + + Common::Point pt1(5, 198); + NpcMover *mover1 = new NpcMover(); + _globals->_player.addMover(mover1, &pt1, this); + + Common::Point pt2(9, 190); + NpcMover *mover2 = new NpcMover(); + scene->_object1.addMover(mover2, &pt2, NULL); + break; + } + case 8: { + Common::Point pt1(108, 112); + PlayerMover *mover1 = new PlayerMover(); + _globals->_player.addMover(mover1, &pt1, this); + + Common::Point pt2(108, 112); + PlayerMover *mover2 = new PlayerMover(); + scene->_object1.addMover(mover2, &pt2, NULL); + break; + } + case 9: + _globals->_sceneManager.changeScene(2300); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene95::Scene95() { +} + +void Scene95::postInit(SceneObjectList *OwnerList) { + loadScene(95); + Scene::postInit(); + setZoomPercents(100, 10, 200, 100); + + _globals->_player.postInit(); + _globals->_player.setVisage(2337); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player._strip = 4; + _globals->_player._moveDiff = Common::Point(30, 30); + _globals->_player.setPosition(Common::Point(-35, 200)); + _globals->_player.changeZoom(-1); + _globals->_player.disableControl(); + + _object1.postInit(); + _object1.setVisage(2333); + _object1.setPosition(Common::Point(-22, 220)); + _object1.animate(ANIM_MODE_1, NULL); + _object1.setObjectWrapper(new SceneObjectWrapper()); + _object1._moveDiff = Common::Point(30, 30); + _object1.changeZoom(-1); + + _object3.postInit(); + _object3.setVisage(96); + _object3.setPosition(Common::Point(29, 198)); + + _soundHandler.startSound(67); + setAction(&_action1); +} + +/*-------------------------------------------------------------------------- + * Scene 6100 - Sunflower navigation sequence + * + *--------------------------------------------------------------------------*/ + +void Scene6100::Action1::signal() { + Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->showMessage(SCENE6100_CAREFUL, 13, this); + break; + case 1: + scene->showMessage(SCENE6100_TOUGHER, 35, this); + break; + case 2: + scene->showMessage(NULL, 0, NULL); + remove(); + break; + } +} + +void Scene6100::Action2::signal() { + Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->showMessage(SCENE6100_ONE_MORE_HIT, 13, this); + break; + case 1: + scene->showMessage(SCENE6100_DOING_BEST, 35, this); + break; + case 2: + scene->showMessage(NULL, 0, NULL); + remove(); + break; + } +} + +void Scene6100::Action3::signal() { + Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->_speed = 0; + setDelay(60); + break; + case 1: + _globals->_scenePalette.clearListeners(); + scene->_fadePercent = 0; + _globals->_scenePalette.refresh(); + scene->loadScene(9997); + scene->_object1.hide(); + scene->_object2.hide(); + scene->_object3.hide(); + scene->_sunflower1.hide(); + scene->_sunflower2.hide(); + scene->_sunflower3.hide(); + scene->_rocks.hide(); + scene->_sceneText.hide(); + + _globals->_events.setCursor(CURSOR_WALK); + scene->_stripManager.start(8120, this); + break; + case 2: + scene->showMessage(SCENE6100_REPAIR, 7, this); + break; + case 3: + scene->showMessage(NULL, 0, NULL); + _globals->_events.setCursor(CURSOR_WALK); + scene->_stripManager.start(8130, this); + break; + case 4: + _globals->setFlag(76); + _globals->_sceneManager.changeScene( + (scene->_stripManager._field2E8 == 135) ? 6100 : 2320); + remove(); + break; + } +} + +void Scene6100::Action4::signal() { + Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->showMessage(SCENE6100_ROCKY_AREA, 13, this); + break; + case 1: + scene->showMessage(SCENE6100_REPLY, 35, this); + break; + case 2: + scene->showMessage(NULL, 0, NULL); + remove(); + break; + } +} + +void Scene6100::Action5::dispatch() { + Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene; + FloatSet zeroSet; + const double MULTIPLY_FACTOR = 0.01744; // 2 * pi / 360 + + if (scene->_turnAmount) { + scene->_angle = (scene->_turnAmount + scene->_angle) % 360; + + for (int objIndex = 1; objIndex <= 3; ++objIndex) { + SceneObject *obj = &scene->_object1; + if (objIndex == 2) obj = &scene->_object2; + if (objIndex == 3) obj = &scene->_object3; + + obj->_position.x += scene->_turnAmount * 2; + if (obj->_position.x >= 320) + obj->_position.x -= 480; + if (obj->_position.x < -160) + obj->_position.x += 480; + } + } + + scene->_object1._flags |= OBJFLAG_PANES; + scene->_object2._flags |= OBJFLAG_PANES; + scene->_object3._flags |= OBJFLAG_PANES; + + double distance = scene->_speed; + double angle = (double)scene->_angle * MULTIPLY_FACTOR; + scene->_probe._floats._float1 += sin(angle) * distance; + scene->_probe._floats._float2 += cos(angle) * distance; + + for (int idx = 0; idx < 4; ++idx) { + FloatSet tempSet = scene->_objList[idx]->_floats; + tempSet.add(-scene->_probe._floats._float1, -scene->_probe._floats._float2, + -scene->_probe._floats._float3); + + tempSet.proc1(scene->_angle * MULTIPLY_FACTOR); + + double sqrtVal = tempSet.sqrt(zeroSet); + if (sqrtVal != 0.0) { + scene->_objList[idx]->_position.y = static_cast<int>(13800.0 / sqrtVal + 62.0); + } + + scene->_objList[idx]->_position.x = static_cast<int>( + 160.0 - (330.0 / (tempSet._float2 + 330.0) * tempSet._float1)); + scene->_objList[idx]->dispatch(); + + if (tempSet._float2 < 0) { + scene->_objList[idx]->_position.y = 300; + + if (idx != 3) { + scene->_objList[idx]->_floats._float1 = + _globals->_randomSource.getRandomNumber(199); + scene->_objList[idx]->_floats._float2 = + _globals->_randomSource.getRandomNumber(999) + 750.0; + + scene->_objList[idx]->_floats.proc1( + -(scene->_turnAmount * 10 + scene->_angle) * MULTIPLY_FACTOR); + scene->_objList[idx]->_floats.add(scene->_probe._floats._float1, + scene->_probe._floats._float2, scene->_probe._floats._float3); + } + } + + if (idx == 3) { + scene->_rocksCheck = (ABS((int)tempSet._float1) < 100) && (tempSet._float2 > 0); + } + + scene->_objList[idx]->_flags |= OBJFLAG_PANES; +/* + if ((idx != 3) && (scene->_fadePercent == 100) && + (tempSet.sqrt(floatSet) < 150.0)) { + switch (scene->_hitCount++) { + case 1: + scene->_soundHandler.startSound(233); + scene->showMessage(0, NULL, 0); + + if (!_globals->getFlag(76)) + scene->_object5.setAction(&scene->_action2); + + case 2: + scene->_soundHandler.startSound(234); + scene->showMessage(0, NULL, 0); + + if (!_globals->getFlag(76)) + scene->_object5.setAction(NULL); + scene->setAction(&scene->_action3); + break; + + default: + scene->_soundHandler.startSound(233); + scene->showMessage(0, NULL, 0); + + if (!_globals->getFlag(76)) + scene->_object5.setAction(&scene->_action1); + break; + } + + _globals->_scenePalette.clearListeners(); + scene->_fadePercent = 0; + } + */ + } +} + +void Scene6100::GetBoxAction::signal() { + Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + scene->_turnAmount = 0; + Common::Point pt(scene->_rocks._position.x, scene->_rocks._position.y + 10); + ProbeMover *mover = new ProbeMover(); + scene->_probe.addMover(mover, &pt, NULL); + scene->_probe.show(); + break; + } + case 1: { + scene->showMessage(SCENE6100_TAKE_CONTROLS, 35, this); + _globals->_scenePalette.clearListeners(); + + Common::Point pt(scene->_rocks._position.x, scene->_rocks._position.y - 10); + NpcMover *mover = new NpcMover(); + scene->_probe.addMover(mover, &pt, NULL); + break; + } + case 2: + scene->_probe._percent = 4; + scene->showMessage(SCENE6100_SURPRISE, 13, this); + break; + case 3: + scene->showMessage(SCENE6100_SWEAT, 35, this); + break; + case 4: + scene->showMessage(SCENE6100_VERY_WELL, 13, this); + break; + case 5: + scene->showMessage(NULL, 0, NULL); + _globals->_sceneManager.changeScene(2320); + remove(); + } +} + +void Scene6100::GetBoxAction::dispatch() { + Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene; + + if (!scene->_probe._mover && (scene->_getBoxAction._actionIndex >= 1)) { + if (scene->_getBoxAction._actionIndex == 1) { + scene->_speed = 0; + scene->_getBoxAction.signal(); + } + + if (scene->_probe._percent > 4) + // Handle the probe disappearing into the rocks + scene->_probe._percent = scene->_probe._percent * 7 / 8; + scene->_probe._flags |= OBJFLAG_PANES; + } + + Action::dispatch(); +} + +void Scene6100::Action7::signal() { + switch (_actionIndex++) { + case 0: + setDelay(30); + break; + case 1: + setDelay(90); + break; + case 2: + _globals->_sceneManager.changeScene(2100); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene6100::ProbeMover::dispatch() { + Scene6100 *scene = (Scene6100 *)_globals->_sceneManager._scene; + + if (!dontMove()) { + if (scene->_speed > 0) { + scene->_action5.dispatch(); + scene->_speed = (scene->_speed * 4) / 5; + } + } + + NpcMover::dispatch(); +} + +/*--------------------------------------------------------------------------*/ + +void Scene6100::Item1::doAction(int action) { + SceneItem::display2(4000, 0); +} + +/*--------------------------------------------------------------------------*/ + +void Scene6100::postInit(SceneObjectList *OwnerList) { + loadScene(6100); + Scene::postInit(); + setZoomPercents(62, 2, 200, 425); + + _globals->_player.disableControl(); + _globals->_events.setCursor(CURSOR_WALK); + _stripManager.addSpeaker(&_speakerQR); + _stripManager.addSpeaker(&_speakerSL); + + _object1.postInit(); + _object1.setVisage(6100); + _object1._frame = 1; + _object1._strip = 4; + _object1.setPosition(Common::Point(0, 60)); + _object1.setPriority2(1); + + _object2.postInit(); + _object2.setVisage(6100); + _object2._frame = 1; + _object2._strip = 4; + _object2.setPosition(Common::Point(160, 60)); + _object2.setPriority2(1); + + _object3.postInit(); + _object3.setVisage(6100); + _object3._frame = 1; + _object3._strip = 4; + _object3.setPosition(Common::Point(320, 60)); + _object3.setPriority2(1); + + _rocks.postInit(); + _rocks.setVisage(6100); + _rocks._frame = 1; + _rocks._strip = 3; + _rocks.setPosition(Common::Point(320, 0)); + _rocks.setPriority2(2); + _rocks.changeZoom(-1); + _rocks._floats._float1 = 320.0; + _rocks._floats._float2 = 25000.0; + _rocks._floats._float3 = 0.0; + + _probe.postInit(); + _probe._moveDiff = Common::Point(15, 15); + _probe.setVisage(6100); + _probe._frame = 1; + _probe._strip = 5; + _probe.setPosition(Common::Point(160, 260)); + _probe.setPriority2(3); + _probe._floats._float1 = 320.0; + _probe._floats._float2 = 0.0; + _probe._floats._float3 = 0.0; + _probe.hide(); + + _objList[0] = &_sunflower1; + _objList[1] = &_sunflower2; + _objList[2] = &_sunflower3; + _objList[3] = &_rocks; + + int baseVal = 2000; + for (int idx = 0; idx < 3; ++idx) { + _objList[idx]->_floats._float1 = _globals->_randomSource.getRandomNumber(999); + _objList[idx]->_floats._float2 = baseVal; + _objList[idx]->_floats._float3 = 0.0; + baseVal += _globals->_randomSource.getRandomNumber(499); + + _objList[idx]->postInit(); + _objList[idx]->setVisage(6100); + _objList[idx]->_frame = 1; + _objList[idx]->_strip = 2; + + _objList[idx]->setPosition(Common::Point( + _globals->_randomSource.getRandomNumber(319), 60)); + _objList[idx]->setPriority2(1); + _objList[idx]->changeZoom(-1); + } + + _speed = 30; + _fadePercent = 100; + _rocksCheck = false; + _hitCount = 0; + _turnAmount = 0; + _angle = 0; + _msgActive = false; + + setAction(&_action5); + _globals->_scenePalette.addRotation(96, 143, -1); + + if (!_globals->getFlag(76)) + _probe.setAction(&_action4); + + _globals->_soundHandler.startSound(231); +} + +void Scene6100::remove() { + _globals->_player.disableControl(); + _globals->_scenePalette.clearListeners(); + Scene::remove(); +} + +void Scene6100::process(Event &event) { + Scene::process(event); + + if (event.eventType == EVENT_KEYPRESS) { + // Handle incremental turning speeds with arrow keys + if ((event.kbd.keycode == Common::KEYCODE_LEFT) || (event.kbd.keycode == Common::KEYCODE_KP4)) { + _turnAmount = MAX(_turnAmount - 1, -8); + } else if ((event.kbd.keycode == Common::KEYCODE_RIGHT) || (event.kbd.keycode == Common::KEYCODE_KP6)) { + _turnAmount = MIN(_turnAmount + 1, -8); + } + } + + if (_probe._action) + _probe._action->process(event); +} + +void Scene6100::dispatch() { + Scene::dispatch(); + + if (_probe._action) + _probe._action->dispatch(); + + // Handle mouse controlling the turning + int changeAmount = (_globals->_events._mousePos.x - 160) / -20; + _turnAmount += (changeAmount - _turnAmount) / 2; + + if (_fadePercent < 100) { + _fadePercent += 10; + if (_fadePercent >= 100) { + _globals->_scenePalette.addRotation(96, 143, -1); + _fadePercent = 100; + } + + byte adjustData[] = {0xff, 0xff, 0xff, 0}; + _globals->_scenePalette.fade(adjustData, false, _fadePercent); + } + + if (_action != &_action3) { + // Display the distance remaining to the target + int distance = _probe._floats.sqrt(_rocks._floats); + Common::String s = Common::String::format("%06d", distance); + + _sceneText.setPosition(Common::Point(24, 160)); + _sceneText._fontNumber = 0; + _sceneText._colour1 = 35; + _sceneText.setup(s); + } + + if (_rocksCheck && (_action == &_action5)) { + // Check whether the probe is close enough to the rocks + double distance = _probe._floats.sqrt(_rocks._floats); + + if ((distance >= 300.0) && (distance <= 500.0)) + setAction(&_getBoxAction); + } +} + +void Scene6100::showMessage(const Common::String &msg, int colour, Action *action) { + if (_msgActive) { + _msgActive = false; + _speaker1.removeText(); + } + + if (!msg.empty()) { + _msgActive = true; + _speaker1._textPos.x = 20; + _speaker1._textWidth = 280; + _speaker1._colour1 = colour; + _speaker1._action = action; + _speaker1.setText(msg); + } +} + +} // End of namespace tSage diff --git a/engines/tsage/ringworld_scenes1.h b/engines/tsage/ringworld_scenes1.h new file mode 100644 index 0000000000..89aa0a65c5 --- /dev/null +++ b/engines/tsage/ringworld_scenes1.h @@ -0,0 +1,557 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/scene_logic.h $ + * $Id: scene_logic.h 232 2011-02-12 11:56:38Z dreammaster $ + * + */ + +#ifndef TSAGE_RINGWORLD_SCENES1_H +#define TSAGE_RINGWORLD_SCENES1_H + +#include "common/scummsys.h" +#include "tsage/ringworld_logic.h" +#include "tsage/converse.h" +#include "tsage/events.h" +#include "tsage/core.h" +#include "tsage/scenes.h" +#include "tsage/globals.h" + +namespace tSage { + +class Scene10: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; +public: + Speaker _speakerSText; + Speaker _speakerQText; + Action1 _action1; + Action2 _action2; + SceneObject _object1, _object2, _object3; + SceneObject _object4, _object5, _object6; + + virtual void stripCallback(int v); + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + +class Scene15: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + virtual void dispatch(); + }; +public: + Action1 _action1; + SceneObject _object1; + SoundHandler _soundHandler; + + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + +class Scene20: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; +public: + SequenceManager _sequenceManager; + SpeakerQText _speakerQText; + SpeakerGameText _speakerGameText; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + SceneObject _sceneObject1, _SceneObjectExt, _sceneObject3, _sceneObject4, _sceneObject5; + SoundHandler _sound; +public: + Scene20(); + virtual ~Scene20() {} + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); +}; + +class Scene30: public Scene { + /* Scene objects */ + // Doorway beam sensor + class BeamObject: public SceneObject { + public: + virtual void doAction(int action) { + if (action == OBJECT_SCANNER) + display(30, 14, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + else if (action == CURSOR_LOOK) + display(30, 2, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + else if (action == CURSOR_USE) { + Scene30 *parent = (Scene30 *)_globals->_sceneManager._scene; + parent->setAction(&parent->_beamAction); + } else + SceneObject::doAction(action); + } + }; + + // Doorway object + class DoorObject: public SceneObject { + public: + virtual void doAction(int action) { + if (action == OBJECT_SCANNER) + display(30, 13, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + else if (action == CURSOR_LOOK) + display(30, 1, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + else if (action == CURSOR_USE) + display(30, 7, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + else + SceneObject::doAction(action); + } + }; + + // Kzin object + class KzinObject: public SceneObject { + public: + virtual void doAction(int action); + }; + + /* Actions */ + class BeamAction: public Action { + public: + virtual void signal(); + }; + class KzinAction: public Action { + public: + virtual void signal(); + }; + class RingAction: public Action { + public: + virtual void signal(); + }; + class TalkAction: public Action { + public: + virtual void signal(); + }; + +public: + SoundHandler _sound; + DisplayHotspot _groundHotspot, _wallsHotspot, _courtyardHotspot, _treeHotspot; + BeamObject _beam; + DoorObject _door; + KzinObject _kzin; + + BeamAction _beamAction; + KzinAction _kzinAction; + RingAction _ringAction; + TalkAction _talkAction; + SequenceManager _sequenceManager; + + SpeakerSR _speakerSR; + SpeakerQL _speakerQL; + SpeakerSText _speakerSText; + SpeakerQText _speakerQText; +public: + Scene30(); + virtual ~Scene30() {} + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); +}; + +class Scene40: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + class Action5: public Action { + public: + virtual void signal(); + }; + class Action6: public Action { + public: + virtual void signal(); + }; + class Action7: public Action { + public: + virtual void signal(); + }; + class Action8: public Action { + public: + virtual void signal(); + }; + + /* Objects */ + class DyingKzin: public SceneObject { + public: + virtual void doAction(int action); + }; + class Assassin: public SceneObject { + public: + virtual void doAction(int action); + }; + + /* Items */ + class Item2: public SceneItem { + public: + virtual void doAction(int action); + }; + class Item6: public SceneItem { + public: + virtual void doAction(int action); + }; + class Item8: public SceneItem { + public: + virtual void doAction(int action); + }; +public: + SequenceManager _sequenceManager; + SpeakerSL _speakerSL; + SpeakerQR _speakerQR; + SpeakerQText _speakerQText; + SpeakerSText _speakerSText; + SpeakerGameText _speakerGameText; + SoundHandler _soundHandler; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Action5 _action5; + Action6 _action6; + Action7 _action7; + Action8 _action8; + SceneObject _object1, _object2, _object3; + DyingKzin _dyingKzin; + Assassin _assassin; + SceneObject _doorway, _object7, _object8; + DisplayHotspot _item1; + Item2 _item2; + DisplayHotspot _item3, _item4, _item5; + Item6 _item6; + DisplayHotspot _item7, _item8; + + Scene40(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene50: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + + /* Objects */ + class Object1: public SceneObject { + public: + virtual void doAction(int action); + }; + class Object2: public SceneObject { + public: + virtual void doAction(int action); + }; + class Object3: public SceneObject { + public: + virtual void doAction(int action); + }; + class Object4: public SceneObject { + public: + virtual void doAction(int action); + }; + +public: + SequenceManager _sequenceManager; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Object1 _object1; + Object2 _object2; + Object3 _object3; + Object4 _object4; + Rect _doorwayRect; + SpeakerSText _speakerSText; + SpeakerQText _speakerQText; + DisplayHotspot _item0, _item1, _item2; + DisplayHotspot _item3, _item4, _item5; + + Scene50(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene60: public Scene { + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Object2: public SceneObject { + public: + virtual void doAction(int action); + }; + class Object3: public SceneObject { + public: + virtual void doAction(int action); + }; + class Object4: public SceneObject { + public: + virtual void doAction(int action); + }; + class Object5: public SceneObject { + public: + virtual void doAction(int action); + }; + class Object6: public SceneObject { + public: + virtual void doAction(int action); + }; + class SlaveObject: public SceneObjectExt { + public: + virtual void doAction(int action); + }; + class Object8: public SceneObjectExt { + public: + virtual void doAction(int action); + }; + class Object9: public SceneObject { + public: + virtual void doAction(int action); + }; + class Item1: public SceneHotspot { + public: + virtual void doAction(int action); + }; + class Item: public SceneHotspot { + public: + int _messageNum, _sceneMode; + + Item(int sceneRegionId, int messageNum, int sceneMode) { + _sceneRegionId = sceneRegionId; + _messageNum = messageNum; + _sceneMode = sceneMode; + } + virtual void doAction(int action); + }; + +public: + GfxButton _gfxButton; + SequenceManager _sequenceManager; + SpeakerQText _speakerQText; + SpeakerSText _speakerSText; + Action1 _action1; + Action2 _action2; + SceneObject _object1; + Object2 _object2; + Object3 _object3; + Object4 _object4; + Object5 _object5; + Object6 _object6; + SlaveObject _slaveButton; + Object8 _object8; + Object9 _object9; + SceneObject _object10; + Item1 _item1; + Item _item2, _item3, _item4, _item5, _item6; + SoundHandler _soundHandler1; + SoundHandler _soundHandler2; + SoundHandler _soundHandler3; + + Scene60(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void process(Event &event); +}; + +class Scene90: public Scene { + class Action1: public Action { + public: + virtual void signal(); + }; + class Object1: public SceneObject { + public: + virtual void doAction(int action); + }; + class Object2: public SceneObject { + public: + virtual void doAction(int action); + }; +public: + SequenceManager _sequenceManager; + SpeakerSText _speakerSText; + SpeakerQText _speakerQText; + SpeakerQL _speakerQL; + SpeakerSR _speakerSR; + SpeakerMText _speakerMText; + Action1 _action1; + Object1 _object1; + Object2 _object2; + DisplayObject _object3, _object4, _object5; + SceneObject _object6; + DisplayHotspot _item1, _item2, _item3; + SoundHandler _soundHandler1, _soundHandler2; + + Scene90(); + + virtual void stripCallback(int v); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); +}; + +class Scene95: public Scene { + class Action1: public ActionExt { + public: + virtual void signal(); + }; + +public: + Action1 _action1; + int _field326; + SceneObject _object1, _object2, _object3; + SoundHandler _soundHandler; + + Scene95(); + virtual void postInit(SceneObjectList *OwnerList); +}; + +class Scene6100: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + class Action5: public Action { + public: + virtual void dispatch(); + }; + class GetBoxAction: public Action { + public: + virtual void signal(); + virtual void dispatch(); + }; + class Action7: public Action { + public: + virtual void signal(); + }; + + /* Objects */ + class Object: public SceneObject { + public: + FloatSet _floats; + }; + class ProbeMover: public NpcMover { + public: + virtual void dispatch(); + }; + + /* Items */ + class Item1: public SceneItem { + public: + virtual void doAction(int action); + }; + +public: + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Action5 _action5; + GetBoxAction _getBoxAction; + Action7 _action7; + SoundHandler _soundHandler; + Speaker _speaker1; + SpeakerQR _speakerQR; + SpeakerSL _speakerSL; + SceneObject _object1, _object2, _object3; + Object _rocks, _probe; + Object _sunflower1, _sunflower2, _sunflower3; + SceneText _sceneText; + SceneItem _item1; + + int _turnAmount, _angle, _speed, _fadePercent; + int _hitCount; + bool _rocksCheck; + Object *_objList[4]; + bool _msgActive; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void remove(); + virtual void process(Event &event); + virtual void dispatch(); + void showMessage(const Common::String &msg, int colour, Action *action); + +}; + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/ringworld_scenes10.cpp b/engines/tsage/ringworld_scenes10.cpp new file mode 100644 index 0000000000..5ea5077b74 --- /dev/null +++ b/engines/tsage/ringworld_scenes10.cpp @@ -0,0 +1,2063 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/scene_logic.cpp $ + * $Id: scene_logic.cpp 232 2011-02-12 11:56:38Z dreammaster $ + * + */ + +#include "graphics/cursorman.h" +#include "tsage/ringworld_scenes10.h" +#include "tsage/scenes.h" +#include "tsage/tsage.h" +#include "tsage/staticres.h" + +namespace tSage { + +Scene2::Scene2() { + Scene::Scene(); + _sceneState = 0; +} + +/*--------------------------------------------------------------------------*/ + +void Object9350::postInit(SceneObjectList *OwnerList) { + _globals->_sceneManager.postInit(&_globals->_sceneManager._altSceneObjects); +} + +void Object9350::draw() { + reposition(); + Rect destRect = _bounds; + destRect.translate(-_globals->_sceneOffset.x, -_globals->_sceneOffset.y); + Region *priorityRegion = _globals->_sceneManager._scene->_priorities.find(_globals->_sceneManager._scene->_stripManager._stripNum); + GfxSurface frame = getFrame(); + _globals->gfxManager().copyFrom(frame, destRect, priorityRegion); +} + +/*-------------------------------------------------------------------------- + * Scene 9100 + * + *--------------------------------------------------------------------------*/ +void Scene9100::SceneHotspot1::doAction(int action) { + Scene9100 *scene = (Scene9100 *)_globals->_sceneManager._scene; + + if (action == CURSOR_TALK) { + if (_globals->getFlag(23)) { + _globals->_player.disableControl(); + scene->_sceneMode = 9104; + } else { + _globals->setFlag(23); + _globals->_player.disableControl(); + scene->_sceneMode = 9105; + } + scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &_globals->_player, &scene->_object5, &scene->_object6, 0); + } else { + NamedHotspot::doAction(action); + } +} + +void Scene9100::dispatch() { + Scene9100 *scene = (Scene9100 *)_globals->_sceneManager._scene; + + if (!_action) { + if (_globals->_player._position.x < 25) { + if (!_globals->getFlag(11)) { + scene->_sceneMode = 9106; + } else { + scene->_sceneMode = 9108; + _globals->setFlag(11); + } + } else { + scene->_sceneMode = 9106; + } + scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, &_globals->_player, 0); + } else { + Scene::dispatch(); + } +} + +void Scene9100::signal() { + Scene9100 *scene = (Scene9100 *)_globals->_sceneManager._scene; + + switch (scene->_sceneMode) { + case 9102: + case 9106: + case 9108: + _globals->_sceneManager.changeScene(9150); + break; + case 9105: + _sceneHotspot1.remove(); + // No break on purpose + case 9103: + case 9104: + case 9107: + case 9109: + default: + _globals->_player.enableControl(); + break; + } +} + +void Scene9100::postInit(SceneObjectList *OwnerList) { + Scene9100 *scene = (Scene9100 *)_globals->_sceneManager._scene; + + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + _object1.postInit(); + _object1.setVisage(9100); + _object1._strip = 1; + _object1._numFrames = 6; + _object1.setPosition(Common::Point(297, 132), 0); + _object1.animate(ANIM_MODE_2, 0); + _object1.setPriority2(10); + + _globals->_player.postInit(); + + _object2.postInit(); + _object2.hide(); + + _object3.postInit(); + _object3.hide(); + + _object4.postInit(); + _object4.hide(); + + _object5.postInit(); + _object5.hide(); + + if (!_globals->getFlag(23)) { + _object6.postInit(); + _object6.setVisage(9111); + _object6.setStrip(6); + _object6.setFrame(1); + _object6.setPosition(Common::Point(138, 166), 0); + _sceneHotspot3.setup(145, 125, 166, 156, 9100, 40, 43); + } + _sceneHotspot1.setup(140, 176, 185, 215, 9100, 36, 37); + _sceneHotspot2.setup(161, 138, 182, 175, 9100, 38, 39); + _sceneHotspot4.setup(37, 196, 47, 320, 9100, 44, -1); + _sceneHotspot5.setup(69, 36, 121, 272, 9100, 45, 46); + _sceneHotspot6.setup(127, 0, 200, 52, 9100, 47, 48); + + _globals->_soundHandler.startSound(251, 0, 127); + if (_globals->_sceneManager._previousScene == 9150) { + if (_globals->getFlag(20)) { + _globals->_player.disableControl(); + if (_globals->getFlag(11)) + _sceneMode = 9107; + else + _sceneMode = 9109; + setAction(&scene->_sequenceManager, scene, _sceneMode, &_globals->_player, &_object5, 0); + } else { + _sceneMode = 9103; + _globals->_player.disableControl(); + setAction(&scene->_sequenceManager, scene, _sceneMode, &_globals->_player, &_object2, &_object3, &_object4, &_object5, 0); + _globals->setFlag(20); + } + } else { + _sceneMode = 9102; + _globals->_player.disableControl(); + setAction(&scene->_sequenceManager, scene, _sceneMode, &_globals->_player, &_object2, &_object3, &_object4, &_object5, 0); + } +} + +/*-------------------------------------------------------------------------- + * Scene 9150 + * + *--------------------------------------------------------------------------*/ +void Scene9150::Object3::signal() { + switch (_signalFlag++) { + case 0: + _timer = 10 + _globals->_randomSource.getRandomNumber(90); + break; + default: + animate(ANIM_MODE_5, this); + _signalFlag = 0; + break; + } +} + +void Scene9150::Object3::dispatch() { + SceneObject::dispatch(); + if ((_timer != 0) && (--_timer == 0)) + signal(); +} + +void Scene9150::signal() { + switch (_sceneMode) { + case 9151: + case 9157: + _globals->_sceneManager.changeScene(9100); + break; + case 9153: + _globals->_sceneManager.changeScene(9300); + break; + case 9152: + case 9155: + case 9156: + _globals->_player.enableControl(); + break; + case 9154: + default: + break; + } +} + +void Scene9150::dispatch() { + + if ((_sceneState != 0) && (_sceneBounds.left == 0)) { + _object3._timer = 0; + _sceneState = 0; + _sceneHotspot3.setAction(&_sequenceManager2, 0, 9154, &_object3, 0); + _sceneHotspot10.remove(); + } + + if (_action) { + _action->dispatch(); + } else { + if (_globals->_player._position.x >= 160) { + if (_globals->_player._position.x > 630) { + _globals->_player.disableControl(); + _sceneMode = 9157; + setAction(&_sequenceManager1, this, _sceneMode, &_globals->_player, 0); + } + } else { + _globals->_player.disableControl(); + if (_globals->getFlag(11)) { + _globals->_soundHandler.startSound(286, 0, 127); + _sceneMode = 9153; + } else { + _sceneMode = 9156; + } + setAction(&_sequenceManager1, this, _sceneMode, &_globals->_player, 0); + } + } +} + +void Scene9150::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + _globals->_player.postInit(); + + _object3.postInit(); + _sceneState = 1; + _object3.setVisage(9151); + _object3._strip = 1; + _object3._frame = 1; + _object3.setPosition(Common::Point(312, 95), 0); + _object3.signal(); + + _sceneHotspot1.setup(0, 0, 200, 94, 9150, 46, -1); + _sceneHotspot2.setup(51, 90, 118, 230, 9150, 47, -1); + _sceneHotspot3.setup(182, 104, 200, 320, 9150, 48, 49); + _sceneHotspot4.setup(103, 292, 152, 314, 9150, 50, 51); + _sceneHotspot5.setup(115, 350, 160, 374, 9150, 52, 53); + _sceneHotspot6.setup(0, 471, 200, 531, 9150, 54, 55); + _sceneHotspot7.setup(170, 320, 185, 640, 9150, 56, -1); + _sceneHotspot9.setup(157, 107, 186, 320, 9150, 56, -1); + _sceneHotspot8.setup(133, 584, 142, 640, 9150, 57, -1); + _sceneHotspot10.setup(83, 304, 103, 323, 9150, 58, 59); + + _globals->_soundHandler.startSound(285, 0, 127); + _globals->_player.disableControl(); + + if (_globals->getFlag(20)) { + // Walking alone + _globals->_scrollFollower = &_globals->_player; + if (_globals->getFlag(11)) + // Hero wearing peasan suit + _sceneMode = 9155; + else + // Hero wearing Purple suit + _sceneMode = 9152; + setAction(&_sequenceManager1, this, _sceneMode, &_globals->_player, 0); + } else { + // Walking with the tiger + _sceneMode = 9151; + _object2.postInit(); + _object2.hide(); + _object1.postInit(); + setAction(&_sequenceManager1, this, _sceneMode, &_globals->_player, &_object1, &_object2, 0); + } +} + +/*-------------------------------------------------------------------------- + * Scene 9200 + * + *--------------------------------------------------------------------------*/ +void Scene9200::SceneHotspot1::doAction(int action) { + Scene9200 *scene = (Scene9200 *)_globals->_sceneManager._scene; + + if (action == OBJECT_TUNIC) { + _globals->_player.disableControl(); + if (_globals->getFlag(93)) { + scene->_sceneState = 9214; + setAction(&scene->_sequenceManager, scene, 9214, &_globals->_player, &scene->_object2, 0); + } else { + _globals->setFlag(93); + scene->_sceneState = 9213; + setAction(&scene->_sequenceManager, scene, 9213, &_globals->_player, &scene->_object2, 0); + } + } else if (action <= 100) { + _globals->_player.disableControl(); + scene->_sceneState = 9214; + setAction(&scene->_sequenceManager, scene, 9214, &_globals->_player, &scene->_object2, 0); + } else { + NamedHotspot::doAction(action); + } +} + +void Scene9200::signal() { + switch (_sceneState++) { + case 9207: + _globals->_sceneManager.changeScene(9700); + break; + case 9208: + case 9211: + case 9212: + _globals->_sceneManager.changeScene(9500); + break; + case 9209: + _globals->_sceneManager.changeScene(9360); + break; + case 9210: + _hotspot1.remove(); + // No break on purpose + case 9201: + case 9202: + case 9203: + case 9204: + case 9205: + case 9206: + default: + _globals->_player.enableControl(); + break; + } +} + +void Scene9200::process(Event &event) { + Scene::process(event); +} + +void Scene9200::dispatch() { +// Rect rect9200 = Rect(320, 175, 250, 154); + Rect rect9200 = Rect(250, 154, 320, 175); + + if (_action) { + _action->dispatch(); + } else { + if ( (_globals->_player._position.x <= 0) || ((_globals->_player._position.x < 100) && (_globals->_player._position.y > 199))) { + _globals->_player.disableControl(); + _sceneState = 9209; + setAction(&_sequenceManager, this, 9209, &_globals->_player, &_object2, &_object3, 0); + } else { + if (rect9200.contains(_globals->_player._position)) { + if (_globals->getFlag(93)) { + if (_globals->getFlag(86)) { + _sceneState = 9215; + setAction(&_sequenceManager, this, 9215, &_globals->_player, &_object2, &_object3, 0); + } else { + _sceneState = 9208; + setAction(&_sequenceManager, this, 9208, &_globals->_player, &_object2, &_object3, 0); + } + } else { + _globals->_player.disableControl(); + _sceneState = 9204; + setAction(&_sequenceManager, this, 9204, &_globals->_player, &_object2, &_object3, 0); + } + } else { + if (_globals->_player._position.y < 140) { + _globals->_player.disableControl(); + _sceneState = 9207; + setAction(&_sequenceManager, this, 9207, &_globals->_player, &_object2, &_object3, 0); + } + } + } + } +} + +void Scene9200::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(130, 50, 200, 150); + + _globals->_player.postInit(); + _object3.postInit(); + _object3.hide(); + _object1.postInit(); + // Water animation + _object1.setVisage(9200); + _object1._strip = 3; + _object1.animate(ANIM_MODE_2, 0); + _object1.setPosition(Common::Point(132, 114), 0); + _object1.setPriority2(140); + _soundHandler.startSound(297, 0, 127); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerGR); + _stripManager.addSpeaker(&_speakerGText); + + if (!_globals->getFlag(86)) { + _object2.postInit(); + _hotspot1.setup(96, 194, 160, 234, 9200, 29, 31); + } + _hotspot2.setup(164, 0, 200, 282, 9200, 0, 1); + _hotspot3.setup(140, 39, 165, 153, 9200, 2, 3); + _hotspot4.setup(92, 122, 139, 152, 9200, 4, 5); + _hotspot5.setup(33, 20, 142, 115, 9200, 6, 7); + _hotspot6.setup(104, 235, 153, 265, 9200, 8, 9); + _hotspot7.setup(107, 262, 153, 286, 9200, 10, 11); + _hotspot8.setup(69, 276, 164, 320, 9200, 12, 13); + + _globals->_events.setCursor(CURSOR_WALK); + _globals->_player.disableControl(); + + switch (_globals->_sceneManager._previousScene) { + case 9500: + if (_globals->getFlag(85)) { + if (_globals->_inventory._helmet._sceneNumber == 1) { + _globals->setFlag(86); + _sceneState = 9210; + setAction(&_sequenceManager, this, 9210, &_globals->_player, &_object2, &_object3, 0); + } else { + _sceneState = 9212; + setAction(&_sequenceManager, this, 9212, &_globals->_player, &_object2, &_object3, 0); + } + } else { + if (_globals->_inventory._helmet._sceneNumber == 1) { + _sceneState = 9211; + setAction(&_sequenceManager, this, 9211, &_globals->_player, &_object2, &_object3, 0); + } else { + _sceneState = 9202; + setAction(&_sequenceManager, this, 9202, &_globals->_player, &_object2, &_object3, 0); + } + } + break; + case 9700: + if (_globals->getFlag(86)) { + _sceneState = 9206; + setAction(&_sequenceManager, this, 9206, &_globals->_player, &_object2, &_object3, 0); + } else { + _sceneState = 9203; + setAction(&_sequenceManager, this, 9203, &_globals->_player, &_object2, &_object3, 0); + } + break; + case 9360: + default: + if (_globals->getFlag(86)) { + _sceneState = 9205; + setAction(&_sequenceManager, this, 9205, &_globals->_player, &_object2, &_object3, 0); + } else { + _sceneState = 9201; + setAction(&_sequenceManager, this, 9201, &_globals->_player, &_object2, &_object3, 0); + } + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 9300 + * + *--------------------------------------------------------------------------*/ +void Scene9300::signal() { + switch (_sceneMode++) { + case 9301: + _globals->setFlag(84); + // No break on purpose + case 9303: + _globals->_soundHandler.startSound(295, 0, 127); + _globals->_sceneManager.changeScene(9350); + break; + case 9302: + _globals->_player.enableControl(); + break; + default: + break; + } +} + +void Scene9300::dispatch() { + if (_action) { + _action->dispatch(); + } else if (_globals->_player._position.y < 145) { + _globals->_player.disableControl(); + _sceneMode = 9303; + setAction(&_sequenceManager, this, 9303, &_globals->_player, &_object1, &_object2, 0); + } +} + +void Scene9300::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(130, 75, 230, 150); + + _sceneMode = 0; + _globals->_player.postInit(); + _globals->_player.changeZoom(-1); + _object1.postInit(); + _object2.postInit(); + _globals->_soundHandler.startSound(289, 0, 127); + + _hotspot1.setup(35, 142, 76, 212, 9300, 0, 1); + _hotspot2.setup(28, 90, 81, 143, 9300, 2, 3); + _hotspot3.setup(78, 142, 146, 216, 9300, 4, 5); + _hotspot4.setup(3, 43, 91, 74, 9300, 6, 7); + _hotspot5.setup(82, 19, 157, 65, 9300, 8, 9); + _hotspot6.setup(5, 218, 84, 274, 9300, 10, 11); + _hotspot7.setup(86, 233, 168, 293, 9300, 12, 13); + _hotspot8.setup(157, 0, 200, 230, 9300, 14, 15); + _hotspot9.setup(169, 227, 200, 320, 9300, 16, 17); + _hotspot10.setup(145, 97, 166, 225, 9300, 18, 19); + _hotspot11.setup(81, 75, 145, 145, 9300, 20, 21); + _hotspot12.setup(0, 0, 94, 35, 9300, 22, 23); + _hotspot13.setup(12, 268, 149, 320, 9300, 24, 25); + + if (_globals->_sceneManager._previousScene == 9350) { + _globals->_player.disableControl(); + _sceneMode = 9302; + setAction(&_sequenceManager, this, 9302, &_globals->_player, &_object1, &_object2, 0); + } else { + _globals->_player.disableControl(); + _sceneMode = 9301; + setAction(&_sequenceManager, this, 9301, &_globals->_player, &_object1, &_object2, 0); + } +} + +/*-------------------------------------------------------------------------- + * Scene 9350 + * + *--------------------------------------------------------------------------*/ + +void Scene9350::signal() { + switch (_sceneState ++) { + case 0: + case 9352: + case 9353: + case 9354: + _globals->_player.enableControl(); + break; + case 9355: + _globals->_sceneManager.changeScene(9300); + break; + case 9356: + _globals->_sceneManager.changeScene(9360); + break; + case 9357: + case 9359: + _globals->_sceneManager.changeScene(9400); + break; + default: + break; + } +} + +void Scene9350::dispatch() { + if (_action == 0) { + if ((_globals->_player._position.x > 300) && (_globals->_player._position.y < 160)) { + _globals->_player.disableControl(); + _sceneState = 9356; + setAction(&_sequenceManager, this, 9356, &_globals->_player, &_object2, 0); + } else if ((_globals->_player._position.x > 110) && (_globals->_player._position.y >= 195)) { + _globals->_player.disableControl(); + _sceneState = 9357; + setAction(&_sequenceManager, this, 9357, &_globals->_player, &_object2, 0); + } else if ((_globals->_player._position.x < 10) || ((_globals->_player._position.x <= 110) && (_globals->_player._position.y >= 195))) { + _globals->_player.disableControl(); + _sceneState = 9355; + setAction(&_sequenceManager, this, 9355, &_globals->_player, &_object2, 0); + } + } else { + Scene::dispatch(); + } +} + +void Scene9350::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(95, 80, 200, 100); + _globals->_player.postInit(); + + _object1.setup(9350, 1, 3, 139, 97, 0); + _sceneHotspot1.setup(42, 0, 97, 60, 9350, 0, -1); + _sceneHotspot2.setup(37, 205, 82, 256, 9350, 0, -1); + _sceneHotspot3.setup(29, 93, 92, 174, 9350, 1, -1); + _sceneHotspot4.setup(0, 308, 109, 320, 9350, 2, -1); + _sceneHotspot5.setup(0, 0, 200, 320, 9350, 3, -1); + + _globals->_events.setCursor(CURSOR_WALK); + _globals->_player.disableControl(); + + if (_globals->_sceneManager._previousScene == 9360) { + _globals->_player.disableControl(); + _sceneState = 9352; + setAction(&_sequenceManager, this, 9352, &_globals->_player, &_object2, 0); + } else if (_globals->_sceneManager._previousScene == 9400) { + _globals->_player.disableControl(); + _sceneState = 9353; + setAction(&_sequenceManager, this, 9353, &_globals->_player, &_object2, 0); + } else { + if (!_globals->getFlag(84)) { + _globals->clearFlag(84); + _object2.postInit(); + _globals->_player.disableControl(); + _sceneState = 9359; + setAction(&_sequenceManager, this, 9359, &_globals->_player, &_object2, 0); + } else { + _globals->_player.disableControl(); + _sceneState = 9354; + setAction(&_sequenceManager, this, 9354, &_globals->_player, &_object2, 0); + } + } +} + +/*-------------------------------------------------------------------------- + * Scene 9360 + * + *--------------------------------------------------------------------------*/ + +void Scene9360::signal() { + switch (_sceneState ++) { + case 0: + case 9362: + case 9363: + case 9364: + _globals->_player.enableControl(); + break; + case 9365: + _globals->_sceneManager.changeScene(9350); + break; + case 9366: + _globals->_sceneManager.changeScene(9200); + break; + case 9367: + _globals->_sceneManager.changeScene(9450); + break; + default: + break; + } +} + +void Scene9360::dispatch() { + if (_action == 0) { + if ((_globals->_player._position.x > 300) && (_globals->_player._position.y < 160)) { + _globals->_player.disableControl(); + _sceneState = 9366; + setAction(&_sequenceManager, this, 9366, &_globals->_player, 0); + } else if ((_globals->_player._position.x > 110) && (_globals->_player._position.y >= 195)) { + _globals->_player.disableControl(); + _sceneState = 9367; + setAction(&_sequenceManager, this, 9367, &_globals->_player, 0); + } else if ((_globals->_player._position.x < 10) || ((_globals->_player._position.x <= 110) && (_globals->_player._position.y >= 195))) { + _globals->_player.disableControl(); + _sceneState = 9365; + setAction(&_sequenceManager, this, 9365, &_globals->_player, 0); + } + } else { + Scene::dispatch(); + } +} + +void Scene9360::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(95, 80, 200, 100); + _globals->_player.postInit(); + + _hotspot1.setup(37, 92, 93, 173, 9360, 0, 1); + _hotspot2.setup(42, 0, 100, 63, 9360, 2, -1); + _hotspot3.setup(36, 205, 82, 260, 9360, 3, -1); + _hotspot4.setup(103, 2, 200, 320, 9360, 4, -1); + _hotspot5.setup(0, 0, 37, 320, 9360, 4, -1); + _hotspot6.setup(35, 61, 103, 92, 9360, 4, -1); + _hotspot7.setup(33, 174, 93, 207, 9360, 4, -1); + _hotspot8.setup(28, 257, 149, 320, 9360, 4, -1); + _globals->_events.setCursor(CURSOR_WALK); + _globals->_player.disableControl(); + if (_globals->_sceneManager._previousScene == 9350) { + _globals->_player.disableControl(); + _sceneState = 9364; + setAction(&_sequenceManager, this, 9364, &_globals->_player, 0); + } else if (_globals->_sceneManager._previousScene == 9450) { + _globals->_player.disableControl(); + _sceneState = 9363; + setAction(&_sequenceManager, this, 9363, &_globals->_player, 0); + } else { + _globals->_player.disableControl(); + _sceneState = 9362; + setAction(&_sequenceManager, this, 9362, &_globals->_player, 0); + } + _object1.setup(9351, 1, 1, 131, 90, 0); +} + +/*-------------------------------------------------------------------------- + * Scene 9400 + * + *--------------------------------------------------------------------------*/ +Scene9400::Scene9400() { + _field1032 = 0; +} + +void Scene9400::SceneHotspot7::doAction(int action) { + Scene9400 *scene = (Scene9400 *)_globals->_sceneManager._scene; + + if ((action == CURSOR_USE) && (_globals->_inventory._straw._sceneNumber != 1)) { + scene->_sceneState = 1; + scene->setAction(&scene->_sequenceManager, scene, 9408, &_globals->_player, 0); + } else { + NamedHotspot::doAction(action); + } +} + +void Scene9400::SceneHotspot8::doAction(int action) { + Scene9400 *scene = (Scene9400 *)_globals->_sceneManager._scene; + + if (action == CURSOR_TALK) { + _globals->_player.disableControl(); + scene->_sceneState = 2; + scene->signal(); + } else { + NamedHotspot::doAction(action); + } +} + +void Scene9400::signal() { + switch (_sceneState ++) { + case 0: + _object1._numFrames = 6; + _stripManager.start(9400, this); + break; + case 1: + _object1._numFrames = 6; + _object1.animate(ANIM_MODE_2, 0); + _globals->_player.enableControl(); + break; + case 2: + _object1.animate(ANIM_MODE_5, this); + break; + case 3: + _stripManager.start(9405, this); + break; + case 4: + _object1.animate(ANIM_MODE_2, this); + _globals->_player.enableControl(); + break; + case 9350: + _globals->_sceneManager.changeScene(9350); + break; + default: + break; + } +} + +void Scene9400::dispatch() { + if ((_object1._animateMode == 2) && (_object1._strip == 1) && (_object1._frame == 4)){ + if (_field1032 == 0) { + _soundHandler.startSound(296, 0, 127); + _field1032 = 1; + } + } else { + _field1032 = 0; + } + if (_action == 0) { + if (_globals->_player._position.y < 120) { + _sceneState = 9350; + _globals->_player.disableControl(); + setAction(&_action1); + Common::Point pt(-45, 88); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + } + } else { + Scene::dispatch(); + } +} + +void Scene9400::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + _sceneNumber = 9400; + setZoomPercents(0, 100, 200, 100); + _globals->_player.postInit(); + _object1.postInit(0); + _object3.postInit(0); + _speakerQText._textPos.x = 20; + + _hotspot7.setup(157, 66, 180, 110, 9400, 21, 23); + _hotspot5.setup(130, 133, 152, 198, 9400, 22, -1); + _hotspot1.setup(33, 280, 69, 297, 9400, 1, 2); + _hotspot2.setup(73, 96, 87, 159, 9400, 3, 4); + _hotspot3.setup(89, 253, 111, 305, 9400, 5, 6); + _hotspot4.setup(46, 0, 116, 35, 9400, 7, 8); + _hotspot8.setup(58, 169, 122, 200, 9400, 9, 10); + _hotspot6.setup(0, 0, 199, 319, 9400, 16, 0); + + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerOR); + _stripManager.addSpeaker(&_speakerOText); + + _globals->_events.setCursor(CURSOR_WALK); + _globals->_player.disableControl(); + + // Useless check (skipped) : if (_globals->_sceneManager._previousScene == 9350) + _sceneState = 2; + if (!_globals->getFlag(89)) { + _globals->setFlag(89); + _sceneState = 0; + } + + setAction(&_sequenceManager, this, 9400, &_globals->_player, &_object1, &_object3, 0); +} + +/*-------------------------------------------------------------------------- + * Scene 9450 + * + *--------------------------------------------------------------------------*/ +void Scene9450::Object2::signal() { + Scene9450 *scene = (Scene9450 *)_globals->_sceneManager._scene; + + this->setAction(&scene->_sequenceManager3, this, 9458, &scene->_object1, 0); +} + +void Scene9450::Object3::dispatch() { + SceneObject::dispatch(); + _percent = (_percent * 20) / 30; +} + +void Scene9450::Hotspot1::doAction(int action) { + Scene9450 *scene = (Scene9450 *)_globals->_sceneManager._scene; + + if (action == CURSOR_USE) { + if (scene->_object2._action) + scene->_object2._action->remove(); + scene->_sceneMode = 9459; + _globals->_player.disableControl(); + setAction(&scene->_sequenceManager1, scene, 9459, &scene->_object2, &scene->_object1, &scene->_object3, &_globals->_player, 0); + } else { + NamedHotspot::doAction(action); + } +} + +void Scene9450::Hotspot3::doAction(int action) { + Scene9450 *scene = (Scene9450 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_CLOAK: + case OBJECT_JACKET: + case OBJECT_TUNIC2: + scene->_sceneMode = 9460; + _globals->_player.disableControl(); + setAction(&scene->_sequenceManager1, scene, 9460, &_globals->_player, &scene->_object2, &scene->_object1, 0); + break; + case OBJECT_TUNIC: + SceneItem::display(9450, 49, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_WALK: + // nothing + break; + case CURSOR_LOOK: + SceneItem::display(9450, 41, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_USE: + case CURSOR_TALK: + if (_globals->_inventory._tunic._sceneNumber == 9450) { + if (scene->_object2._action) + scene->_object2._action->remove(); + scene->_sceneMode = 9459; + _globals->_player.disableControl(); + setAction(&scene->_sequenceManager1, scene, 9459, &scene->_object2, &scene->_object1, &scene->_object3, &_globals->_player, 0); + } else if ((_globals->_inventory._cloak._sceneNumber != 1) && (_globals->_inventory._jacket._sceneNumber != 1) && (_globals->_inventory._tunic2._sceneNumber != 1)) { + SceneItem::display(9450, 38, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } else { + scene->_sceneMode = 9460; + _globals->_player.disableControl(); + setAction(&scene->_sequenceManager1, scene, 9460, &_globals->_player, &scene->_object2, &scene->_object1, 0); + } + break; + default: + SceneItem::display(9450, 45, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + } +} + +void Scene9450::signal() { + switch (_sceneMode++) { + case 1002: + case 1004: + // Drink + setAction(&_sequenceManager1, this, 9456, &_object2, &_object1, &_object3, 0); + break; + case 1005: + // Bring me more wine + setAction(&_sequenceManager1, this, 9457, &_object2, &_object1, &_object3, 0); + break; + case 9451: + if (_globals->getFlag(87)) { + _globals->_player.enableControl(); + } else { + _sceneMode = 1001; + if (_object2._action) + _object2._action->remove(); + } + // No break on purpose + case 1001: + case 1003: + // Eat + setAction(&_sequenceManager1, this, 9455, &_object2, &_object1, &_object3, 0); + break; + case 9453: + _globals->_sceneManager.changeScene(9360); + break; + case 9459: + _object2.signal(); + _globals->_events.setCursor(CURSOR_WALK); + _hotspot1.remove(); + break; + case 1006: + _globals->setFlag(87); + // No break on purpose + default: + _globals->_player.enableControl(); + break; + } +} + +void Scene9450::dispatch() { + if (_action) { + _action->dispatch(); + } else { + if ((_globals->_player._position.y < 98) && (_globals->_player._position.x > 241) && (_globals->_player._position.x < 282)) { + _globals->_player.disableControl(); + _sceneMode = 9452; + setAction(&_sequenceManager1, this, 9452, &_globals->_player, 0); + } else if ((_globals->_player._position.y < 99) && (_globals->_player._position.x > 68) && (_globals->_player._position.x < 103)) { + _globals->_player.disableControl(); + _sceneMode = 9453; + setAction(&_sequenceManager1, this, 9453, &_globals->_player, 0); + } + } +} + +void Scene9450::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(84, 75, 167, 150); + _globals->_events.setCursor(CURSOR_WALK); + _globals->_player.postInit(); + + _object2.postInit(); + _object1.postInit(); + _object1.hide(); + + _globals->_player.disableControl(); + _sceneMode = 9451; + setAction(&_sequenceManager1, this, 9451, &_globals->_player, 0); + + if (_globals->getFlag(87)) { + if (_globals->_inventory._tunic._sceneNumber == 1) { + _object2.signal(); + } else { + _object2.setPosition(Common::Point(184, 144), 0); + _object2.setVisage(9451); + _object2.setPriority2(250); + _object2._strip = 5; + _object2._frame = 10; + } + } else { + _object3.postInit(); + _object3.hide(); + _object3.setAction(&_sequenceManager2, 0, 9455, &_object2, &_object1, 0); + } + + if (_globals->_inventory._tunic._sceneNumber != 1) + _hotspot1.setup(123, 139, 138, 170, 9450, 37, -1); + + _hotspot2.setup(153, 102, 176, 141, 9450, 39, 40); + _hotspot3.setup(97, 198, 130, 229, 9450, 41, 42); + _hotspot15.setup(131, 190, 145, 212, 9450, 43, 44); + _hotspot4.setup(33, 144, 105, 192, 9450, 0, 1); + _hotspot5.setup(20, 236, 106, 287, 9450, 2, 3); + _hotspot6.setup(137, 119, 195, 320, 9450, 4, 5); + _hotspot7.setup(20, 59, 99, 111, 9450, 6, -1); + _hotspot8.setup(110, 0, 199, 117, 9450, 7, 8); + _hotspot9.setup(101, 104, 130, 174, 9450, 9, 10); + _hotspot10.setup(110, 246, 149, 319, 9450, 11, 12); + _hotspot11.setup(16, 34, 74, 62, 6450, 13, 14); + _hotspot12.setup(19, 108, 72, 134, 9450, 15, 16); + _hotspot13.setup(18, 215, 71, 237, 9450, 17, 18); + _hotspot14.setup(15, 288, 76, 314, 9450, 19, 20); + _hotspot16.setup(0, 0, 200, 320, 9450, 46, -1); +} + +/*-------------------------------------------------------------------------- + * Scene 9500 + * + *--------------------------------------------------------------------------*/ +void Scene9500::Hotspot1::doAction(int action) { + Scene9500 *scene = (Scene9500 *)_globals->_sceneManager._scene; + + if (action == OBJECT_SWORD) { + scene->_sceneMode = 9510; + _globals->setFlag(92); + _globals->_inventory._sword._sceneNumber = 9500; + _globals->_player.disableControl(); + _globals->_sceneItems.remove(this); + scene->_hotspot2.setup(87, 294, 104, 314, 9400, 17, -1); + scene->setAction(&scene->_sequenceManager, scene, 9510, &_globals->_player, &scene->_object2, 0); + } else { + NamedHotspot::doAction(action); + } +} + +void Scene9500::Hotspot2::doAction(int action) { + Scene9500 *scene = (Scene9500 *)_globals->_sceneManager._scene; + + if (action == CURSOR_USE) { + scene->_sceneMode = 9511; + _globals->_player.disableControl(); + _globals->_sceneItems.remove(this); + scene->setAction(&scene->_sequenceManager, scene, 9511, &_globals->_player, &scene->_object2, 0); + } else { + NamedHotspot::doAction(action); + } +} + +void Scene9500::Hotspot3::doAction(int action) { + Scene9500 *scene = (Scene9500 *)_globals->_sceneManager._scene; + + if ((action == CURSOR_USE) && (_globals->_inventory._candle._sceneNumber != 1)){ + scene->_sceneMode = 9505; + _globals->_player.disableControl(); + _globals->_sceneItems.remove(this); + scene->setAction(&scene->_sequenceManager, scene, 9505, &_globals->_player, &scene->_candle, 0); + } else { + NamedHotspot::doAction(action); + } +} + +void Scene9500::Hotspot4::doAction(int action) { + Scene9500 *scene = (Scene9500 *)_globals->_sceneManager._scene; + + if (action == OBJECT_CANDLE) { + _globals->_player.disableControl(); + if (_globals->_inventory._straw._sceneNumber == 9500) { + scene->_sceneMode = 9506; + _globals->_sceneItems.remove(&scene->_hotspot5); + _globals->_sceneItems.remove(this); + scene->setAction(&scene->_sequenceManager, scene, 9506, &_globals->_player, &scene->_object3, 0); + _globals->_inventory._candle._sceneNumber = 9850; + } else { + scene->_sceneMode = 9507; + scene->setAction(&scene->_sequenceManager, scene, 9507, &_globals->_player, &scene->_object3, 0); + } + } else if (action == OBJECT_STRAW) { + scene->_sceneMode = 9512; + _globals->_player.disableControl(); + _globals->_inventory._straw._sceneNumber = 9500; + scene->setAction(&scene->_sequenceManager, scene, 9512, &_globals->_player, &scene->_object3, 0); + } else { + NamedHotspot::doAction(action); + } +} + +void Scene9500::signal() { + switch (_sceneMode) { + case 9503: + _globals->_sceneManager.changeScene(9200); + _globals->_soundHandler.startSound(295, 0, 127); + break; + case 9504: + _globals->_sceneManager.changeScene(9850); + break; + case 9505: + _candle.setStrip(2); + _globals->_player.enableControl(); + break; + case 9506: + _globals->setFlag(85); + _globals->_player.enableControl(); + break; + case 9511: + _globals->_player.enableControl(); + if (!_globals->getFlag(51)) { + _globals->setFlag(51); + _globals->_player.disableControl(); + _sceneMode = 9514; + setAction(&_sequenceManager, this, 9514, &_globals->_player, 0, 0, 0, 0); + } + break; + case 0: + case 9514: + default: + _globals->_player.enableControl(); + break; + } +} + +void Scene9500::dispatch() { + if (_action) { + _action->dispatch(); + } else { + if (_globals->_player._position.y >= 199) { + _globals->_player.disableControl(); + _sceneMode = 9503; + setAction(&_sequenceManager, this, 9503, &_globals->_player, 0, 0, 0, 0); + } else if (_globals->_player._position.y < 127) { + _globals->_player.disableControl(); + _sceneMode = 9504; + setAction(&_sequenceManager, this, 9504, &_globals->_player, 0, 0, 0, 0); + } + } + +} + +void Scene9500::process(Event &event) { + Scene::process(event); +} + +void Scene9500::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(110, 75, 200, 150); + + _globals->_player.postInit(); + _globals->_soundHandler.startSound(305, 0, 127); + + _candle.postInit(0); + _candle.setVisage(9500); + _candle.setStrip(1); + _candle.animate(ANIM_MODE_2); + _candle.setPosition(Common::Point(30, 105), 0); + if (_globals->_inventory._candle._sceneNumber != 9500) + _candle.setStrip(2); + + _object3.postInit(0); + _object3.hide(); + _object3.setPriority2(150); + _object3.setPosition(Common::Point(166, 133)); + if (_globals->_inventory._straw._sceneNumber == 9500) { + _object3.show(); + _object3.setVisage(5); + _object3._strip = 2; + _object3._frame = 9; + _object3.setPosition(Common::Point(168, 128)); + if (_globals->getFlag(85)) { + _object3.setVisage(9500); + _object3.setStrip(4); + _object3.animate(ANIM_MODE_8, 0, 0); + _object3.setPosition(Common::Point(166, 133)); + } + } + + _object2.postInit(0); + _object2.hide(); + if (_globals->getFlag(92)) { + _object2.show(); + _object2.setVisage(9501); + _object2.setStrip(1); + _object2.setFrame(_object2.getFrameCount()); + _object2.setPosition(Common::Point(303, 130)); + _object2.setPriority2(132); + if (_globals->_inventory._helmet._sceneNumber == 1) { + _hotspot2.setup(87, 294, 104, 314, 9400, 17, -1); + } else { + _object2.setStrip(2); + _object2.setFrame(1); + } + } else { + _hotspot1.setup(105, 295, 134, 313, 9500, 9, 10); + } + + _hotspot17.setup(101, 293, 135, 315, 9500, 9, 10); + _hotspot3.setup(84, 12, 107, 47, 9500, 15, 15); + _hotspot6.setup(93, 11, 167, 46, 9500, 0, 1); + _hotspot7.setup(100, 70, 125, 139, 9500, 2, 3); + + if (!_globals->getFlag(85)) { + _hotspot5.setup(111, 68, 155, 244, 9500, 17, -1); + _hotspot4.setup(57, 71, 120, 126, 9500, 16, -1); + } + + _hotspot8.setup(60, 24, 90, 53, 9500, 4, 5); + _hotspot9.setup(72, 143, 93, 163, 9500, 4, 5); + _hotspot10.setup(70, 205, 92, 228, 9500, 4, 5); + _hotspot11.setup(66, 291, 90, 317, 9500, 4, 5); + _hotspot12.setup(22, 58, 101, 145, 9500, 6, 7); + _hotspot13.setup(121, 57, 163, 249, 9500, 6, 7); + _hotspot14.setup(115, 133, 135, 252, 9500, 6, 7); + _hotspot15.setup(55, 240, 125, 254, 9500, 6, 7); + _hotspot16.setup(53, 251, 132, 288, 9500, 8, -1); + _hotspot19.setup(101, 207, 120, 225, 9500, 9, 10); + _hotspot18.setup(98, 144, 117, 162, 9500, 9, 10); + _hotspot20.setup(102, 27, 132, 50, 9500, 9, 10); + + _globals->_events.setCursor(CURSOR_WALK); + _globals->_player.disableControl(); + + if ((_globals->_sceneManager._previousScene == 9200) || (_globals->_sceneManager._previousScene != 9850)) { + _sceneMode = 0; + if (_globals->_inventory._helmet._sceneNumber != 1) { + setAction(&_sequenceManager, this, 9501, &_globals->_player, &_candle, 0); + } else { + _globals->_inventory._helmet._sceneNumber = 9500; + _hotspot2.setup(87, 294, 104, 314, 9400, 17, -1); + setAction(&_sequenceManager, this, 9513, &_globals->_player, &_object2, 0); + } + } else { + _sceneMode = 0; + setAction(&_sequenceManager, this, 9502, &_globals->_player, &_candle, 0); + } +} + +/*-------------------------------------------------------------------------- + * Scene 9700 + * + *--------------------------------------------------------------------------*/ +void Scene9700::signal() { + switch (_sceneMode ++) { + case 9703: + _globals->setFlag(88); + // No break on purpose + case 9701: + case 9702: + _gfxButton1.setText(EXIT_MSG); + _gfxButton1._bounds.centre(50, 190); + _gfxButton1.draw(); + _gfxButton1._bounds.expandPanes(); + _globals->_player.enableControl(); + _globals->_player._canWalk = 0; + _globals->_events.setCursor(CURSOR_USE); + break; + case 9704: + _globals->_soundHandler.startSound(323, 0, 127); + _globals->_sceneManager.changeScene(9750); + break; + } +} + +void Scene9700::process(Event &event) { + if ((event.eventType == EVENT_BUTTON_DOWN) && (event.kbd.keycode == 0)) { + if (_gfxButton1.process(event)) { + _globals->_sceneManager.changeScene(9200); + } else if (_globals->_events._currentCursor == OBJECT_SCANNER) { + event.handled = true; + if (_globals->_inventory._helmet._sceneNumber == 1) { + _globals->_player.disableControl(); + _sceneMode = 9704; + setAction(&_sequenceManager, this, 9704, &_globals->_player, &_object1, 0); + } else { + _globals->_player.disableControl(); + _sceneMode = 9703; + setAction(&_sequenceManager, this, 9703, &_globals->_player, &_object1, 0); + } + } + } +} + +void Scene9700::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + _sceneHotspot1.setup(84, 218, 151, 278, 9700, 14, -1); + _sceneHotspot2.setup(89, 11, 151, 121, 9700, 14, -1); + _sceneHotspot3.setup(69, 119, 138, 218, 9700, 15, 16); + _sceneHotspot4.setup(34, 13, 88, 116, 9700, 17, -1); + _sceneHotspot5.setup(52, 119, 68, 204, 9700, 17, -1); + _sceneHotspot6.setup(0, 22, 56, 275, 9700, 18, -1); + + _object1.postInit(); + _object1.hide(); + _globals->_player.postInit(); + if (_globals->getFlag(97)) { + _globals->_player.disableControl(); + _sceneMode = 9701; + setAction(&_sequenceManager, this, 9701, &_globals->_player, &_object1, 0); + _globals->setFlag(97); + } else { + _globals->_player.disableControl(); + _sceneMode = 9702; + setAction(&_sequenceManager, this, 9702, &_globals->_player, &_object1, 0); + } +} + +/*-------------------------------------------------------------------------- + * Scene 9750 + * + *--------------------------------------------------------------------------*/ +void Scene9750::signal() { + switch (_sceneMode ++) { + case 9751: + _globals->_soundHandler.proc1(this); + break; + case 9752: + _globals->_sceneManager.changeScene(2100); + default: + break; + } +} + +void Scene9750::dispatch() { + Scene::dispatch(); +} + +void Scene9750::postInit(SceneObjectList *OwnerList) { + loadScene(9750); + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + _globals->_player.postInit(); + _object1.postInit(); + _object1.hide(); + _object2.postInit(); + _object2.hide(); + _globals->_player.disableControl(); + _sceneMode = 9751; + setAction(&_sequenceManager, this, 9751, &_globals->_player, &_object1, &_object2, 0); +} + + +/*-------------------------------------------------------------------------- + * Scene 9850 + * + *--------------------------------------------------------------------------*/ +void Scene9850::Object6::doAction(int action) { + if ((_flags & OBJFLAG_HIDE) == 0) { + if (action == CURSOR_LOOK) { + SceneItem::display(9850, 27, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } else if (action == CURSOR_USE) { + _globals->_inventory._scimitar._sceneNumber = 1; + hide(); + } else { + SceneHotspot::doAction(action); + } + } +} +void Scene9850::Object7::doAction(int action) { + if ((_flags & OBJFLAG_HIDE) == 0) { + if (action == CURSOR_LOOK) { + SceneItem::display(9850, 28, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } else if (action == CURSOR_USE) { + _globals->_inventory._sword._sceneNumber = 1; + hide(); + } else { + SceneHotspot::doAction(action); + } + } +} + +// Hair covered tunic +void Scene9850::Hotspot12::doAction(int action) { + Scene9850 *scene = (Scene9850 *)_globals->_sceneManager._scene; + + if (action == CURSOR_USE) { + if (_globals->_inventory._tunic2._sceneNumber != 1) { + _globals->_inventory._tunic2._sceneNumber = 1; + _globals->_player.disableControl(); + scene->_sceneMode = 9858; + setAction(&scene->_sequenceManager, scene, 9858, &_globals->_player, &scene->_objTunic2, 0); + } else { + _globals->_inventory._tunic2._sceneNumber = 9850; + _globals->_player.disableControl(); + scene->_sceneMode = 9861; + setAction(&scene->_sequenceManager, scene, 9861, &_globals->_player, &scene->_objTunic2, 0); + } + } else if ((action != CURSOR_LOOK) || (_globals->_inventory._tunic2._sceneNumber != 1)) { + NamedHotspot::doAction(action); + } else { + SceneItem::display(9850, 30, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } +} + +void Scene9850::Hotspot14::doAction(int action) { + Scene9850 *scene = (Scene9850 *)_globals->_sceneManager._scene; + + if (action == CURSOR_USE) { + if (_globals->_inventory._jacket._sceneNumber != 1) { + _globals->_inventory._jacket._sceneNumber = 1; + _globals->_player.disableControl(); + scene->_sceneMode = 9857; + setAction(&scene->_sequenceManager, scene, 9857, &_globals->_player, &scene->_objJacket, 0); + } else { + _globals->_inventory._jacket._sceneNumber = 9850; + _globals->_player.disableControl(); + scene->_sceneMode = 9860; + setAction(&scene->_sequenceManager, scene, 9860, &_globals->_player, &scene->_objJacket, 0); + } + } else if ((action != CURSOR_LOOK) || (_globals->_inventory._jacket._sceneNumber != 1)) { + NamedHotspot::doAction(action); + } else { + SceneItem::display(9850, 30, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } +} + +void Scene9850::Hotspot16::doAction(int action) { + Scene9850 *scene = (Scene9850 *)_globals->_sceneManager._scene; + + if (action == CURSOR_USE) { + if (_globals->_inventory._cloak._sceneNumber != 1) { + _globals->_inventory._cloak._sceneNumber = 1; + _globals->_player.disableControl(); + scene->_sceneMode = 9862; + setAction(&scene->_sequenceManager, scene, 9862, &_globals->_player, &scene->_objCloak, 0); + } else { + _globals->_inventory._cloak._sceneNumber = 9850; + _globals->_player.disableControl(); + scene->_sceneMode = 9859; + setAction(&scene->_sequenceManager, scene, 9859, &_globals->_player, &scene->_objCloak, 0); + } + } else if ((action != CURSOR_LOOK) || (_globals->_inventory._cloak._sceneNumber != 1)) { + NamedHotspot::doAction(action); + } else { + SceneItem::display(9850, 30, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } +} + +void Scene9850::Hotspot17::doAction(int action) { + Scene9850 *scene = (Scene9850 *)_globals->_sceneManager._scene; + + if (action == OBJECT_SCANNER) { + SceneItem::display(9850, 32, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } else { + if (action == CURSOR_USE) + scene->_soundHandler.startSound(306, 0, 127); + NamedHotspot::doAction(action); + } +} + +void Scene9850::Hotspot18::doAction(int action) { + Scene9850 *scene = (Scene9850 *)_globals->_sceneManager._scene; + + if (action == OBJECT_SCANNER) { + SceneItem::display(9850, 32, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } else { + if (action == CURSOR_USE) + scene->_soundHandler.startSound(306, 0, 127); + NamedHotspot::doAction(action); + } +} + +void Scene9850::Hotspot19::doAction(int action) { + Scene9850 *scene = (Scene9850 *)_globals->_sceneManager._scene; + + if (action == OBJECT_SCANNER) { + SceneItem::display(9850, 31, SET_Y, 20, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } else { + if (action == CURSOR_USE) + scene->_soundHandler.startSound(313, 0, 127); + NamedHotspot::doAction(action); + } +} + +// Arrow on Statue +void Scene9850::Hotspot20::doAction(int action) { + Scene9850 *scene = (Scene9850 *)_globals->_sceneManager._scene; + + if (action == CURSOR_USE) { + _globals->_player.disableControl(); + if (scene->_objSword._state == 0) { + if (_globals->_inventory._scimitar._sceneNumber == 9850) + scene->_objScimitar.show(); + if (_globals->_inventory._sword._sceneNumber == 9850) + scene->_objSword.show(); + scene->_sceneMode = 11; + setAction(&scene->_sequenceManager, scene, 9853, &_globals->_player, &scene->_objDoor, &scene->_objLever, 0); + } else { + scene->_sceneMode = 10; + setAction(&scene->_sequenceManager, scene, 9854, &_globals->_player, &scene->_objDoor, &scene->_objLever, 0); + } + scene->_objSword._state ^= 1; + } else { + NamedHotspot::doAction(action); + } +} + +void Scene9850::signal() { + switch (_sceneMode ++) { + case 10: + // Hidden closet closed + if (_globals->_inventory._scimitar._sceneNumber == 9850) + _objScimitar.hide(); + if (_globals->_inventory._sword._sceneNumber == 9850) + _objSword.hide(); + _globals->_sceneItems.remove(&_objScimitar); + _globals->_sceneItems.remove(&_objSword); + _globals->_sceneItems.addItems(&_hotspot19, NULL); + _globals->_player.enableControl(); + break; + case 11: + // Hidden closet opened + if (_globals->_inventory._scimitar._sceneNumber == 9850) + _globals->_sceneItems.addItems(&_objScimitar, NULL); + if (_globals->_inventory._sword._sceneNumber == 9850) + _globals->_sceneItems.addItems(&_objSword, NULL); + _globals->_sceneItems.remove(&_hotspot19); + _globals->_player.enableControl(); + break; + case 9500: + _globals->_sceneManager.changeScene(9500); + break; + case 0: + default: + _globals->_player.enableControl(); + break; + } +} + +void Scene9850::process(Event &event) { + Scene::process(event); + if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_4)) { + event.handled = true; + _globals->_player.disableControl(); + if (_objSword._state == 0) { + _sceneMode = 0; + setAction(&_sequenceManager, this, 9853, &_objLever, &_objDoor, &_objScimitar, &_objSword, 0); + } else { + _sceneMode = 10; + setAction(&_sequenceManager, this, 9854, &_objLever, &_objDoor, &_objScimitar, &_objSword, 0); + } + _objSword._state ^= 1; + } +} + +void Scene9850::dispatch() { + if (_action) { + _action->dispatch(); + } else if (_globals->_player._position.y >= 198) { + _globals->_player.disableControl(); + _sceneMode = 9500; + setAction(&_sequenceManager, this, 9852, &_globals->_player, 0); + } +} + +void Scene9850::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + _objSword._state = 0; + + _objDoor.postInit(); + _objDoor.setVisage(9850); + _objDoor.setStrip(1); + _objDoor.setFrame(1); + _objDoor.setPosition(Common::Point(28, 118), 0); + _objDoor.setPriority2(90); + + _objLever.postInit(); + _objLever.setVisage(9850); + _objLever.setStrip(4); + _objLever.setFrame(1); + _objLever.setPosition(Common::Point(256, 35), 0); + + _objCloak.postInit(); + _objCloak.setVisage(9850); + _objCloak.setStrip(5); + _objCloak.setFrame(1); + _objCloak.setPriority2(90); + _objCloak.setPosition(Common::Point(157, 81), 0); + if (_globals->_inventory._cloak._sceneNumber != 9850) + _objCloak.hide(); + + _objJacket.postInit(); + _objJacket.setVisage(9850); + _objJacket.setStrip(5); + _objJacket.setFrame(2); + _objJacket.setPriority2(90); + _objJacket.setPosition(Common::Point(201, 84)); + if (_globals->_inventory._jacket._sceneNumber != 9850) + _objJacket.hide(); + + _objTunic2.postInit(); + _objTunic2.setVisage(9850); + _objTunic2.setStrip(5); + _objTunic2.setFrame(3); + _objTunic2.setPriority2(90); + _objTunic2.setPosition(Common::Point(295, 90)); + if (_globals->_inventory._tunic2._sceneNumber != 9850) + _objTunic2.hide(); + + if (_globals->_inventory._scimitar._sceneNumber == 9850) { + _objScimitar.postInit(); + _objScimitar.setVisage(9850); + _objScimitar.setStrip(2); + _objScimitar.setFrame(1); + _objScimitar.setPosition(Common::Point(55, 83), 0); + _objScimitar.setPriority2(80); + _objScimitar.hide(); + } + + if (_globals->_inventory._sword._sceneNumber == 9850) { + _objSword.postInit(); + _objSword.setVisage(9850); + _objSword.setStrip(3); + _objSword.setFrame(1); + _objSword.setPosition(Common::Point(56, 101), 0); + _objSword.setPriority2(80); + _objSword.hide(); + } + + _spotLever.setup(30, 251, 45, 270, 9850, 26, -1); + _hotspot1.setup(123, 0, 200, 320, 9850, 0, 1); + _hotspot2.setup(107, 87, 133, 308, 9850, 0, 1); + _hotspot3.setup(2, 28, 53, 80, 9850, 2, 3); + _hotspot4.setup(13, 0, 55, 27, 9850, 2, 3); + _hotspot5.setup(8, 74, 27, 91, 9850, 4, 5); + _hotspot17.setup(61, 0, 125, 28, 9850, 6, 7); + _hotspot18.setup(51, 95, 105, 145, 9850, 6, 7); + _hotspot19.setup(56, 28, 115, 97, 9850, 6, 8); + _hotspot6.setup(0, 223, 115, 257, 9850, 9, 10); + _hotspot7.setup(15, 254, 33, 268, 9850, 9, -1); + _hotspot8.setup(17, 218, 37, 233, 9850, 9, 10); + _hotspot9.setup(8, 113, 26, 221, 9850, 11, 12); + _hotspot10.setup(14, 94, 53, 112, 9850, 13, 14); + _hotspot11.setup(5, 269, 29, 303, 9850, 15, 16); + _hotspot12.setup(43, 278, 91, 317, 9850, 17, 18); + _hotspot13.setup(47, 263, 112, 282, 9850, 19, 20); + _hotspot14.setup(43, 188, 86, 224, 9850, 21, 22); + _hotspot15.setup(43, 162, 92, 191, 9850, 23, 24); + _hotspot16.setup(40, 146, 90, 169, 9850, 25, -1); + + _globals->_player.postInit(); + _globals->_player.disableControl(); + _sceneMode = 0; + setAction(&_sequenceManager, this, 9851, &_globals->_player, 0); +} + +/*-------------------------------------------------------------------------- + * Scene 9900 + * + *--------------------------------------------------------------------------*/ +void Scene9900::strAction1::signal() { + static uint32 mask1 = 0xFFFFFF00; + static uint32 mask2 = 0x00000000; + + Scene9900 *scene = (Scene9900 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->_soundHandler.startSound(351, 0, 127); + _object9.postInit(); + _object9.setVisage(18); + _object9._frame = 1; + _object9._strip = 6; + _object9.setPosition(Common::Point(171, 59)); + _object9.animate(ANIM_MODE_5, 0); + _globals->_scenePalette.addRotation(67, 111, 1, 1, this); + scene->_object2.hide(); + break; + case 1: + _palette1.getPalette(); + _globals->_scenePalette.addUnkPal(&mask1, 1, true /*10*/, this); + break; + case 2: + _object9.remove(); + _globals->_scenePalette.addUnkPal(&mask2, 1, true /*5*/, this); + break; + case 3: + _globals->_soundHandler.startSound(377, 0, 127); + setDelay(120); + break; + case 4: + _globals->_scenePalette.addUnkPal(_palette1._palette, 256, 1, this); + break; + case 5: + remove(); + break; + default: + break; + } +} + +void Scene9900::strAction2::signal() { + switch (_actionIndex++) { + case 0: + var1 = 0; + _txtArray1Index = 0; + _txtArray1[0]._position.y = 200; + _txtArray1[0]._position.y = 300; + _txtArray2[0]._position.y = 400; + _txtArray2[0]._position.y = 500; + var3 = 0; + // No break on purpose + case 1: { + Common::String msg = _vm->_dataManager->getMessage(8030, var1++); + if (!msg.compareTo("LASTCREDIT")) { + if (var3 == 0) { + // Not used? + // int x = _txtArray1[_txtArray1Index].getFrame().getBounds().height(); + _txtArray1[_txtArray1Index]._moveDiff.y = 10; + + NpcMover *mover = new NpcMover(); + Common::Point pt(_txtArray1[_txtArray1Index]._moveDiff.x, -100); + _txtArray1[_txtArray1Index].addMover(mover, &pt, 0); + + // Not used? + // int x = _txtArray2[_txtArray1Index].getFrame().getBounds().height(); + _txtArray2[_txtArray1Index]._moveDiff.y = 10; + _txtArray1Index = (_txtArray1Index++) % 2; + } + var3 = 1; + _txtArray1[_txtArray1Index]._textMode = ALIGN_CENTRE; + _txtArray1[_txtArray1Index]._width = 240; + _txtArray1[_txtArray1Index]._fontNumber = 2; + _txtArray1[_txtArray1Index]._colour1 = 7; + _txtArray1[_txtArray1Index].setup(msg); + _txtArray1[_txtArray1Index]._field7A = 20; + _txtArray1[_txtArray1Index]._moveDiff.y = 2; + _txtArray1[_txtArray1Index].setPriority2(255); + int frameWidth = _txtArray1[_txtArray1Index].getFrame().getBounds().width(); + int frameHeight = _txtArray1[_txtArray1Index].getFrame().getBounds().height(); + _txtArray1[_txtArray1Index].setPosition(Common::Point((320 - frameWidth) / 2, 200)); + NpcMover *mover2 = new NpcMover(); + Common::Point pt2(_txtArray1[_txtArray1Index]._position.x, 100); + _txtArray1[_txtArray1Index].addMover(mover2, &pt2, 0); + + _txtArray2[_txtArray1Index]._textMode = ALIGN_CENTRE; + _txtArray2[_txtArray1Index]._width = 240; + _txtArray2[_txtArray1Index]._fontNumber = 2; + _txtArray2[_txtArray1Index]._colour1 = 23; + + msg = _vm->_dataManager->getMessage(8030, var1++); + _txtArray2[_txtArray1Index].setup(msg); + _txtArray2[_txtArray1Index]._field7A = 20; + _txtArray2[_txtArray1Index]._moveDiff.y = 2; + _txtArray2[_txtArray1Index].setPriority2(255); + frameWidth = _txtArray2[_txtArray1Index].getFrame().getBounds().width(); + _txtArray2[_txtArray1Index].setPosition(Common::Point((320 - frameWidth) / 2, 200 + frameHeight)); + } else { + _globals->_player.enableControl(); + _actionIndex = 3; + signal(); + } + break; + } + case 2: + setDelay(60); + _actionIndex = 1; + break; + case 3: + setDelay(7200); + break; + case 4: + _txtArray1[0].remove(); + _txtArray1[1].remove(); + _txtArray2[0].remove(); + _txtArray2[1].remove(); + remove(); + break; + default: + break; + } +} +void Scene9900::strAction2::dispatch() { +// if (this->_txtArray1[0]._textSurface != 0) { + int frameHeight = _txtArray1[0].getFrame().getBounds().height(); + _txtArray2[0]._position.y = frameHeight + _txtArray1[0]._position.y; + _txtArray2[0]._flags |= OBJFLAG_PANES; +// } +// if (this->_txtArray1[1]._textSurface != 0) { + frameHeight = _txtArray1[1].getFrame().getBounds().height(); + _txtArray2[1]._position.y = frameHeight + _txtArray1[1]._position.y; + _txtArray2[1]._flags |= OBJFLAG_PANES; +// } + Action::dispatch(); +} + +void Scene9900::strAction3::signal() { + static uint32 mask3 = 0xFF000000; + static uint32 mask4 = 0x00000000; + + switch (_actionIndex++) { + case 0: + _palette2.getPalette(); + _palette3.loadPalette(2003); + _globals->_scenePalette.addUnkPal(_palette3._palette, 256, true /*5*/, this); + break; + case 1: + _globals->_scenePalette.addUnkPal(&mask3, 1, true /*10*/, this); + break; + case 2: + _globals->_scenePalette.addUnkPal(&mask4, 1, true /*1*/, this); + break; + case 3: + _palette2.loadPalette(17); + _globals->_sceneManager._scene->loadScene(17); + _globals->_scenePalette.addUnkPal(_palette2._palette, 256, true /*5*/, this); + break; + case 4: + _globals->_game.endGame(9900, 61); + remove(); + default: + break; + } +} + +void Scene9900::signal() { + if ((_sceneMode != 9913) && (_sceneMode != 9905) && (_sceneMode != 9904) && (_sceneMode != 9912)) { + _object1.hide(); + _object2.hide(); + _object3.hide(); + _object4.hide(); + _object5.hide(); + _object6.hide(); + } + + _object1.animate(ANIM_MODE_NONE, 0); + _object2.animate(ANIM_MODE_NONE, 0); + _object3.animate(ANIM_MODE_NONE, 0); + _object4.animate(ANIM_MODE_NONE, 0); + _object5.animate(ANIM_MODE_NONE, 0); + _object6.animate(ANIM_MODE_NONE, 0); + + _object1.setObjectWrapper(0); + _object2.setObjectWrapper(0); + _object3.setObjectWrapper(0); + _object4.setObjectWrapper(0); + _object5.setObjectWrapper(0); + _object6.setObjectWrapper(0); + + _object1.addMover(0); + _object2.addMover(0); + _object3.addMover(0); + _object4.addMover(0); + _object5.addMover(0); + _object6.addMover(0); + + switch (_sceneMode){ + case 150: + _globals->_soundHandler.startSound(380, 0, 127); + _object8.postInit(0); + _object8.setVisage(2002); + _object8.setStrip(1); + _object8.setFrame(1); + _object8.setPriority2(200); + _object8.setPosition(Common::Point(64, 199)); + _globals->_player.disableControl(); + _sceneMode = 9908; + setAction(&_sequenceManager, this, 9908, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6); + break; + case 162: + warning("TBC: shutdown();"); + _globals->_game.quitGame(); + break; + case 9901: + _globals->_player.disableControl(); + _sceneMode = 9906; + setAction(&_sequenceManager, this, 9906, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6); + _globals->_player._uiEnabled = true; + _globals->_events.setCursor(CURSOR_USE); + break; + case 9902: + _globals->_player.disableControl(); + _sceneMode = 9901; + setAction(&_sequenceManager, this, 9901, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6); + break; + case 9903: + _globals->_player.disableControl(); + _sceneMode = 9902; + setAction(&_sequenceManager, this, 9902, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6); + break; + case 9904: + _globals->_soundHandler.startSound(390, 0, 127); + _sceneMode = 9912; + setAction(&_strAction2, this); + break; + case 9905: + _sceneMode = 150; + setAction(&_strAction1, this); + break; + case 9906: + if (_object8._state == 0) { + _globals->_player.disableControl(); + _sceneMode = 9913; + setAction(&_sequenceManager, this, 9913, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6); + } else { + _globals->_player.disableControl(); + _sceneMode = 9905; + setAction(&_sequenceManager, this, 9905, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6); + } + break; + case 9907: + _globals->_player.disableControl(); + _sceneMode = 9903; + setAction(&_sequenceManager, this, 9903, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6); + break; + case 9908: + _object8.remove(); + _globals->_player.disableControl(); + _sceneMode = 9904; + setAction(&_sequenceManager, this, 9904, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6); + break; + case 9909: + _globals->_soundHandler.startSound(375, 0, 127); + _globals->_player.disableControl(); + _sceneMode = 9907; + setAction(&_sequenceManager, this, 9907, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6); + break; + case 9910: + _globals->_player.disableControl(); + _sceneMode = 9911; + setAction(&_sequenceManager, this, 9911, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6); + break; + case 9911: + _globals->_soundHandler.startSound(367, 0, 127); + _globals->_player.disableControl(); + _sceneMode = 9909; + setAction(&_sequenceManager, this, 9909, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6); + break; + case 9912: + _globals->_player.disableControl(); + _sceneMode = 9912; + setAction(&_sequenceManager, this, 9912, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6); + _sceneMode = 162; + _globals->_player.enableControl(); + _globals->_player._canWalk = false; + break; + case 9913: + _sceneMode = 200; + setAction(&_strAction3, this); + break; + default: + break; + } +} + +void Scene9900::process(Event &event) { + if (event.handled) + return; + Scene::process(event); + if (_sceneMode != 9906) { + if ((event.eventType == EVENT_BUTTON_DOWN) && (_globals->_events.getCursor() == OBJECT_ITEMS)) { + _object8._state = 1; + _globals->_inventory._items._sceneNumber = 9900; + _globals->_events.setCursor(CURSOR_USE); + } + } +} + +void Scene9900::dispatch() { + if (_action) + _action->dispatch(); +} + +void Scene9900::postInit(SceneObjectList *OwnerList) { + _object1.postInit(0); + _object1.hide(); + _object2.postInit(0); + _object2.hide(); + _object3.postInit(0); + _object3.hide(); + _object4.postInit(0); + _object4.hide(); + _object5.postInit(0); + _object5.hide(); + _object6.postInit(0); + _object6.hide(); + + _object8._state = 0; + + _globals->_inventory._concentrator._sceneNumber = 9900; + _globals->_inventory._items._rlbNum = 3; + _globals->_inventory._items._cursorNum = 6; + _globals->_inventory._items._description = Common::String("One of the items from the stasis ship. The other is on the Lance's bridge."); + + _stripManager.addSpeaker(&_speakerMR); + _globals->_player.disableControl(); + _sceneMode = 9910; + setAction(&_sequenceManager, this, 9910, &_object1, &_object2, &_object3, &_object4, &_object5, &_object6); +} + +/*-------------------------------------------------------------------------- + * Scene 9999 + * + *--------------------------------------------------------------------------*/ + +void Scene9999::Action1::signal() { + switch (_actionIndex++) { + case 0: + setDelay(600); + break; + case 1: + _globals->_sceneManager.changeScene(3500); + break; + default: + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene9999::Action2::signal() { + switch (_actionIndex++) { + case 0: + setDelay(10); + break; + case 1: + SceneItem::display(9999, 0, SET_Y, 10, SET_X, 30, SET_FONT, 2, SET_BG_COLOUR, -1, SET_EXT_BGCOLOUR, 23, SET_WIDTH, 260, SET_KEEP_ONSCREEN, 1, LIST_END); + setDelay(300); + break; + case 2: + _globals->_stripNum = 3600; + _globals->_sceneManager.changeScene(3600); + default: + break; + } +} + +void Scene9999::postInit(SceneObjectList *OwnerList) { + loadScene(9998); + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + _object1.postInit(); + _object1.setVisage(1303); + _object1.setStrip2(3); + _object1.setPosition(Common::Point(160, 152), 0); + + _globals->_player.postInit(); + _globals->_player.setVisage(1303); + _globals->_player.setStrip2(1); + _globals->_player.setPriority2(250); + _globals->_player.animate(ANIM_MODE_2, 0); + _globals->_player.setPosition(Common::Point(194, 98), 0); + _globals->_player._numFrames = 20; + _globals->_player.disableControl(); + + _object2.postInit(); + _object2.setVisage(1303); + _object2.setStrip2(2); + _object2.setPriority2(2); + _object2.setPosition(Common::Point(164, 149), 0); + + _object3.postInit(); + _object3.setVisage(1303); + _object3.setStrip2(2); + _object3.setPriority2(2); + _object3.setFrame(2); + _object3.setPosition(Common::Point(292, 149), 0); + _object3.setAction(&_action3); + + if (_globals->_sceneManager._previousScene == 3500) + setAction(&_action2); + else + setAction(&_action1); + + _globals->_sceneManager._scene->_sceneBounds.centre(_globals->_player._position.x, _globals->_player._position.y); + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160; + + if (_globals->_sceneManager._previousScene == 3500) + _globals->_stripNum = 2222; + else + _globals->_stripNum = 2121; + + _globals->_soundHandler.startSound(118, 0, 127); + +} + +} // End of namespace tSage diff --git a/engines/tsage/ringworld_scenes10.h b/engines/tsage/ringworld_scenes10.h new file mode 100644 index 0000000000..4f70a23ede --- /dev/null +++ b/engines/tsage/ringworld_scenes10.h @@ -0,0 +1,544 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/scene_logic.h $ + * $Id: scene_logic.h 232 2011-02-12 11:56:38Z dreammaster $ + * + */ + +#ifndef TSAGE_RINGWORLD_SCENES10_H +#define TSAGE_RINGWORLD_SCENES10_H + +#include "common/scummsys.h" +#include "tsage/ringworld_logic.h" +#include "tsage/events.h" +#include "tsage/core.h" +#include "tsage/scenes.h" +#include "tsage/globals.h" + +namespace tSage { + +class SceneObject9150: public SceneObject { +public: + int _timer, _signalFlag; + + virtual void synchronise(Serialiser &s) { + SceneObject::synchronise(s); + s.syncAsSint16LE(_timer); + s.syncAsSint16LE(_signalFlag); + } + virtual Common::String getClassName() { return "SceneObject9150"; } +}; + +class Scene2: public Scene { +public : + int _sceneState; + + Scene2(); + virtual void synchronise(Serialiser &s) { + Scene::synchronise(s); + s.syncAsSint16LE(_sceneState); + } +}; + +class Object9350: public SceneObject { +public: + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void draw(); +}; + +class Scene9100: public Scene { + /* Items */ + class SceneHotspot1: public NamedHotspot { + public: + virtual void doAction(int action); + }; +public: + SequenceManager _sequenceManager; + SceneObject _object1; + SceneObject _object2; + SceneObject _object3; + SceneObject _object4; + SceneObject _object5; + SceneObject _object6; + SceneHotspot1 _sceneHotspot1; + NamedHotspot _sceneHotspot2; + NamedHotspot _sceneHotspot3; + NamedHotspot _sceneHotspot4; + NamedHotspot _sceneHotspot5; + NamedHotspot _sceneHotspot6; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene9150: public Scene2 { + class Object3: public SceneObject9150 { + public: + virtual void signal(); + virtual void dispatch(); + }; +public: + SequenceManager _sequenceManager1; + SequenceManager _sequenceManager2; + SceneObject _object1; + SceneObject _object2; + Object3 _object3; + NamedHotspot _sceneHotspot1; + NamedHotspot _sceneHotspot2; + NamedHotspot _sceneHotspot3; + NamedHotspot _sceneHotspot4; + NamedHotspot _sceneHotspot5; + NamedHotspot _sceneHotspot6; + NamedHotspot _sceneHotspot7; + NamedHotspot _sceneHotspot8; + NamedHotspot _sceneHotspot9; + NamedHotspot _sceneHotspot10; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene9200: public Scene2 { + class SceneHotspot1: public NamedHotspot{ + public: + virtual void doAction(int action); + }; +public: + SequenceManager _sequenceManager; + SceneObject _object1; + SceneObject _object2; + SceneObject _object3; + Action _action1; + SpeakerGText _speakerGText; + SpeakerGR _speakerGR; + SpeakerQText _speakerQText; + SoundHandler _soundHandler; + SceneHotspot1 _hotspot1; + NamedHotspot _hotspot2; + NamedHotspot _hotspot3; + NamedHotspot _hotspot4; + NamedHotspot _hotspot5; + NamedHotspot _hotspot6; + NamedHotspot _hotspot7; + NamedHotspot _hotspot8; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); + virtual void process(Event &event); +}; + +class Scene9300: public Scene { +public: + SequenceManager _sequenceManager; + SceneObject _object1; + SceneObject _object2; + NamedHotspot _hotspot1; + NamedHotspot _hotspot2; + NamedHotspot _hotspot3; + NamedHotspot _hotspot4; + NamedHotspot _hotspot5; + NamedHotspot _hotspot6; + NamedHotspot _hotspot7; + NamedHotspot _hotspot8; + NamedHotspot _hotspot9; + NamedHotspot _hotspot10; + NamedHotspot _hotspot11; + NamedHotspot _hotspot12; + NamedHotspot _hotspot13; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene9350: public Scene2 { +public: + SequenceManager _sequenceManager; + Object9350 _object1; + SceneObject _object2; + NamedHotspot _sceneHotspot1; + NamedHotspot _sceneHotspot2; + NamedHotspot _sceneHotspot3; + NamedHotspot _sceneHotspot4; + NamedHotspot _sceneHotspot5; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene9360: public Scene2 { +public: + SequenceManager _sequenceManager; + Action _action1; + Object9350 _object1; + NamedHotspot _hotspot1; + NamedHotspot _hotspot2; + NamedHotspot _hotspot3; + NamedHotspot _hotspot4; + NamedHotspot _hotspot5; + NamedHotspot _hotspot6; + NamedHotspot _hotspot7; + NamedHotspot _hotspot8; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene9400: public Scene2 { + class SceneHotspot7: public NamedHotspot{ + public: + virtual void doAction(int action); + }; + + class SceneHotspot8: public NamedHotspot{ + public: + virtual void doAction(int action); + }; +public: + Scene9400(); + SequenceManager _sequenceManager; + Action _action1; + SceneObject _object1; + SceneObject _object2; + SceneObject _object3; + SpeakerOText _speakerOText; + SpeakerOR _speakerOR; + SpeakerQText _speakerQText; + NamedHotspot _hotspot1; + NamedHotspot _hotspot2; + NamedHotspot _hotspot3; + NamedHotspot _hotspot4; + NamedHotspot _hotspot5; + NamedHotspot _hotspot6; + SoundHandler _soundHandler; + int _field1032; + SceneHotspot7 _hotspot7; + SceneHotspot8 _hotspot8; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene9450: public Scene2 { + class Object2: public SceneObject { + public: + virtual void signal(); + }; + + class Object3: public SceneObject9150 { + public: + virtual void dispatch(); + }; + + class Hotspot1: public NamedHotspot{ + public: + virtual void doAction(int action); + }; + + class Hotspot3: public NamedHotspot{ + public: + virtual void doAction(int action); + }; +public: + SceneObject _object1; + SequenceManager _sequenceManager1; + SequenceManager _sequenceManager2; + Object2 _object2; + SequenceManager _sequenceManager3; + Object3 _object3; + Hotspot1 _hotspot1; + NamedHotspot _hotspot2; + Hotspot3 _hotspot3; + NamedHotspot _hotspot4; + NamedHotspot _hotspot5; + NamedHotspot _hotspot6; + NamedHotspot _hotspot7; + NamedHotspot _hotspot8; + NamedHotspot _hotspot9; + NamedHotspot _hotspot10; + NamedHotspot _hotspot11; + NamedHotspot _hotspot12; + NamedHotspot _hotspot13; + NamedHotspot _hotspot14; + NamedHotspot _hotspot15; + NamedHotspot _hotspot16; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene9500: public Scene2 { + class Hotspot1: public NamedHotspot{ + public: + virtual void doAction(int action); + }; + + class Hotspot2: public NamedHotspot{ + public: + virtual void doAction(int action); + }; + + class Hotspot3: public NamedHotspot{ + public: + virtual void doAction(int action); + }; + + class Hotspot4: public NamedHotspot{ + public: + virtual void doAction(int action); + }; + +public: + SequenceManager _sequenceManager; + SceneObject _candle; + SceneObject _object2; + SceneObject _object3; + Hotspot1 _hotspot1; + Hotspot2 _hotspot2; + Hotspot3 _hotspot3; + Hotspot4 _hotspot4; + Hotspot4 _hotspot5; + NamedHotspot _hotspot6; + NamedHotspot _hotspot7; + NamedHotspot _hotspot8; + NamedHotspot _hotspot9; + NamedHotspot _hotspot10; + NamedHotspot _hotspot11; + NamedHotspot _hotspot12; + NamedHotspot _hotspot13; + NamedHotspot _hotspot14; + NamedHotspot _hotspot15; + NamedHotspot _hotspot16; + NamedHotspot _hotspot17; + NamedHotspot _hotspot18; + NamedHotspot _hotspot19; + NamedHotspot _hotspot20; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); + virtual void process(Event &event); +}; + +class Scene9700: public Scene2 { + SequenceManager _sequenceManager; + SceneObject _object1; + NamedHotspot _sceneHotspot1; + NamedHotspot _sceneHotspot2; + NamedHotspot _sceneHotspot3; + NamedHotspot _sceneHotspot4; + NamedHotspot _sceneHotspot5; + NamedHotspot _sceneHotspot6; + GfxButton _gfxButton1; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void process(Event &event); +}; + +class Scene9750: public Scene { +public: + SequenceManager _sequenceManager; + SceneObject _object1; + SceneObject _object2; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene9850: public Scene { + class Object6: public SceneObject{ + public: + virtual void doAction(int action); + }; + + class Object7: public SceneObjectExt{ + public: + virtual void doAction(int action); + }; + + class Hotspot12: public NamedHotspot{ + public: + virtual void doAction(int action); + }; + + class Hotspot14: public NamedHotspot{ + public: + virtual void doAction(int action); + }; + + class Hotspot16: public NamedHotspot{ + public: + virtual void doAction(int action); + }; + + class Hotspot17: public NamedHotspot{ + public: + virtual void doAction(int action); + }; + + class Hotspot18: public NamedHotspot{ + public: + virtual void doAction(int action); + }; + + class Hotspot19: public NamedHotspot{ + public: + virtual void doAction(int action); + }; + + class Hotspot20: public NamedHotspot{ + public: + virtual void doAction(int action); + }; +public: + SequenceManager _sequenceManager; + SceneObject _objDoor; + SceneObject _objCloak; + SceneObject _objJacket; + SceneObject _objTunic2; + SceneObject _objLever; + Object6 _objScimitar; + Object7 _objSword; + SoundHandler _soundHandler; + NamedHotspot _hotspot1; + NamedHotspot _hotspot2; + NamedHotspot _hotspot3; + NamedHotspot _hotspot4; + NamedHotspot _hotspot5; + NamedHotspot _hotspot6; + NamedHotspot _hotspot7; + NamedHotspot _hotspot8; + NamedHotspot _hotspot9; + NamedHotspot _hotspot10; + NamedHotspot _hotspot11; + Hotspot12 _hotspot12; + NamedHotspot _hotspot13; + Hotspot14 _hotspot14; + NamedHotspot _hotspot15; + Hotspot16 _hotspot16; + Hotspot17 _hotspot17; + Hotspot18 _hotspot18; + Hotspot19 _hotspot19; + Hotspot20 _spotLever; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void process(Event &event); + virtual void dispatch(); +}; + +class Scene9900: public Scene { + class strAction1: public Action { + public: + SceneObject _object9; + ScenePalette _palette1; + + virtual void signal(); + }; + + class strAction2: public Action { + public: + SceneText _txtArray1[2]; + SceneText _txtArray2[2]; + int var1, _txtArray1Index, var3; + + virtual void signal(); + virtual void dispatch(); + }; + + class strAction3: public Action { + public: + SceneObject _object10; + ScenePalette _palette2; + ScenePalette _palette3; + + virtual void signal(); + }; + + class SceneTextArr1 { + public: + SceneText _sceneText[2]; + }; + + class SceneTextArr2 { + public: + SceneText _sceneText[2]; + int _var1, var2, var3; + }; + +public: + SoundHandler _soundHandler; + SequenceManager _sequenceManager; + SceneObject _object1; + SceneObject _object2; + SceneObject _object3; + SceneObject _object4; + SceneObject _object5; + SceneObject _object6; + SceneObject _object7; + SceneObjectExt _object8; + strAction1 _strAction1; + strAction2 _strAction2; + strAction3 _strAction3; + SpeakerMR _speakerMR; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); + virtual void process(Event &event); +}; + +class Scene9999: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + +public: + + Action1 _action1; + Action2 _action2; + Action _action3; + SceneObject _object1; + SceneObject _object2; + SceneObject _object3; + + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/ringworld_scenes2.cpp b/engines/tsage/ringworld_scenes2.cpp new file mode 100644 index 0000000000..65b676885a --- /dev/null +++ b/engines/tsage/ringworld_scenes2.cpp @@ -0,0 +1,929 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/scene_logic.cpp $ + * $Id: scene_logic.cpp 232 2011-02-12 11:56:38Z dreammaster $ + * + */ + +#include "tsage/ringworld_scenes2.h" +#include "tsage/scenes.h" +#include "tsage/tsage.h" +#include "tsage/staticres.h" + +namespace tSage { + +/*-------------------------------------------------------------------------- + * Scene 1000 - Title Screen + * + *--------------------------------------------------------------------------*/ + +void Scene1000::Action1::signal() { + Scene1000 *scene = (Scene1000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(10); + break; + case 1: + scene->_object4.postInit(); + scene->_object4.setVisage(1001); + scene->_object4._frame = 1; + scene->_object4.setStrip2(5); + scene->_object4.changeZoom(100); + scene->_object4.animate(ANIM_MODE_2, NULL); + scene->_object4.setPosition(Common::Point(403, 163)); + setDelay(90); + break; + case 2: { + SceneItem::display(0, 0); + scene->_object4.remove(); + scene->_object1.changeZoom(-1); + NpcMover *mover = new NpcMover(); + Common::Point pt(180, 100); + scene->_object1.addMover(mover, &pt, this); + break; + } + case 3: + _globals->_sceneManager.changeScene(1400); + break; + } + +} + +void Scene1000::Action2::signal() { + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(10); + break; + case 1: + SceneItem::display(1000, 0, SET_Y, 20, SET_FONT, 2, SET_BG_COLOUR, -1, + SET_EXT_BGCOLOUR, 35, SET_WIDTH, 200, SET_KEEP_ONSCREEN, 1, LIST_END); + setDelay(180); + break; + case 2: + SceneItem::display(0, 0); + _globals->_sceneManager.changeScene(2000); + break; + default: + break; + } +} + +void Scene1000::Action3::signal() { + Scene1000 *scene = (Scene1000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_sceneManager._scene->loadBackground(0, 0); + setDelay(60); + break; + case 1: { + NpcMover *mover = new NpcMover(); + Common::Point pt(158, 31); + scene->_object3.addMover(mover, &pt, this); + break; + } + case 2: + case 3: + setDelay(60); + break; + case 4: + _globals->_player.show(); + setDelay(240); + break; + case 5: { + // Intro.txt file presence is used to allow user option to skip the introduction + _globals->_player.enableControl(); + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading("Intro.txt"); + if (!in) { + // File not present, so create it + Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving("Intro.txt"); + out->finalize(); + delete out; + setDelay(1); + } else { + delete in; + + // Prompt user for whether to start play or watch introduction + if (MessageDialog::show2(WATCH_INTRO_MSG, START_PLAY_BTN_STRING, INTRODUCTION_BTN_STRING) == 0) { + _actionIndex = 20; + _globals->_soundHandler.proc1(this); + } else { + setDelay(1); + } + + _globals->_player.disableControl(); + } + break; + } + case 6: { + scene->_object3.remove(); + _globals->_player.setStrip2(2); + NpcMover *mover = new NpcMover(); + Common::Point pt(480, 100); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 7: + _globals->_scenePalette.loadPalette(1002); + _globals->_scenePalette.refresh(); + _globals->_scenePalette.addRotation(80, 95, -1); + scene->_object3.postInit(); + scene->_object3.setVisage(1002); + scene->_object3.setStrip(1); + scene->_object3.setPosition(Common::Point(284, 122)); + scene->_object3.changeZoom(1); + + zoom(true); + setDelay(200); + break; + case 8: + zoom(false); + setDelay(10); + break; + case 9: + scene->_object3.setStrip(2); + scene->_object3.setPosition(Common::Point(285, 155)); + + zoom(true); + setDelay(400); + break; + case 10: + zoom(false); + setDelay(10); + break; + case 11: + scene->_object3.setStrip(3); + scene->_object3.setPosition(Common::Point(279, 172)); + + zoom(true); + setDelay(240); + break; + case 12: + zoom(false); + setDelay(10); + break; + case 13: + scene->_object3.setStrip(4); + scene->_object3.setPosition(Common::Point(270, 128)); + + zoom(true); + setDelay(300); + break; + case 14: + zoom(false); + setDelay(10); + break; + case 15: + scene->_object3.setStrip(1); + scene->_object3.setFrame(2); + scene->_object3.setPosition(Common::Point(283, 137)); + + zoom(true); + setDelay(300); + break; + case 16: + zoom(false); + setDelay(10); + break; + case 17: + scene->_object3.setStrip(5); + scene->_object3.setFrame(1); + scene->_object3.setPosition(Common::Point(292, 192)); + + zoom(true); + setDelay(300); + break; + case 18: + zoom(false); + _globals->_scenePalette.clearListeners(); + _globals->_soundHandler.proc1(this); + break; + case 19: + _globals->_sceneManager.changeScene(10); + break; + case 20: + _globals->_sceneManager.changeScene(30); + break; + default: + break; + } +} + +void Scene1000::Action3::zoom(bool up) { + Scene1000 *scene = (Scene1000 *)_globals->_sceneManager._scene; + + if (up) { + while ((scene->_object3._percent < 100) && !_vm->shouldQuit()) { + scene->_object3.changeZoom(MIN(scene->_object3._percent + 5, 100)); + _globals->_sceneObjects->draw(); + _globals->_events.delay(1); + } + } else { + while ((scene->_object3._percent > 0) && !_vm->shouldQuit()) { + scene->_object3.changeZoom(MAX(scene->_object3._percent - 5, 0)); + _globals->_sceneObjects->draw(); + _globals->_events.delay(1); + } + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene1000::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + loadScene(1000); + + if (_globals->_sceneManager._previousScene == 2000) { + setZoomPercents(150, 10, 180, 100); + _object1.postInit(); + _object1.setVisage(1001); + _object1._strip = 7; + _object1.animate(ANIM_MODE_2, 0); + _object1._moveDiff = Common::Point(1, 1); + _object1.setPosition(Common::Point(120, 180)); + + setAction(&_action2); + + _globals->_sceneManager._scene->_sceneBounds.centre(_object1._position.x, _object1._position.y); + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + + _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160; + _globals->_soundHandler.startSound(114); + } else if (_globals->_sceneManager._previousScene == 2222) { + setZoomPercents(150, 10, 180, 100); + _object1.postInit(); + _object1.setVisage(1001); + _object1._strip = 7; + _object1.animate(ANIM_MODE_2, 0); + _object1._moveDiff = Common::Point(2, 2); + _object1.setPosition(Common::Point(120, 180)); + + _globals->_sceneManager._scene->_sceneBounds.centre(_object1._position.x, _object1._position.y); + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160; + + setAction(&_action1); + } else { + _globals->_soundHandler.startSound(4); + setZoomPercents(0, 10, 30, 100); + _object3.postInit(); + _object3.setVisage(1050); + _object3.changeZoom(-1); + _object3.setPosition(Common::Point(158, 0)); + + _globals->_player.postInit(); + _globals->_player.setVisage(1050); + _globals->_player.setStrip(3); + _globals->_player.setPosition(Common::Point(160, 191)); + _globals->_player._moveDiff.x = 12; + _globals->_player.hide(); + _globals->_player.disableControl(); + + _globals->_sceneManager._scene->_sceneBounds.centre(_object3._position.x, _object3._position.y); + + setAction(&_action3); + } +} + +/*-------------------------------------------------------------------------- + * Scene 1001 - Fleeing planet cutscene + * + *--------------------------------------------------------------------------*/ + +void Scene1001::Action1::signal() { + Scene1001 *scene = (Scene1001 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(10); + break; + case 1: + scene->_object3.animate(ANIM_MODE_5, this); + break; + case 2: { + Common::Point pt(108, 171); + NpcMover *mover = new NpcMover(); + scene->_object3.addMover(mover, &pt, this); + break; + } + case 3: { + Common::Point pt(170, 159); + NpcMover *mover = new NpcMover(); + scene->_object3.addMover(mover, &pt, this); + break; + } + case 4: { + scene->_object2.postInit(); + scene->_object2.setVisage(16); + scene->_object2.setStrip2(4); + scene->_object2.setPosition(Common::Point(61, 177)); + scene->_object2.animate(ANIM_MODE_5, this); + + Common::Point pt(320, 100); + NpcMover *mover = new NpcMover(); + scene->_object3.addMover(mover, &pt, this); + break; + } + case 5: { + Common::Point pt(82, 166); + NpcMover *mover = new NpcMover(); + scene->_object2.addMover(mover, &pt, this); + break; + } + case 6: { + Common::Point pt(64, 149); + NpcMover *mover = new NpcMover(); + scene->_object2.addMover(mover, &pt, this); + break; + } + case 7: { + Common::Point pt(15, 136); + NpcMover *mover = new NpcMover(); + scene->_object2.addMover(mover, &pt, this); + break; + } + case 8: { + Common::Point pt(-5, 120); + NpcMover *mover = new NpcMover(); + scene->_object2.addMover(mover, &pt, this); + break; + } + case 9: { + scene->_object1.postInit(); + scene->_object1.setVisage(16); + scene->_object1.setStrip2(1); + scene->_object1.setFrame(1); + scene->_object1.setPosition(Common::Point(-75, 87)); + scene->_object1.animate(ANIM_MODE_2, NULL); + + Common::Point pt(0, 100); + NpcMover *mover = new NpcMover(); + scene->_object1.addMover(mover, &pt, this); + break; + } + case 10: { + Common::Point pt1(107, 115); + NpcMover *mover1 = new NpcMover(); + scene->_object1.addMover(mover1, &pt1, NULL); + + scene->_object3.setVisage(16); + scene->_object3.setStrip2(5); + scene->_object3.setFrame2(2); + scene->_object3.setPosition(Common::Point(220, 200)); + + Common::Point pt2(187, 181); + NpcMover *mover2 = new NpcMover(); + scene->_object3.addMover(mover2, &pt2, this); + break; + } + case 11: { + scene->_object2.setVisage(16); + scene->_object2.setStrip2(5); + scene->_object2.setFrame2(1); + scene->_object2.setPosition(Common::Point(211, 0)); + + Common::Point pt(189, 30); + NpcMover *mover = new NpcMover(); + scene->_object2.addMover(mover, &pt, this); + break; + } + case 12: + scene->_stripManager.start(100, this); + break; + case 13: { + scene->_object4.postInit(); + scene->_object4.setVisage(16); + scene->_object4.setStrip2(2); + scene->_object4.setFrame(4); + scene->_object4.setPosition(Common::Point(360, 80)); + scene->_object4.animate(ANIM_MODE_2, NULL); + + Common::Point pt(303, 97); + NpcMover *mover = new NpcMover(); + scene->_object4.addMover(mover, &pt, this); + break; + } + case 14: + scene->_stripManager.start(110, this); + break; + case 15: + setDelay(10); + break; + case 16: { + scene->_soundHandler1.startSound(90); + + scene->_object6.postInit(); + scene->_object6.setVisage(16); + scene->_object6.setStrip2(6); + scene->_object6.setFrame2(2); + scene->_object6._moveDiff = Common::Point(20, 20); + scene->_object6.setPriority2(20); + scene->_object6.setPosition(Common::Point(scene->_object2._position.x - 6, scene->_object2._position.y + 7)); + scene->_object6.animate(ANIM_MODE_5, NULL); + + Common::Point pt(scene->_object6._position.x - 70, scene->_object6._position.y + 70); + NpcMover *mover = new NpcMover(); + scene->_object6.addMover(mover, &pt, this); + break; + } + case 17: { + scene->_soundHandler1.startSound(90); + scene->_object6.remove(); + + scene->_object7.postInit(); + scene->_object7.setVisage(16); + scene->_object7.setStrip2(6); + scene->_object7.setFrame2(1); + scene->_object7._moveDiff = Common::Point(20, 20); + scene->_object7.setPosition(Common::Point(scene->_object3._position.x - 28, scene->_object3._position.y - 11)); + scene->_object7.setPriority2(200); + scene->_object7.animate(ANIM_MODE_5, NULL); + + Common::Point pt(scene->_object7._position.x - 70, scene->_object7._position.y - 70); + NpcMover *mover = new NpcMover(); + scene->_object7.addMover(mover, &pt, this); + break; + } + case 18: + scene->_object7.remove(); + + scene->_object5.postInit(); + scene->_object5.setVisage(16); + scene->_object5.setPosition(Common::Point(306, 93)); + scene->_object5._strip = 3; + scene->_object5.setPriority2(200); + scene->_object5.animate(ANIM_MODE_2, NULL); + setDelay(30); + break; + case 19: { + _globals->_soundHandler.startSound(91); + byte adjustData[4] = {0xff, 0xff, 0xff, 0}; + _globals->_scenePalette.fade(adjustData, true, 0); + + scene->_object1._strip = 7; + scene->_object1._frame = 1; + scene->_object1.setPosition(Common::Point(314, 112)); + scene->_object1.addMover(NULL); + setDelay(2); + } + case 20: + _globals->_scenePalette.loadPalette(16); + _globals->_scenePalette.refresh(); + setDelay(6); + break; + case 21: + scene->_object1._numFrames = 15; + scene->_object1.animate(ANIM_MODE_5, this); + break; + case 22: + _globals->_soundHandler.startSound(92); + scene->_stripManager.start(111, this); + break; + case 23: + setDelay(60); + break; + case 24: + _globals->_sceneManager.changeScene(2000); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene1001::postInit(SceneObjectList *OwnerList) { + loadScene(16); + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerCText); + _stripManager.addSpeaker(&_speakerCR); + _stripManager.addSpeaker(&_speakerSL); + _speakerQText._colour1 = 11; + + _object3.postInit(); + _object3.setVisage(16); + _object3.setStrip2(4); + _object3.setPosition(Common::Point(61, 177)); + + _globals->_soundHandler.startSound(85); + setAction(&_action1); +} + + +/*-------------------------------------------------------------------------- + * Scene 1250 - + * + *--------------------------------------------------------------------------*/ + +void Scene1250::Action1::signal() { + Scene1250 *scene = (Scene1250 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(_globals->_randomSource.getRandomNumber(120) + 60); + break; + case 1: + scene->_object1.animate(ANIM_MODE_5, this); + _actionIndex = 0; + break; + } +} + +void Scene1250::Action2::signal() { + Scene1250 *scene = (Scene1250 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + switch (_globals->_randomSource.getRandomNumber(2)) { + case 0: + scene->_object2.setPosition(Common::Point(163, 75)); + break; + case 1: + scene->_object2.setPosition(Common::Point(109, 65)); + break; + case 2: + scene->_object2.setPosition(Common::Point(267, 20)); + break; + } + + setDelay(30); + break; + case 1: + scene->_object2.animate(ANIM_MODE_5, this); + _actionIndex = 0; + break; + } +} + +void Scene1250::Action3::signal() { + Scene1250 *scene = (Scene1250 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(30); + break; + case 1: + scene->_stripManager.start(1251, this); + break; + case 2: + setDelay(6); + break; + case 3: + _globals->_sceneManager.changeScene(1000); + break; + } +} + +void Scene1250::Action4::signal() { + Scene1250 *scene = (Scene1250 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(3); + break; + case 1: + scene->_stripManager.start(1250, this); + break; + case 2: + setDelay(6); + break; + case 3: + _globals->_sceneManager.changeScene(2000); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene1250::postInit(SceneObjectList *OwnerList) { + loadScene(1250); + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + _stripManager.addSpeaker(&_speakerQText); + _speakerQText._textPos = Common::Point(120, 120); + _speakerQText._textWidth = 180; + + _object1.postInit(); + _object1.setVisage(1250); + _object1.setPosition(Common::Point(126, 69)); + _object1.setStrip2(1); + _object1._frame = 1; + _object1.setAction(&_action1); + + _object2.postInit(); + _object2.setVisage(1250); + _object2.setPosition(Common::Point(126, 69)); + _object2.setStrip2(2); + _object2.setPriority2(255); + _object2._frame = 1; + _object2.setAction(&_action2); + + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160; + + if ((_globals->_sceneManager._previousScene != 2000) || (_globals->_stripNum != 1250)) { + setAction(&_action4); + } else { + setAction(&_action3); + _globals->_soundHandler.startSound(114); + } +} + +/*-------------------------------------------------------------------------- + * Scene 1400 - Ringworld Wall + * + *--------------------------------------------------------------------------*/ + +void Scene1400::Action1::signal() { + Scene1400 *scene = (Scene1400 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(5); + break; + case 1: { + SceneItem::display(1400, 0, SET_X, 120, SET_Y, 610, SET_FONT, 2, SET_EXT_BGCOLOUR, 23, SET_KEEP_ONSCREEN, -1, LIST_END); + + Common::Point pt(160, 700); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 2: { + _globals->_player.setStrip2(3); + _globals->_player.changeZoom(100); + + Common::Point pt(160, 100); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + + SceneItem::display(0, 0); + setDelay(360); + break; + } + case 3: + SceneItem::display(1400, 2, SET_X, 60, SET_Y, _globals->_sceneManager._scene->_sceneBounds.bottom - 80, + SET_FONT, 2, SET_FG_COLOUR, 13, SET_POS_MODE, 0, SET_KEEP_ONSCREEN, -1, LIST_END); + setDelay(420); + break; + case 4: + SceneItem::display(0, 0); + setDelay(360); + break; + case 5: + SceneItem::display(1400, 3, SET_X, 60, SET_Y, _globals->_sceneManager._scene->_sceneBounds.bottom - 80, + SET_FONT, 2, SET_FG_COLOUR, 23, SET_POS_MODE, 0, SET_KEEP_ONSCREEN, -1, LIST_END); + setDelay(360); + break; + case 6: + SceneItem::display(0, 0); + break; + case 7: { + _globals->_player._frame = 1; + _globals->_player.setStrip2(1); + _globals->_player._numFrames = 5; + _globals->_player.animate(ANIM_MODE_5, this); + + Common::Point pt(205, 70); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, NULL); + _globals->_sceneManager._fadeMode = FADEMODE_NONE; + + scene->loadScene(1402); + break; + } + case 8: + _globals->_player.setStrip2(2); + _globals->_player._numFrames = 10; + _globals->_player.animate(ANIM_MODE_2, NULL); + + SceneItem::display(1400, 4, SET_X, 30, SET_Y, _globals->_player._position.y + 10, SET_FONT, 2, + SET_FG_COLOUR, 13, SET_POS_MODE, 0, SET_KEEP_ONSCREEN, -1, LIST_END); + setDelay(300); + break; + case 9: { + SceneItem::display(0, 0); + Common::Point pt(450, 45); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 10: + _globals->_sceneManager._scrollerRect = Rect(40, 20, 280, 180); + _globals->_sceneManager._fadeMode = FADEMODE_GRADUAL; + _globals->_stripNum = 1500; + _globals->_soundHandler.proc3(); + + _globals->_sceneManager.changeScene(1500); + break; + } +} + +void Scene1400::Action1::dispatch() { + Action::dispatch(); + + if ((_actionIndex > 3) && (_actionIndex < 9)) + _globals->_sceneText.setPosition(Common::Point(60, _globals->_sceneManager._scene->_sceneBounds.bottom - 80)); + + if ((_actionIndex <= 2) && (_globals->_player._percent > 22)) + _globals->_player.changeZoom(100 - (800 - _globals->_player._position.y)); + + if ((_actionIndex >= 9) && (_globals->_player._percent > 22)) + _globals->_player.changeZoom(100 - (_globals->_player._position.x - 205)); +} + +/*--------------------------------------------------------------------------*/ + +void Scene1400::postInit(SceneObjectList *OwnerList) { + if (_globals->_stripNum != 1400) { + loadScene(1401); + } else { + loadScene(1402); + } + Scene::postInit(); + + _globals->_sceneManager._scrollerRect = Rect(40, 90, 280, 180); + _globals->_player.postInit(); + _globals->_player.setVisage(1401); + _globals->_player.animate(ANIM_MODE_2, 0); + _globals->_player.setStrip2(4); + _globals->_player.setPriority2(4); + _globals->_player.disableControl(); + + _globals->_player._moveDiff = Common::Point(4, 2); + _globals->_player.setPosition(Common::Point(160, 800)); + _globals->_sceneManager._scene->_sceneBounds.centre(_globals->_player._position); + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + _globals->_sceneOffset.y = (_globals->_sceneManager._scene->_sceneBounds.top / 100) * 100; + + setAction(&_action1); + _globals->_soundHandler.startSound(118); +} + +/*-------------------------------------------------------------------------- + * Scene 1500 - Ringworld Space-port + * + *--------------------------------------------------------------------------*/ + +void Scene1500::Action1::signal() { + Scene1500 *scene = (Scene1500 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + scene->_object1.postInit(); + scene->_object1.setVisage(1501); + scene->_object1._moveDiff = Common::Point(2, 1); + scene->_object1.setPosition(Common::Point(204, 85)); + scene->_object1.animate(ANIM_MODE_2, NULL); + scene->_object1._numFrames = 3; + scene->_object1.changeZoom(-1); + + Common::Point pt(238, 121); + PlayerMover *mover = new PlayerMover(); + scene->_object1.addMover(mover, &pt, this); + break; + } + case 1: { + Common::Point pt(312, 145); + PlayerMover *mover = new PlayerMover(); + scene->_object1.addMover(mover, &pt, this); + break; + } + case 2: { + scene->_object1.setStrip(2); + scene->_object1.setFrame(1); + scene->_object1._moveDiff.y = 2; + scene->_object1._numFrames = 5; + + Common::Point pt(310, 150); + PlayerMover *mover = new PlayerMover(); + scene->_object1.addMover(mover, &pt, this); + break; + } + case 3: { + Common::Point pt(304, 165); + PlayerMover *mover = new PlayerMover(); + scene->_object1.addMover(mover, &pt, this); + break; + } + case 4: { + scene->_object1._numFrames = 3; + scene->_object1.setStrip2(3); + scene->_object1.animate(ANIM_MODE_2, this); + + Common::Point pt(94, 175); + PlayerMover *mover = new PlayerMover(); + scene->_object1.addMover(mover, &pt, this); + break; + } + case 5: + setDelay(30); + break; + case 6: + scene->_soundHandler.startSound(123); + scene->_object1.setStrip2(4); + scene->_object1.setFrame(1); + scene->_object1.animate(ANIM_MODE_5, this); + break; + case 7: + scene->_object1.setStrip2(5); + scene->_object1.animate(ANIM_MODE_2, NULL); + scene->_soundHandler.startSound(124, this); + break; + case 8: + _globals->_soundHandler.startSound(126, this); + break; + case 9: + _globals->_soundHandler.startSound(127); + _globals->_sceneManager.changeScene(2000); + break; + } +} + +void Scene1500::Action2::signal() { + Scene1500 *scene = (Scene1500 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(6); + break; + case 1: { + scene->_object2.postInit(); + scene->_object2.setVisage(1502); + scene->_object2.setPriority2(255); + scene->_object2.changeZoom(5); + scene->_object2._frame = 1; + scene->_object2._moveDiff = Common::Point(1, 1); + scene->_object2.setPosition(Common::Point(104, 184)); + scene->_object2.animate(ANIM_MODE_2, NULL); + + Common::Point pt(118, 147); + NpcMover *mover = new NpcMover(); + scene->_object2.addMover(mover, &pt, this); + break; + } + case 2: { + scene->_object2._moveDiff.x = 5; + scene->_object2.changeZoom(-1); + Common::Point pt(-55, 200); + NpcMover *mover = new NpcMover(); + scene->_object2.addMover(mover, &pt, this); + break; + } + case 3: + scene->_soundHandler.proc4(); + _globals->_stripNum = 1505; + _globals->_sceneManager.changeScene(1505); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene1500::postInit(SceneObjectList *OwnerList) { + loadScene(1500); + Scene::postInit(); + + if ((_globals->_stripNum == 1500) || ((_globals->_stripNum != 1504) && (_globals->_stripNum != 2751))) { + _globals->_soundHandler.startSound(120); + setZoomPercents(105, 20, 145, 100); + + setAction(&_action1); + } else { + setZoomPercents(150, 5, 200, 100); + + _object1.postInit(); + _object1.setVisage(1501); + _object1.setStrip2(5); + _object1.setPosition(Common::Point(94, 175)); + _object1.animate(ANIM_MODE_2, NULL); + + setAction(&_action2); + } +} + +} // End of namespace tSage diff --git a/engines/tsage/ringworld_scenes2.h b/engines/tsage/ringworld_scenes2.h new file mode 100644 index 0000000000..7cd72adf1c --- /dev/null +++ b/engines/tsage/ringworld_scenes2.h @@ -0,0 +1,152 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/scene_logic.h $ + * $Id: scene_logic.h 232 2011-02-12 11:56:38Z dreammaster $ + * + */ + +#ifndef TSAGE_RINGWORLD_SCENES2_H +#define TSAGE_RINGWORLD_SCENES2_H + +#include "common/scummsys.h" +#include "tsage/ringworld_logic.h" +#include "tsage/events.h" +#include "tsage/core.h" +#include "tsage/scenes.h" +#include "tsage/globals.h" + +namespace tSage { + +class Scene1000: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + private: + void zoom(bool up); + public: + virtual void signal(); + }; + +public: + SceneObject _object1, _object2, _object3, _object4; + Action1 _action1; + Action2 _action2; + Action3 _action3; + + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + +class Scene1001: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; +public: + SpeakerQText _speakerQText; + SpeakerSL _speakerSL; + SpeakerCText _speakerCText; + SpeakerCR _speakerCR; + Action1 _action1; + SceneObject _object1, _object2, _object3, _object4; + SceneObject _object5, _object6, _object7; + SoundHandler _soundHandler1, _soundHandler2; + + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + +class Scene1250: public Scene { +public: + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; +public: + SpeakerQText _speakerQText; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + SceneObject _object1, _object2; + + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + +class Scene1400: public Scene { +public: + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + virtual void dispatch(); + }; +public: + Action1 _action1; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + +}; + +class Scene1500: public Scene { +public: + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; +public: + SoundHandler _soundHandler; + Action1 _action1; + Action2 _action2; + SceneObject _object1, _object2, _object3; + + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + + + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/ringworld_scenes3.cpp b/engines/tsage/ringworld_scenes3.cpp new file mode 100644 index 0000000000..8a8730ca88 --- /dev/null +++ b/engines/tsage/ringworld_scenes3.cpp @@ -0,0 +1,6098 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#include "common/config-manager.h" +#include "tsage/ringworld_scenes3.h" +#include "tsage/scenes.h" +#include "tsage/tsage.h" +#include "tsage/staticres.h" + +namespace tSage { + +/*-------------------------------------------------------------------------- + * Scene 2000 - Cockpit cutscenes + * + *--------------------------------------------------------------------------*/ + +void Scene2000::Action1::signal() { + Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + error("Old stuff"); + break; + case 1: + scene->_stripManager.start(2075, this); + break; + case 2: + setDelay(4); + break; + case 3: + _globals->_stripNum = 0; + _globals->_sceneManager.changeScene(1250); + break; + } +} + +void Scene2000::Action2::signal() { + Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->_object2.animate(ANIM_MODE_6, NULL); + setDelay(_globals->_randomSource.getRandomNumber(179) + 60); + break; + case 1: + setDelay(_globals->_randomSource.getRandomNumber(179) + 60); + if (_globals->_randomSource.getRandomNumber(4) >= 2) + _actionIndex = 0; + break; + case 2: + setDelay(_globals->_randomSource.getRandomNumber(179) + 60); + _actionIndex = _globals->_randomSource.getRandomNumber(1); + break; + } +} + +void Scene2000::Action3::signal() { + Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->_object6.animate(ANIM_MODE_5, NULL); + setDelay(_globals->_randomSource.getRandomNumber(179) + 60); + break; + case 1: + scene->_object6.animate(ANIM_MODE_6, NULL); + setDelay(_globals->_randomSource.getRandomNumber(179) + 60); + _actionIndex = 0; + break; + } +} + +void Scene2000::Action4::signal() { + Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->_object4.animate(ANIM_MODE_5, NULL); + setDelay(_globals->_randomSource.getRandomNumber(179) + 60); + break; + case 1: + scene->_object4.animate(ANIM_MODE_6, NULL); + setDelay(_globals->_randomSource.getRandomNumber(179) + 60); + _actionIndex = 0; + break; + } +} + +void Scene2000::Action5::signal() { + Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->_object3.animate(ANIM_MODE_5, NULL); + setDelay(_globals->_randomSource.getRandomNumber(125) + 300); + break; + case 1: + scene->_object3.animate(ANIM_MODE_6, NULL); + setDelay(_globals->_randomSource.getRandomNumber(125) + 300); + _actionIndex = 0; + break; + } +} + +void Scene2000::Action6::signal() { + Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(130); + break; + case 1: + scene->_soundHandler2.startSound(79); + scene->_stripManager.start(2000, this); + break; + case 2: + _globals->_soundHandler.startSound(81); + scene->_object6.postInit(); + scene->_object6.setVisage(2003); + scene->_object6.setAction(NULL); + scene->_object6.setStrip2(2); + scene->_object6.setPosition(Common::Point(184, 137)); + scene->_object6.animate(ANIM_MODE_5, this); + break; + case 3: + scene->_stripManager.start(95, this); + break; + case 4: + scene->_object6.animate(ANIM_MODE_6, this); + break; + case 5: + _globals->_soundHandler.startSound(80); + scene->_object6.remove(); + _globals->_sceneManager.changeScene(1001); + break; + } +} + +void Scene2000::Action7::signal() { + Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(30); + break; + case 1: + scene->_stripManager.start(2072, this); + break; + case 2: + setDelay(3); + break; + case 3: + _globals->_sceneManager.changeScene(2222); + break; + } +} + +void Scene2000::Action8::signal() { + Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + error("Old stuff"); + break; + case 1: + scene->_stripManager.start(2073, this); + break; + case 2: + setDelay(10); + break; + case 3: + _globals->_stripNum = 2005; + _globals->_sceneManager.changeScene(1000); + break; + } +} + +void Scene2000::Action9::signal() { + Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + error("Old stuff"); + break; + case 1: + scene->_stripManager.start(2074, this); + break; + case 2: + setDelay(3); + break; + case 3: + _globals->_stripNum = 2008; + _globals->_sceneManager.changeScene(9999); + break; + } +} + +void Scene2000::Action10::signal() { + switch (_actionIndex++) { + case 0: + setDelay(30); + break; + case 1: + error("Old stuff"); + break; + case 2: + SceneItem::display(2000, 17, SET_Y, 20, SET_X, 110, SET_FONT, 2, SET_BG_COLOUR, -1, + SET_FG_COLOUR, 17, SET_WIDTH, 200, SET_POS_MODE, 0, SET_KEEP_ONSCREEN, 1, LIST_END); + break; + case 3: + SceneItem::display(0, 0); + _globals->_stripNum = 0; + _globals->_sceneManager.changeScene(9999); + break; + } +} + +void Scene2000::Action11::signal() { + Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + error("Old stuff"); + break; + case 1: + scene->_stripManager.start(2076, this); + break; + case 2: + scene->_stripManager.start(2077, this); + break; + case 3: + _globals->_stripNum = 0; + _globals->_sceneManager.changeScene(1400); + break; + } +} + +void Scene2000::Action12::signal() { + Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(60); + break; + case 1: + _globals->_events.setCursor(CURSOR_WALK); + scene->_stripManager.start(2020, this); + break; + case 2: + _globals->_player.disableControl(); + setDelay(10); + break; + case 3: + _globals->_sceneManager.changeScene(2300); + break; + } +} + +void Scene2000::Action13::signal() { + Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(30); + break; + case 1: + scene->_stripManager.start(2078, this); + break; + case 2: + SceneItem::display(0, 0); + _globals->_stripNum = 2751; + _globals->_sceneManager.changeScene(1500); + break; + } +} + +void Scene2000::Action14::signal() { + Scene2000 *scene = (Scene2000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(30); + break; + case 1: + scene->_stripManager.start(2070, this); + break; + case 2: + setDelay(60); + break; + case 3: + _globals->_soundHandler.startSound(99); + scene->_object8.show(); + scene->_object8.animate(ANIM_MODE_5, this); + break; + case 4: + _globals->_soundHandler.startSound(12); + scene->_object8.setStrip(2); + scene->_object8.setFrame(1); + scene->_object9.show(); + scene->_object10.show(); + setDelay(60); + break; + case 5: + scene->_stripManager.start(2001, this, scene); + break; + case 6: + _globals->_soundHandler.proc1(false); + scene->_object8.setStrip(1); + scene->_object8.setFrame(scene->_object8.getFrameCount()); + scene->_object8.animate(ANIM_MODE_6, this); + + scene->_object9.remove(); + scene->_object10.remove(); + break; + case 7: + _globals->_soundHandler.startSound(111); + scene->_object8.remove(); + setDelay(5); + break; + case 8: + scene->_stripManager.start(2071, this); + break; + case 9: + _globals->_stripNum = 1250; + _globals->_sceneManager.changeScene(1000); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene2000::postInit(SceneObjectList *OwnerList) { + loadScene(2000); + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + _stripManager.addSpeaker(&_speakerQR); + _stripManager.addSpeaker(&_speakerSL); + _stripManager.addSpeaker(&_speakerMR); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerMText); + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerGameText); + _stripManager.addSpeaker(&_speakerHText); + + _speakerQText._npc = &_object2; + _speakerSText._npc = &_object3; + _speakerMText._npc = &_object6; + _speakerHText._npc = &_object6; + _stripManager.setCallback(this); + + _object3.postInit(); + _object3.setVisage(2002); + _object3.setPosition(Common::Point(65, 199)); + + _object4.postInit(); + _object4.setVisage(2002); + _object4.setStrip(2); + _object4.setPosition(Common::Point(125, 199)); + _object4.setAction(&_action4); + + _object2.postInit(); + _object2.setVisage(2001); + _object2.setPosition(Common::Point(43, 115)); + _object2.setAction(&_action2); + + _globals->_player.disableControl(); + + _object6.postInit(); + _object6.setVisage(2003); + _object6.setPosition(Common::Point(267, 170)); + _object6.setAction(&_action3); + + _object8.postInit(); + _object8.setVisage(2005); + _object8.setPosition(Common::Point(169, 133)); + _object8.setPriority(133); + _object8.hide(); + + _object9.postInit(); + _object9.setVisage(2005); + _object9.setStrip2(3); + _object9.setFrame(4); + _object9.setPosition(Common::Point(136, 86)); + _object9.setPriority2(190); + _object9.hide(); + + _object10.postInit(); + _object10.setVisage(2005); + _object10.setStrip2(5); + _object10.setFrame(4); + _object10.setPosition(Common::Point(202, 86)); + _object10.setPriority2(195); + _object10.hide(); + + switch (_globals->_sceneManager._previousScene) { + case 1000: + setAction(&_action7); + break; + case 1001: + _object6.remove(); + setAction(&_action12); + break; + case 1500: + setAction(&_action13); + break; + case 2200: + _globals->_soundHandler.startSound(111); + setAction(&_action14); + break; + case 2222: + _globals->_soundHandler.startSound(115); + setAction(&_action8); + break; + case 3500: + setAction(&_action11); + break; + default: + _object6.remove(); + _globals->_soundHandler.startSound(80); + setAction(&_action6); + break; + } + + _soundHandler1.startSound(78); + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160; +} + +void Scene2000::stripCallback(int v) { + switch (v) { + case 0: + _object9.setStrip(3); + _object9.animate(ANIM_MODE_7, NULL); + _object10.setStrip(6); + _object10.setFrame(1); + _object10.animate(ANIM_MODE_5, NULL); + break; + case 1: + _object10.setStrip(5); + _object10.animate(ANIM_MODE_7, NULL); + _object9.setStrip(4); + _object9.setFrame(1); + _object9.animate(ANIM_MODE_5, NULL); + break; + case 2: + _object9.animate(ANIM_MODE_NONE, NULL); + break; + case 3: + _object10.setStrip(6); + _object10.setFrame(1); + _object10.animate(ANIM_MODE_5, NULL); + _object9.setStrip(4); + _object9.setFrame(1); + _object9.animate(ANIM_MODE_5, NULL); + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 2100 - Starcraft Cockpit + * + *--------------------------------------------------------------------------*/ + +void Scene2100::Action1::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + if (!scene->_field1800) + setDelay(1); + else { + setAction(&scene->_sequenceManager, this, 2102, &_globals->_player, NULL); + scene->_field1800 = 0; + } + break; + case 1: { + Common::Point pt(157, 62); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 2: + scene->_soundHandler.startSound(162); + scene->_object1.animate(ANIM_MODE_5, this); + break; + case 3: { + Common::Point pt(157, 56); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 4: + _globals->_player._strip = 3; + setDelay(3); + break; + case 5: + _globals->_player.setPriority2(1); + scene->_area1.display(); + scene->_area2.display(); + scene->_area3.display(); + scene->_area4.display(); + + scene->_area1.draw(true); + _state = 0; + _globals->_events.setCursor(CURSOR_USE); + + while (!_state && !_vm->getEventManager()->shouldQuit()) { + // Wait for an event + Event event; + if (!_globals->_events.getEvent(event)) { + g_system->updateScreen(); + g_system->delayMillis(10); + continue; + } + + if (scene->_area1._bounds.contains(event.mousePos)) { + scene->_area1.draw(true); + _state = scene->_area1._actionId; + } + if (scene->_area2._bounds.contains(event.mousePos)) { + scene->_area1.draw(false); + scene->_area2.draw(true); + _state = scene->_area2._actionId; + } + if (scene->_area3._bounds.contains(event.mousePos)) { + scene->_area1.draw(false); + scene->_area3.draw(true); + _state = scene->_area3._actionId; + } + } + + scene->_soundHandler.startSound(161); + scene->_area1.restore(); + scene->_area2.restore(); + scene->_area3.restore(); + scene->_area4.restore(); + + if (_state == 2100) { + setDelay(1); + } else { + scene->_soundHandler.startSound(162); + scene->_object1.animate(ANIM_MODE_6, this); + } + break; + case 6: + if (_state == 2100) { + Common::Point pt(157, 65); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } else { + _globals->_sceneManager.changeScene(_state); + } + break; + case 7: + _globals->_player.setPriority2(-1); + scene->_soundHandler.startSound(162); + scene->_object1.animate(ANIM_MODE_6, this); + break; + case 8: + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene2100::Action2::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->_object3._numFrames = 5; + setDelay(_globals->_randomSource.getRandomNumber(59)); + break; + case 1: + scene->_object3.animate(ANIM_MODE_5, this); + break; + case 2: + setDelay(_globals->_randomSource.getRandomNumber(59)); + break; + case 3: + scene->_object3.animate(ANIM_MODE_6, this); + _actionIndex = 0; + break; + } +} + +void Scene2100::Action3::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + case 2: + setDelay(_globals->_randomSource.getRandomNumber(119)); + break; + case 1: + scene->_object2.animate(ANIM_MODE_5, this); + break; + case 3: + scene->_object2.animate(ANIM_MODE_6, this); + _actionIndex = 0; + break; + } +} + +void Scene2100::Action4::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + if (!scene->_field1800) + setDelay(1); + else + setAction(&scene->_sequenceManager, this, 2102, &_globals->_player, NULL); + break; + case 1: { + Common::Point pt(80, 66); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 2: + _globals->_player.setVisage(2109); + _globals->_player._frame = 1; + _globals->_player._strip = 2; + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 3: + _globals->_sceneManager.changeScene(2120); + break; + } +} + +void Scene2100::Action5::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(30); + break; + case 1: + setAction(&scene->_sequenceManager, this, 2104, &_globals->_player, &scene->_object1, NULL); + break; + case 2: { + Common::Point pt(272, 127); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 3: + _globals->_player.checkAngle(&scene->_object3); + setDelay(30); + break; + case 4: + _globals->_sceneManager.changeScene(3700); + break; + } +} + +void Scene2100::Action6::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + scene->_object2.setVisage(2806); + scene->_object2.setStrip(1); + scene->_object2.setStrip2(-1); + scene->_object2.changeZoom(-1); + scene->_object2.setPosition(Common::Point(155, 116)); + scene->_object2.setObjectWrapper(new SceneObjectWrapper()); + scene->_object2.setAction(NULL); + scene->_object2.animate(ANIM_MODE_1, NULL); + + Common::Point pt(130, 116); + NpcMover *mover = new NpcMover(); + scene->_object2.addMover(mover, &pt, NULL); + break; + } + case 1: { + scene->_object2.setPriority2(-1); + Common::Point pt(153, 67); + NpcMover *mover = new NpcMover(); + scene->_object2.addMover(mover, &pt, NULL); + break; + } + case 2: + remove(); + break; + } +} + +void Scene2100::Action7::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(60); + break; + case 1: + setAction(&scene->_sequenceManager, this, 2104, &_globals->_player, &scene->_object1, NULL); + break; + case 2: + setAction(&scene->_sequenceManager, this, 2104, &_globals->_player, NULL); + break; + case 3: + _globals->_sceneManager.changeScene(8100); + break; + } +} + +void Scene2100::Action8::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(60); + break; + case 1: + setAction(&scene->_sequenceManager, this, 2104, &_globals->_player, &scene->_object1, NULL); + break; + case 2: { + Common::Point pt(200, 174); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 3: + _globals->_player.checkAngle(&scene->_object3); + scene->_stripManager.start((_globals->_inventory._translator._sceneNumber == 1) ? 7720 : 7710, this); + break; + case 4: + if (_globals->_inventory._translator._sceneNumber != 1) + _globals->_sceneManager.changeScene(7600); + else { + _globals->setFlag(24); + _globals->_player.enableControl(); + remove(); + } + break; + } +} + +void Scene2100::Action9::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(60); + break; + case 1: + scene->_stripManager.start(6050, this); + break; + case 2: + scene->_soundHandler.startSound(99); + scene->_object4.show(); + scene->_object4.animate(ANIM_MODE_5, this); + break; + case 3: + scene->_soundHandler.startSound(12); + scene->_object4.setStrip(2); + scene->_stripManager.start(6051, this, scene); + break; + case 4: + scene->_soundHandler.proc1(false); + scene->_object4.setStrip(1); + scene->_object4.setFrame(scene->_object4.getFrameCount()); + scene->_object4.animate(ANIM_MODE_6, this); + break; + case 5: + scene->_object4.hide(); + _globals->_events.setCursor(CURSOR_WALK); + scene->_stripManager.start(6010, this); + break; + case 6: + if (scene->_stripManager._field2E8 != 165) + setAction(&scene->_action10); + else + setAction(&scene->_action11); + break; + } +} + +void Scene2100::Action10::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(60); + break; + case 1: + setAction(&scene->_sequenceManager, this, 2102, &_globals->_player, NULL); + break; + case 2: { + _globals->_player.disableControl(); + Common::Point pt(155, 64); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 3: + scene->_object3.setVisage(2105); + scene->_object3.setStrip(2); + scene->_object3.setFrame(1); + scene->_object3._numFrames = 10; + scene->_object3.setAction(NULL); + scene->_object3.animate(ANIM_MODE_5, this); + break; + case 4: { + scene->_object3.setVisage(2705); + scene->_object3.setStrip2(-1); + scene->_object3.changeZoom(-1); + scene->_object3.setPriority2(-1); + scene->_object3.setPosition(Common::Point(260, 156)); + scene->_object3.setObjectWrapper(new SceneObjectWrapper()); + scene->_object3.animate(ANIM_MODE_1, NULL); + + Common::Point pt(166, 64); + PlayerMover *mover = new PlayerMover(); + scene->_object3.addMover(mover, &pt, this); + + setAction(&scene->_action6, NULL); + break; + } + case 5: + scene->_soundHandler.startSound(162); + scene->_object1.animate(ANIM_MODE_5, this); + break; + case 6: { + _globals->_player.setPriority2(1); + Common::Point pt(144, 54); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 7: { + scene->_object3.setPriority2(2); + Common::Point pt1(163, 55); + NpcMover *mover1 = new NpcMover(); + scene->_object3.addMover(mover1, &pt1, NULL); + + scene->_object2.setPriority2(2); + Common::Point pt2(158, 55); + NpcMover *mover2 = new NpcMover(); + scene->_object2.addMover(mover2, &pt2, this); + break; + } + case 8: + _globals->_player.setPriority2(1); + _globals->_player.setStrip(1); + scene->_object3.setPriority2(1); + scene->_object3.setStrip(2); + scene->_object2.setPriority2(2); + scene->_object2.setStrip(3); + + setDelay(45); + break; + case 9: + scene->_soundHandler.startSound(162); + scene->_object1.animate(ANIM_MODE_6, this); + break; + case 10: + _globals->setFlag(70); + _globals->_stripNum = 2101; + _globals->_sceneManager.changeScene(2320); + break; + } +} + +void Scene2100::Action11::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(60); + break; + case 1: + scene->_object3._numFrames = 10; + scene->_object3.setAction(NULL); + scene->_object3.setVisage(2105); + scene->_object3.setStrip(2); + scene->_object3.setFrame(1); + scene->_object3.animate(ANIM_MODE_5, this); + break; + case 2: { + scene->_object3.setVisage(2705); + scene->_object3.setStrip2(-1); + scene->_object3.changeZoom(-1); + scene->_object3.setPriority2(-1); + scene->_object3.setPosition(Common::Point(260, 156)); + scene->_object3.setObjectWrapper(new SceneObjectWrapper()); + scene->_object3.animate(ANIM_MODE_1, NULL); + + Common::Point pt(158, 62); + PlayerMover *mover = new PlayerMover(); + scene->_object3.addMover(mover, &pt, this); + + setAction(&scene->_action6, NULL); + break; + } + case 3: + scene->_soundHandler.startSound(162); + scene->_object1.animate(ANIM_MODE_5, this); + break; + case 4: { + scene->_object3.setPriority2(1); + Common::Point pt1(163, 55); + NpcMover *mover1 = new NpcMover(); + scene->_object3.addMover(mover1, &pt1, NULL); + + scene->_object2.setPriority2(1); + Common::Point pt2(158, 55); + NpcMover *mover2 = new NpcMover(); + scene->_object2.addMover(mover2, &pt2, this); + break; + } + case 5: + scene->_object3.setStrip(2); + scene->_object2.setStrip(3); + setDelay(45); + break; + case 6: + scene->_soundHandler.startSound(162); + scene->_object1.animate(ANIM_MODE_6, this); + break; + case 7: + scene->_object3.remove(); + scene->_object2.remove(); + _globals->setFlag(70); + _globals->_stripNum = 2102; + _globals->_player.enableControl(); + _globals->_player._canWalk = false; + break; + } +} + +void Scene2100::Action12::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(10); + break; + case 1: + scene->_stripManager.start(6000, this); + break; + case 2: + scene->_soundHandler.startSound(162); + scene->_object1.animate(ANIM_MODE_5, this); + break; + case 3: { + Common::Point pt1(158, 74); + NpcMover *mover1 = new NpcMover(); + _globals->_player.addMover(mover1, &pt1, this); + + Common::Point pt2(158, 68); + NpcMover *mover2 = new NpcMover(); + scene->_object2.addMover(mover2, &pt2, NULL); + break; + } + case 4: { + scene->_soundHandler.startSound(162); + scene->_object1.animate(ANIM_MODE_6, NULL); + + _globals->_player.setPriority2(-1); + Common::Point pt1(277, 84); + PlayerMover *mover1 = new PlayerMover(); + _globals->_player.addMover(mover1, &pt1, this); + + scene->_object2.setPriority2(-1); + Common::Point pt2(255, 76); + PlayerMover *mover2 = new PlayerMover(); + scene->_object2.addMover(mover2, &pt2, this); + break; + } + case 6: + _globals->_player.setStrip(4); + scene->_object2.setStrip(4); + setDelay(60); + break; + case 7: + _globals->_events.setCursor(CURSOR_WALK); + scene->_stripManager.start(6052, this); + break; + case 8: + if (scene->_stripManager._field2E8 == 320) + _globals->setFlag(74); + setDelay(30); + break; + case 9: + _globals->_events.setCursor(OBJECT_STUNNER); + scene->_object2.setAction(&scene->_action13); + setDelay(60); + break; + case 10: + if (_globals->getFlag(74)) + setDelay(1); + break; + case 11: + scene->_stripManager.start(2170, this); + break; + case 12: + setDelay(5); + break; + case 13: + scene->_stripManager.start(_globals->getFlag(74) ? 2172 : 2174, this); + break; + case 14: + if (_globals->getFlag(74)) { + _globals->_stripNum = 6100; + _globals->_sceneManager.changeScene(2320); + } else { + _globals->_sceneManager.changeScene(6100); + } + remove(); + break; + } +} + +void Scene2100::Action13::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(6); + break; + case 1: { + scene->_object2.setPriority2(113); + Common::Point pt(178, 116); + PlayerMover *mover = new PlayerMover(); + scene->_object2.addMover(mover, &pt, this); + break; + } + case 2: { + Common::Point pt(150, 116); + NpcMover *mover = new NpcMover(); + scene->_object2.addMover(mover, &pt, this); + break; + } + case 3: + scene->_object2.setVisage(2108); + scene->_object2._strip = 3; + scene->_object2.setPosition(Common::Point(150, 100)); + scene->_object2.animate(ANIM_MODE_NONE, NULL); + scene->_object2.changeZoom(100); + scene->_object2.setAction(&scene->_action3); + setDelay(15); + break; + case 4: + remove(); + break; + } +} + +void Scene2100::Action14::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(6); + break; + case 1: + setAction(&scene->_sequenceManager, this, 2104, &_globals->_player, &scene->_object1, NULL); + break; + case 2: + setAction(&scene->_sequenceManager, this, 2101, &_globals->_player, NULL); + break; + case 3: + scene->_stripManager.start(6008, this); + break; + case 4: + scene->_soundHandler.startSound(99); + scene->_object4.show(); + scene->_object4.animate(ANIM_MODE_5, this); + break; + case 5: + scene->_object4.setStrip(2); + scene->_stripManager.start(6009, this, scene); + break; + case 6: + scene->_soundHandler.proc1(false); + scene->_object4.setStrip(1); + scene->_object4.setFrame(scene->_object4.getFrameCount()); + scene->_object4.animate(ANIM_MODE_6, this); + break; + case 7: + scene->_stripManager.start(6060, this); + break; + case 8: + scene->_object3._numFrames = 10; + scene->_object3.setAction(NULL); + scene->_object3.setVisage(2105); + scene->_object3.setStrip(2); + scene->_object3.setFrame(1); + scene->_object3.animate(ANIM_MODE_5, this); + break; + case 9: { + scene->_object3.setVisage(2705); + scene->_object3.setStrip2(-1); + scene->_object3.changeZoom(-1); + scene->_object3.setPriority2(-1); + scene->_object3.setPosition(Common::Point(260, 156)); + scene->_object3.setObjectWrapper(new SceneObjectWrapper()); + scene->_object3.animate(ANIM_MODE_1, NULL); + + Common::Point pt(157, 65); + PlayerMover *mover = new PlayerMover(); + scene->_object3.addMover(mover, &pt, this); + break; + } + case 10: + scene->_soundHandler.startSound(162); + scene->_object1.animate(ANIM_MODE_5, this); + break; + case 11: { + Common::Point pt(159, 51); + NpcMover *mover = new NpcMover(); + scene->_object3.addMover(mover, &pt, this); + break; + } + case 12: + scene->_object3.setStrip(2); + setDelay(30); + case 13: + scene->_object3.setPriority2(1); + scene->_soundHandler.startSound(162); + scene->_object1.animate(ANIM_MODE_6, this); + break; + case 14: + setDelay(90); + break; + case 15: + _globals->_sceneManager.changeScene(7000); + remove(); + break; + } +} + +void Scene2100::Action15::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(6); + break; + case 1: + scene->_object3.postInit(); + scene->_object3.setVisage(2705); + scene->_object3.animate(ANIM_MODE_1, NULL); + scene->_object3.setObjectWrapper(new SceneObjectWrapper()); + scene->_object3.setPosition(Common::Point(157, 56)); + scene->_object3.setPriority2(1); + scene->_object3.changeZoom(-1); + + scene->_soundHandler.startSound(162); + scene->_object1.animate(ANIM_MODE_5, this); + break; + case 2: { + scene->_object3.setPriority2(-1); + Common::Point pt(177, 68); + NpcMover *mover = new NpcMover(); + scene->_object3.addMover(mover, &pt, this); + break; + } + case 3: { + scene->_soundHandler.startSound(162); + scene->_object1.animate(ANIM_MODE_6, this); + + Common::Point pt(272, 140); + NpcMover *mover = new NpcMover(); + scene->_object3.addMover(mover, &pt, this); + break; + } + case 4: { + Common::Point pt(266, 150); + NpcMover *mover = new NpcMover(); + scene->_object3.addMover(mover, &pt, this); + break; + } + case 5: { + scene->_object3.setPriority2(156); + + Common::Point pt(260, 156); + NpcMover *mover = new NpcMover(); + scene->_object3.addMover(mover, &pt, this); + break; + } + case 6: + scene->_object3.setVisage(2105); + scene->_object3._strip = 1; + scene->_object3._frame = 1; + scene->_object3.setPosition(Common::Point(256, 156)); + scene->_object3.animate(ANIM_MODE_5, this); + scene->_object3.changeZoom(100); + + scene->_object3.animate(ANIM_MODE_NONE, NULL); + break; + case 7: + remove(); + break; + } +} + +void Scene2100::Action16::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + case 4: + setDelay(3); + break; + case 1: + scene->_stripManager.start(7001, this); + break; + case 2: + setAction(&scene->_sequenceManager, this, 2102, &_globals->_player, NULL); + break; + case 3: { + _globals->_player.disableControl(); + Common::Point pt(155, 63); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 5: + scene->_soundHandler.startSound(162); + scene->_object1.animate(ANIM_MODE_5, this); + break; + case 6: { + Common::Point pt(160, 54); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 7: + _globals->_player.setPriority2(1); + _globals->_player.setStrip(3); + setDelay(45); + break; + case 8: + scene->_soundHandler.startSound(162); + scene->_object1.animate(ANIM_MODE_6, this); + break; + case 9: + _globals->setFlag(15); + _globals->setFlag(36); + _globals->_sceneManager.changeScene(7000); + remove(); + break; + } +} + +void Scene2100::Action17::signal() { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(60); + break; + case 1: + setAction(&scene->_sequenceManager, this, 2104, &_globals->_player, &scene->_object1, NULL); + break; + case 2: + setAction(&scene->_sequenceManager, this, 2101, &_globals->_player, NULL); + break; + case 3: + scene->_stripManager.start(7070, this); + break; + case 4: + scene->_soundHandler.startSound(99); + scene->_object4.show(); + scene->_object4.animate(ANIM_MODE_5, this); + break; + case 5: + scene->_soundHandler.startSound(12); + scene->_object4.setStrip(2); + scene->_stripManager.start(7071, this, scene); + break; + case 6: + scene->_soundHandler.proc1(NULL); + scene->_object4.setStrip(1); + scene->_object4.setFrame(scene->_object4.getFrameCount()); + scene->_object4.animate(ANIM_MODE_6, this); + break; + case 7: + scene->_stripManager.start(7072, this); + break; + case 8: + _globals->_inventory._stasisNegator._sceneNumber = 1; + _globals->_sceneManager.changeScene(9100); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene2100::Hotspot2::doAction(int action) { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2100, 3); + break; + case CURSOR_USE: + if (_globals->getFlag(13)) + SceneItem::display2(2100, 29); + else { + _globals->_player.disableControl(); + scene->setAction(&scene->_action4); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2100::Hotspot3::doAction(int action) { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2100, 4); + break; + case CURSOR_USE: + if (_globals->getFlag(13)) + SceneItem::display2(2100, 29); + else { + _globals->_player.disableControl(); + scene->setAction(&scene->_action4); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2100::Hotspot4::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2100, 5); + break; + case CURSOR_USE: + SceneItem::display2(2100, 6); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2100::Hotspot8::doAction(int action) { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2100, 12); + break; + case CURSOR_USE: + if (_globals->getFlag(13)) + SceneItem::display2(2100, 29); + else { + _globals->_player.disableControl(); + scene->setAction(&scene->_action4); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2100::Hotspot10::doAction(int action) { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2100, 13); + break; + case CURSOR_USE: + if (scene->_field1800) { + _globals->_player.disableControl(); + scene->_sceneMode = 2102; + scene->setAction(&scene->_sequenceManager, scene, 2102, &_globals->_player, NULL); + } else if (_globals->getFlag(13)) { + SceneItem::display2(2100, 28); + } else { + scene->setAction(&scene->_sequenceManager, scene, 2101, &_globals->_player, NULL); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2100::Hotspot14::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(0)) + SceneItem::display2(2100, 19); + else + SceneItem::display2(2100, 18); + break; + case CURSOR_USE: + if (_globals->getFlag(1)) + SceneItem::display2(2100, 21); + else + SceneItem::display2(2100, 20); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2100::Object1::doAction(int action) { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2100, 1); + break; + case CURSOR_USE: + scene->setAction(&scene->_action1); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2100::Object2::doAction(int action) { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2100, 30); + break; + case CURSOR_TALK: + if (_globals->getFlag(72)) { + _globals->_player.disableControl(); + if (!_globals->getFlag(52)) + scene->setAction(&scene->_sequenceManager, scene, 2111, NULL); + else { + scene->_sceneMode = _globals->getFlag(53) ? 2112 : 2110; + scene->setAction(&scene->_sequenceManager, scene, scene->_sceneMode, NULL); + } + } else { + if (_globals->getFlag(14)) + SceneItem::display2(2100, 32); + else { + _globals->setFlag(14); + _globals->_player.disableControl(); + scene->_sceneMode = 2108; + scene->setAction(&scene->_sequenceManager, scene, 2109, NULL); + } + } + + scene->setAction(&scene->_action4); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2100::Object3::doAction(int action) { + Scene2100 *scene = (Scene2100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + if (!_globals->getFlag(59)) + SceneItem::display2(2100, 34); + else + error("***I have no response."); + break; + + case CURSOR_TALK: + if (!_globals->getFlag(59)) { + _globals->_player.disableControl(); + scene->_sceneMode = 2108; + scene->setAction(&scene->_sequenceManager, scene, 2108, NULL); + } else { + error("***I have no response."); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene2100::Scene2100(): + _hotspot1(0, CURSOR_LOOK, 2100, 2, LIST_END), + _hotspot5(0, CURSOR_LOOK, 2100, 9, LIST_END), + _hotspot6(0, CURSOR_LOOK, 2100, 7, CURSOR_USE, 2100, 8, LIST_END), + _hotspot7(0, CURSOR_LOOK, 2100, 7, CURSOR_USE, 2100, 11, LIST_END), + _hotspot9(0, CURSOR_LOOK, 2100, 14, LIST_END), + _hotspot11(0, CURSOR_LOOK, 2100, 15, CURSOR_USE, 2100, 16, LIST_END), + _hotspot12(0, CURSOR_LOOK, 2100, 24, CURSOR_USE, 2100, 25, LIST_END), + _hotspot13(0, CURSOR_LOOK, 2100, 17, LIST_END), + _hotspot15(0, CURSOR_LOOK, 2100, 22, CURSOR_USE, 2100, 23, LIST_END) { +} + +void Scene2100::postInit(SceneObjectList *OwnerList) { + loadScene(2100); + Scene::postInit(); + setZoomPercents(60, 80, 200, 100); + + _stripManager.addSpeaker(&_speakerMText); + _stripManager.addSpeaker(&_speakerMR); + _stripManager.addSpeaker(&_speakerQL); + _stripManager.addSpeaker(&_speakerQR); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerSL); + _stripManager.addSpeaker(&_speakerSAL); + _stripManager.addSpeaker(&_speakerHText); + _stripManager.addSpeaker(&_speakerGameText); + _speakerMText._npc = &_object3; + _speakerQText._npc = &_globals->_player; + _speakerSText._npc = &_object2; + + _object1.postInit(); + _object1.setVisage(2100); + _object1.animate(ANIM_MODE_NONE, NULL); + _object1.setPosition(Common::Point(157, 57)); + _object1.setPriority(5); + + _hotspot3.postInit(); + _hotspot3.setVisage(2101); + _hotspot3._frame = 1; + _hotspot3.animate(ANIM_MODE_2, NULL); + _hotspot3.setPosition(Common::Point(53, 44)); + _hotspot3.changeZoom(100); + _hotspot3.setPriority2(1); + + _hotspot4.postInit(); + _hotspot4.setVisage(2101); + _hotspot4._frame = 1; + _hotspot4._strip = 3; + _hotspot4.animate(ANIM_MODE_8, 0, NULL); + _hotspot4.setPosition(Common::Point(274, 52)); + _hotspot4.changeZoom(100); + _hotspot4.setPriority2(1); + + _hotspot5.postInit(); + _hotspot5.setVisage(2101); + _hotspot5._frame = 1; + _hotspot5._strip = 4; + _hotspot5.animate(ANIM_MODE_8, 0, NULL); + _hotspot5.setPosition(Common::Point(219, 141)); + _hotspot5.changeZoom(100); + _hotspot5.setPriority2(160); + + _hotspot6.postInit(); + _hotspot6.setVisage(2101); + _hotspot6._frame = 1; + _hotspot6._strip = 5; + _hotspot6.setPriority2(175); + _hotspot6.animate(ANIM_MODE_8, 0, NULL); + _hotspot6.setPosition(Common::Point(97, 142)); + _hotspot6.changeZoom(100); + + _hotspot7.postInit(); + _hotspot7.setVisage(2101); + _hotspot7._frame = 1; + _hotspot7._strip = 6; + _hotspot7.animate(ANIM_MODE_NONE, NULL); + _hotspot7.setPosition(Common::Point(133, 46)); + _hotspot7.changeZoom(100); + _hotspot7.setPriority2(1); + + _hotspot8.postInit(); + _hotspot8.setVisage(2101); + _hotspot8._frame = 1; + _hotspot8._strip = 7; + _hotspot8.animate(ANIM_MODE_8, 0, NULL); + _hotspot8.setPosition(Common::Point(20, 45)); + _hotspot8.changeZoom(100); + _hotspot8.setPriority2(1); + + _hotspot2.postInit(); + _hotspot2.setVisage(2101); + _hotspot2._frame = 1; + _hotspot2._strip = 7; + _hotspot2.animate(ANIM_MODE_8, 0, NULL); + _hotspot2.setPosition(Common::Point(88, 41)); + _hotspot2.changeZoom(100); + _hotspot2.setPriority2(1); + + _hotspot11.setBounds(Rect(139, 74, 173, 96)); + _hotspot10.setBounds(Rect(71, 100, 91, 135)); + _hotspot9.setBounds(Rect(225, 110, 251, 136)); + _hotspot14.setBounds(Rect(100, 97, 216, 130)); + _hotspot13.setBounds(Rect(13, 124, 94, 168)); + _hotspot12.setBounds(Rect(217, 141, 307, 155)); + _hotspot15.setBounds(Rect(14, 90, 46, 107)); + _hotspot1.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + + if (!_globals->getFlag(36) && !_globals->getFlag(70) && !_globals->getFlag(43)) { + _object3.postInit(); + _object3.setPosition(Common::Point(246, 156)); + _object3.animate(ANIM_MODE_NONE, NULL); + _object3.changeZoom(100); + _object3.setPriority2(156); + _object3.setVisage(2107); + _object3.setStrip(1); + _object3.setAction(&_action2); + _globals->_sceneItems.push_back(&_object3); + } + + if (!_globals->getFlag(59) && !_globals->getFlag(70) && !_globals->getFlag(37) && !_globals->getFlag(114)) { + _object2.postInit(); + _object2.setVisage(2108); + _object2._strip = 3; + _object2.setPosition(Common::Point(150, 100)); + _object2.animate(ANIM_MODE_NONE, NULL); + _object2.changeZoom(100); + _object2.setPriority2(113); + _object2.setAction(&_action3); + _globals->_sceneItems.push_back(&_object2); + } + + _globals->_sceneItems.addItems(&_hotspot15, &_hotspot11, &_hotspot10, &_hotspot9, &_hotspot14, + &_hotspot13, &_hotspot12, &_hotspot8, &_object1, &_hotspot2, &_hotspot3, &_hotspot4, &_hotspot5, + &_hotspot6, &_hotspot7, &_hotspot1, NULL); + + _area1.setup(2153, 2, 1, 2100); + _area1._pt = Common::Point(200, 31); + _area2.setup(2153, 3, 1, 2150); + _area2._pt = Common::Point(200, 50); + _area3.setup(2153, 4, 1, 2320); + _area3._pt = Common::Point(200, 75); + _area4.setup(2153, 1, 1, OBJECT_TRANSLATOR); + _area4._pt = Common::Point(237, 77); + + _globals->_player.postInit(); + _globals->_player.setVisage(_globals->getFlag(13) ? 2170 : 0); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player._moveDiff.x = 4; + _globals->_player.changeZoom(-1); + _globals->_player.disableControl(); + _field1800 = 0; + + switch (_globals->_sceneManager._previousScene) { + case 2120: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + _object1.setPriority2(-1); + _globals->_player.setPriority2(-1); + _globals->_player.setPosition(Common::Point(80, 66)); + _globals->_player.enableControl(); + break; + case 2150: + _globals->_player.setPriority2(1); + _globals->_player.setPosition(Common::Point(157, 56)); + _sceneMode = 2104; + setAction(&_sequenceManager, this, 2104, &_globals->_player, &_object1, NULL); + break; + case 2222: + if (_globals->_sceneObjects->contains(&_object3)) + _object3.remove(); + + _globals->_player.setPriority2(1); + _globals->_player.setPosition(Common::Point(144, 55)); + + _object2.setVisage(2806); + _object2.changeZoom(-1); + _object2.setPosition(Common::Point(158, 55)); + _object2.setPriority2(1); + _object2.setAction(NULL); + _object2.setObjectWrapper(new SceneObjectWrapper()); + _object2.animate(ANIM_MODE_1, NULL); + _object2.setStrip(3); + setAction(&_action12); + break; + case 2320: + if (_globals->_stripNum == 2321) { + if (_globals->_sceneObjects->contains(&_object3)) + _object3.remove(); + + _globals->_player.setPriority2(1); + _globals->_player.setPosition(Common::Point(144, 55)); + + _object2.postInit(); + _object2.setVisage(2806); + _object2.setStrip(1); + _object2.changeZoom(-1); + _object2.setPosition(Common::Point(158, 55)); + _object2.setPriority2(1); + _object2.setAction(NULL); + _object2.setObjectWrapper(new SceneObjectWrapper()); + _object2.animate(ANIM_MODE_1, NULL); + + setAction(&_action12); + } else if (_globals->_stripNum == 6100) { + _globals->_player.setPosition(Common::Point(157, 56)); + _globals->_player.setPriority2(1); + + _object4.postInit(); + _object4.setVisage(2102); + _object4.setPosition(Common::Point(160, 199)); + _object4.hide(); + + setAction(&_action14); + } else { + _globals->_player.disableControl(); + _globals->_player.setPosition(Common::Point(157, 56)); + _sceneMode = 2104; + + setAction(&_sequenceManager, this, 2104, &_globals->_player, &_object1, NULL); + } + break; + case 3700: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + Scene::setZoomPercents(80, 75, 100, 90); + + if (_globals->_sceneObjects->contains(&_object2)) + _object2.remove(); + + _globals->_player._angle = 225; + _globals->_player.setStrip(6); + _globals->_player.setFrame(1); + _globals->_player.setPriority2(-1); + _globals->_player.setPosition(Common::Point(272, 127)); + + _object3.setPosition(Common::Point(246, 156)); + _object3.setPriority2(156); + _sceneMode = 2105; + setAction(&_sequenceManager, this, 2105, &_object3, NULL); + break; + case 4250: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + _globals->clearFlag(43); + + _globals->_player.setVisage(2104); + _globals->_player.setFrame(1); + _globals->_player.setPosition(Common::Point(65, 149)); + _globals->_player.setPriority2(152); + _globals->_player.setStrip(2); + + _object4.postInit(); + _object4.setVisage(2102); + _object4.setPosition(Common::Point(160, 199)); + _object4.hide(); + + _sceneMode = 2107; + setAction(&_sequenceManager, this, 2107, &_object4, NULL); + break; + case 5000: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + + if (_globals->_sceneObjects->contains(&_object2)) + _object2.remove(); + + _globals->_player.setStrip(3); + _globals->_player.setFrame(1); + _globals->_player.setPriority2(1); + _globals->_player.setPosition(Common::Point(157, 56)); + + _object3.setPosition(Common::Point(246, 156)); + _object3.setPriority2(156); + + setAction(&_action5); + break; + case 5100: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + _globals->_player.setVisage(2104); + _globals->_player.setFrame(1); + _globals->_player.setPosition(Common::Point(65, 149)); + _globals->_player.setPriority2(152); + _globals->_player.setStrip(2); + + _field1800 = 1; + + _object4.postInit(); + _object4.setVisage(2102); + _object4.setPosition(Common::Point(160, 199)); + _object4.hide(); + + _globals->_inventory._stasisBox._sceneNumber = 0; + setAction(&_action9); + break; + case 7000: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + + if (_globals->_inventory._stasisBox2._sceneNumber == 1) { + _globals->_player.setPriority2(1); + _globals->_player.setPosition(Common::Point(157, 56)); + + _object4.postInit(); + _object4.setVisage(2102); + _object4.setPosition(Common::Point(160, 199)); + _object4.hide(); + _globals->clearFlag(15); + _globals->clearFlag(109); + _globals->clearFlag(72); + + setAction(&_action17); + } else { + _globals->_player.setVisage(2104); + _globals->_player.setFrame(1); + _globals->_player.setPosition(Common::Point(65, 149)); + _globals->_player.setPriority2(152); + _globals->_player.setStrip(2); + + _field1800 = 1; + setAction(&_action16); + } + break; + case 7600: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + + if (_globals->_sceneObjects->contains(&_object2)) + _object2.remove(); + + _globals->_player.setPriority2(1); + _globals->_player.setPosition(Common::Point(157, 56)); + + setAction(&_action8); + break; + case 8100: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + + _globals->_player.setVisage(2104); + _globals->_player.setFrame(1); + _globals->_player.setPosition(Common::Point(65, 149)); + _globals->_player.setPriority2(152); + _globals->_player.setStrip(2); + + _sceneMode = 2106; + setAction(&_sequenceManager, this, 2106, NULL); + break; + case 9750: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + + _globals->_player.setVisage(2104); + _globals->_player.setFrame(1); + _globals->_player.setPosition(Common::Point(65, 149)); + _globals->_player.setPriority2(152); + _globals->_player.setStrip(2); + + _object4.postInit(); + _object4.setVisage(2102); + _object4.setPosition(Common::Point(160, 199)); + _object4.hide(); + + _sceneMode = 2103; + setAction(&_sequenceManager, this, 2103, &_object4, NULL); + break; + default: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + + _globals->_player._uiEnabled = true; + break; + } + + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160; +} + +void Scene2100::stripCallback(int v) { + switch (v) { + case 1: + _object4._numFrames = 4; + _object4.animate(ANIM_MODE_7, NULL); + break; + case 2: + _object4.animate(ANIM_MODE_NONE, NULL); + break; + } +} + +void Scene2100::signal() { + switch (_sceneMode) { + case 2101: + _field1800 = 1; + _globals->_player._uiEnabled = true; + _globals->_events.setCursor(CURSOR_USE); + break; + case 2102: + _field1800 = 0; + _globals->_player.enableControl(); + break; + case 2103: + _globals->_stripNum = 9000; + _globals->_sceneManager.changeScene(4000); + break; + case 2106: + _globals->_sceneManager.changeScene(7000); + break; + case 2107: + _globals->_sceneManager.changeScene(5000); + break; + case 2104: + case 2105: + case 2108: + case 2110: + case 2111: + case 2112: + _globals->_player.enableControl(); + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 2120 - Encyclopedia + * + *--------------------------------------------------------------------------*/ + +Scene2120::Action1::Action1() { + _entries.push_back(Entry(0, 0, 0)); + _entries.push_back(Entry(0, 0, 0)); + _entries.push_back(Entry(4, 1, 2123)); + _entries.push_back(Entry(1, 6, 0)); + _entries.push_back(Entry(2, 8, 0)); + _entries.push_back(Entry(1, 11, 0)); + _entries.push_back(Entry(4, 13, 2131)); + _entries.push_back(Entry(2, 18, 0)); + _entries.push_back(Entry(4, 21, 0)); + _entries.push_back(Entry(7, 26, 2128)); + _entries.push_back(Entry(3, 34, 0)); + _entries.push_back(Entry(0, 38, 0)); + _entries.push_back(Entry(3, 39, 2126)); + _entries.push_back(Entry(3, 43, 0)); + _entries.push_back(Entry(4, 47, 2125)); + _entries.push_back(Entry(3, 52, 0)); + _entries.push_back(Entry(4, 56, 2129)); + _entries.push_back(Entry(7, 61, 0)); + _entries.push_back(Entry(2, 69, 2127)); + _entries.push_back(Entry(7, 72, 2122)); + _entries.push_back(Entry(0, 80, 2124)); + _entries.push_back(Entry(0, 81, 0)); + _entries.push_back(Entry(0, 82, 0)); + _entries.push_back(Entry(1, 83, 0)); + _entries.push_back(Entry(2, 85, 2132)); + _entries.push_back(Entry(1, 88, 2133)); + _entries.push_back(Entry(2, 90, 2136)); + _entries.push_back(Entry(1, 93, 0)); + _entries.push_back(Entry(10, 95, 2135)); + _entries.push_back(Entry(5, 106, 0)); + _entries.push_back(Entry(2, 112, 2134)); + _entries.push_back(Entry(1, 115, 2130)); + _entries.push_back(Entry(0, 117, 0)); +} + +void Scene2120::Action1::signal() { + Scene2120 *scene = (Scene2120 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(30); + _globals->_events.setCursor(CURSOR_WALK); + break; + case 1: + // First page of index + SceneItem::display(2120, 0, SET_X, 120, SET_FONT, 1, SET_EXT_BGCOLOUR, 7, SET_BG_COLOUR, -1, + SET_WIDTH, 200, SET_KEEP_ONSCREEN, -1, SET_TEXT_MODE, 0, LIST_END); + break; + case 2: + // Second page of index + SceneItem::display(2120, 1, SET_X, 120, SET_FONT, 1, SET_EXT_BGCOLOUR, 7, SET_BG_COLOUR, -1, + SET_WIDTH, 200, SET_KEEP_ONSCREEN, -1, SET_TEXT_MODE, 0, LIST_END); + break; + case 3: + // Display an image associated with the encyclopedia entry + SceneItem::display(0, 0); + + scene->_visageHotspot.postInit(); + scene->_visageHotspot.setVisage(_entries[scene->_subjectIndex]._visage); + scene->_visageHotspot.setPosition(Common::Point(129, 180)); + scene->_visageHotspot.animate(ANIM_MODE_NONE, NULL); + scene->_visageVisable = true; + break; + case 4: + // Display page of text + SceneItem::display(2121, _entries[scene->_subjectIndex]._lineNum + scene->_lineOffset, + SET_X, 130, SET_FONT, 1, SET_EXT_BGCOLOUR, 7, SET_BG_COLOUR, -1, SET_WIDTH, 200, + SET_KEEP_ONSCREEN, -1, SET_TEXT_MODE, 0, LIST_END); + _actionIndex = 4; + break; + } +} + +void Scene2120::Action1::dispatch() { + Scene2120 *scene = (Scene2120 *)_globals->_sceneManager._scene; + + Event event; + if (_globals->_events.getEvent(event) && (event.eventType == EVENT_BUTTON_DOWN)) { + if (scene->_listRect.contains(event.mousePos) && (scene->_dbMode != 2)) { + scene->_topicArrowHotspot.setPosition(Common::Point(scene->_topicArrowHotspot._position.x, event.mousePos.y)); + } + + // Subject button handling + if (scene->_subjectButton._bounds.contains(event.mousePos) && (scene->_dbMode != 2)) { + scene->_arrowHotspot.setPosition(Common::Point(291, 34)); + scene->_arrowHotspot._strip = 1; + scene->_arrowHotspot.animate(ANIM_MODE_5, NULL); + + if (scene->_dbMode == 0) + scene->_subjectIndex = (scene->_topicArrowHotspot._position.y - 48) / 8; + else + scene->_subjectIndex = (scene->_topicArrowHotspot._position.y - 44) / 8 + 16; + + if ((scene->_subjectIndex == 27) && _globals->getFlag(70)) + _globals->setFlag(75); + + scene->_topicArrowHotspot.hide(); + scene->_prevDbMode = scene->_dbMode; + scene->_dbMode = 2; + scene->_lineOffset = 0; + + _actionIndex = !_entries[scene->_subjectIndex]._visage ? 4 : 3; + setDelay(30); + scene->_soundHandler.startSound(159); + } + + // Next Page button handling + if (scene->_nextPageButton._bounds.contains(event.mousePos)) { + if (!scene->_dbMode) { + scene->_arrowHotspot._strip = 2; + scene->_arrowHotspot.setPosition(Common::Point(291, 76)); + scene->_arrowHotspot.animate(ANIM_MODE_5, NULL); + scene->_dbMode = 1; + + _actionIndex = 2; + setDelay(30); + } + + if ((scene->_dbMode == 2) && (scene->_lineOffset < _entries[scene->_subjectIndex]._size)) { + if (!scene->_visageVisable) { + ++scene->_lineOffset; + } else { + scene->_visageVisable = false; + scene->_visageHotspot.remove(); + } + setDelay(30); + } + + if ((scene->_subjectIndex == 20) && scene->_visageVisable) { + scene->_visageVisable = false; + scene->_visageHotspot.remove(); + setDelay(30); + } + + scene->_soundHandler.startSound(159); + } + + // Previous Page button handling + if (scene->_previousPageButton._bounds.contains(event.mousePos)) { + switch (scene->_dbMode) { + case 1: + scene->_arrowHotspot._strip = 3; + scene->_arrowHotspot.setPosition(Common::Point(291, 117)); + scene->_arrowHotspot.animate(ANIM_MODE_5, NULL); + + scene->_dbMode = 0; + _actionIndex = 1; + setDelay(30); + break; + case 2: + if (scene->_lineOffset > 0) { + --scene->_lineOffset; + setDelay(20); + } + if ((_entries[scene->_subjectIndex]._visage != 0) && (scene->_lineOffset == 0)) { + _actionIndex = 3; + setDelay(30); + } + break; + } + + scene->_soundHandler.startSound(159); + } + + // Exit button handling + if (scene->_exitButton._bounds.contains(event.mousePos)) { + if (scene->_dbMode != 2) { + // In the index, so return to the previous scene + setAction(NULL); + SceneItem::display(0, 0); + + _globals->_gfxManagerInstance._font.setFontNumber(2); + _globals->_sceneText._fontNumber = 2; + _globals->_sceneManager.changeScene(_globals->_sceneManager._previousScene); + } else { + // Exit out of topic display to index + SceneItem::display(0, 0); + + if (_entries[scene->_subjectIndex]._visage) + scene->_visageHotspot.remove(); + + scene->_arrowHotspot._strip = 4; + scene->_arrowHotspot.setPosition(Common::Point(291, 159)); + scene->_arrowHotspot.animate(ANIM_MODE_5, NULL); + scene->_dbMode = scene->_prevDbMode; + _actionIndex = scene->_prevDbMode + 1; + + scene->_topicArrowHotspot.show(); + setDelay(1); + } + + scene->_soundHandler.startSound(159); + } + } + + Action::dispatch(); +} + +/*--------------------------------------------------------------------------*/ + +void Scene2120::postInit(SceneObjectList *OwnerList) { + loadScene(2120); + setZoomPercents(0, 100, 200, 100); + _globals->_player.disableControl(); + + _listRect = Rect(18, 48, 260, 177); + _subjectButton.setBounds(Rect(266, 13, 320, 56)); + _nextPageButton.setBounds(Rect(266, 56, 320, 98)); + _previousPageButton.setBounds(Rect(266, 98, 320, 140)); + _exitButton.setBounds(Rect(266, 140, 320, 182)); + + _topicArrowHotspot.postInit(); + _topicArrowHotspot.setVisage(2120); + _topicArrowHotspot.animate(ANIM_MODE_NONE, NULL); + _topicArrowHotspot.setPosition(Common::Point(240, 55)); + + _arrowHotspot.postInit(); + _arrowHotspot.setVisage(2121); + _arrowHotspot.animate(ANIM_MODE_NONE, NULL); + _arrowHotspot._frame = 1; + _arrowHotspot.setPosition(Common::Point(400, 200)); + + _dbMode = 0; + _prevDbMode = 0; + _visageVisable = false; + _subjectIndex = 0; + + setAction(&_action1); + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160; +} + +void Scene2120::synchronise(Serialiser &s) { + Scene::synchronise(s); + + s.syncAsSint16LE(_dbMode); + s.syncAsSint16LE(_prevDbMode); + s.syncAsSint16LE(_visageVisable); + s.syncAsSint16LE(_subjectIndex); + s.syncAsSint16LE(_lineOffset); +} + +/*-------------------------------------------------------------------------- + * Scene 2150 - Starcraft Level 2 + * + *--------------------------------------------------------------------------*/ + +void Scene2150::Action1::signal() { + Scene2150 *scene = (Scene2150 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + _globals->_player.disableControl(); + Common::Point pt(158, 103); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 1: + scene->_soundHandler.startSound(162); + scene->_hotspot1.animate(ANIM_MODE_5, this); + break; + case 2: { + _globals->_player.setStrip2(4); + Common::Point pt(158, 95); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 3: + _globals->_player.setStrip2(-1); + _globals->_player._strip = 3; + setDelay(10); + break; + case 4: + scene->_area1.display(); + scene->_area2.display(); + scene->_area3.display(); + scene->_area4.display(); + + scene->_area2.draw(true); + _state = 0; + _globals->_events.setCursor(CURSOR_USE); + + while (!_state && !_vm->getEventManager()->shouldQuit()) { + // Wait for an event + Event event; + if (!_globals->_events.getEvent(event)) { + g_system->updateScreen(); + g_system->delayMillis(10); + continue; + } + + if (scene->_area1._bounds.contains(event.mousePos)) { + scene->_area2.draw(false); + scene->_area1.draw(true); + _state = scene->_area1._actionId; + } + if (scene->_area2._bounds.contains(event.mousePos)) { + scene->_area2.draw(true); + _state = scene->_area2._actionId; + } + if (scene->_area3._bounds.contains(event.mousePos)) { + scene->_area2.draw(false); + scene->_area3.draw(true); + _state = scene->_area3._actionId; + } + } + + scene->_soundHandler.startSound(161); + scene->_area1.restore(); + scene->_area2.restore(); + scene->_area3.restore(); + scene->_area4.restore(); + + if (_state == 2150) { + setDelay(1); + } else { + scene->_soundHandler.startSound(162); + scene->_hotspot1.animate(ANIM_MODE_6, this); + } + break; + case 5: + if (_state == 2150) { + Common::Point pt(158, 103); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } else { + _globals->_sceneManager.changeScene(_state); + } + break; + case 6: + scene->_soundHandler.startSound(162); + scene->_hotspot1.animate(ANIM_MODE_6, this); + break; + case 7: + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene2150::Action2::signal() { + Scene2150 *scene = (Scene2150 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + _globals->_player.disableControl(); + Common::Point pt(47, 85); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 1: + _globals->_player.setVisage(2152); + _globals->_player.setFrame(1); + _globals->_player.setStrip(8); + _globals->_player.animate(ANIM_MODE_8, 1, this); + + scene->_soundHandler.startSound(163); + break; + case 2: + scene->_soundHandler.startSound(164); + scene->_hotspot10.animate(ANIM_MODE_5, this); + break; + case 3: + _globals->_events.setCursor(CURSOR_WALK); + scene->_stripManager.start((_globals->_inventory._ale._sceneNumber == 2150) ? 2151 : 2152, this); + break; + case 4: + scene->_hotspot14.postInit(); + scene->_hotspot14.setVisage(2152); + scene->_hotspot14.setStrip(6); + scene->_hotspot14.setPosition(Common::Point(59, 54)); + + if (scene->_stripManager._field2E8 == 15) { + scene->_hotspot14.setFrame(5); + _globals->_inventory._ale._sceneNumber = 1; + } else { + scene->_hotspot14.setFrame(scene->_stripManager._field2E8 - 5); + } + + _globals->_player.setFrame(1); + _globals->_player.setStrip(7); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 5: + scene->_soundHandler.startSound(164); + scene->_hotspot10.animate(ANIM_MODE_6, NULL); + scene->_hotspot14.remove(); + + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 6: + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.enableControl(); + + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene2150::Hotspot1::doAction(int action) { + Scene2150 *scene = (Scene2150 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2150, 0); + break; + case CURSOR_USE: + scene->setAction(&scene->_action1); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2150::Hotspot2::doAction(int action) { + Scene2150 *scene = (Scene2150 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2150, 1); + break; + case CURSOR_USE: + _globals->_player.disableControl(); + scene->_sceneMode = 2156; + scene->setAction(&scene->_sequenceManager, scene, 2156, &_globals->_player, this, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2150::Hotspot4::doAction(int action) { + Scene2150 *scene = (Scene2150 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2150, 3); + break; + case CURSOR_USE: + _globals->_player.disableControl(); + scene->_sceneMode = 2155; + scene->setAction(&scene->_sequenceManager, scene, 2155, &_globals->_player, &scene->_hotspot4, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2150::Hotspot7::doAction(int action) { + Scene2150 *scene = (Scene2150 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2150, 7); + break; + case CURSOR_USE: + if (_globals->getFlag(13)) + SceneItem::display2(2150, 19); + else { + _globals->_player.disableControl(); + scene->_sceneMode = 2154; + scene->setAction(&scene->_sequenceManager, scene, 2154, &_globals->_player, NULL); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2150::Hotspot10::doAction(int action) { + Scene2150 *scene = (Scene2150 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2150, 10); + break; + case CURSOR_USE: + if (_globals->getFlag(13)) + SceneItem::display2(2150, 19); + else + scene->setAction(&scene->_action2); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene2150::Scene2150(): + _hotspot3(18, CURSOR_LOOK, 2150, 2, CURSOR_USE, 2150, 18, LIST_END), + _hotspot5(17, CURSOR_LOOK, 2150, 4, CURSOR_USE, 2150, 18, LIST_END), + _hotspot6(0, CURSOR_LOOK, 2150, 5, CURSOR_USE, 2150, 18, LIST_END), + _hotspot8(16, CURSOR_LOOK, 2150, 8, LIST_END), + _hotspot9(0, CURSOR_LOOK, 2150, 9, CURSOR_USE, 2150, 13, LIST_END), + _hotspot11(0, CURSOR_LOOK, 2150, 12, LIST_END) { +} + +void Scene2150::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(55, 85, 200, 100); + loadScene(2150); + + _stripManager.addSpeaker(&_speakerGameText); + + _hotspot7.postInit(); + _hotspot7.setVisage(2152); + _hotspot7._frame = 1; + _hotspot7._strip = 2; + _hotspot7.animate(ANIM_MODE_8, NULL); + _hotspot7.setPosition(Common::Point(122, 62)); + _hotspot7.changeZoom(100); + _hotspot7.setPriority2(76); + + _hotspot2.postInit(); + _hotspot2.setVisage(2151); + _hotspot2._frame = 1; + _hotspot2._strip = 3; + _hotspot2.animate(ANIM_MODE_NONE, NULL); + _hotspot2.setPosition(Common::Point(257, 67)); + _hotspot2.changeZoom(100); + _hotspot2.setPriority2(60); + + _hotspot1.postInit(); + _hotspot1.setVisage(2151); + _hotspot1._frame = 1; + _hotspot1._strip = 2; + _hotspot1.animate(ANIM_MODE_NONE, NULL); + _hotspot1.setPosition(Common::Point(158, 99)); + _hotspot1.changeZoom(100); + _hotspot1.setPriority2(99); + + _hotspot4.postInit(); + _hotspot4.setVisage(2150); + _hotspot4._frame = 1; + _hotspot4._strip = 2; + _hotspot4.animate(ANIM_MODE_NONE, NULL); + _hotspot4.setPosition(Common::Point(218, 200)); + _hotspot4.changeZoom(100); + _hotspot4.setPriority2(200); + + _hotspot10.postInit(); + _hotspot10.setVisage(2152); + _hotspot10.setStrip(5); + _hotspot10.setPosition(Common::Point(59, 56)); + + _rect1 = Rect(260, 70, 270, 77); + _rect2 = Rect(222, 142, 252, 150); + + _globals->_player.postInit(); + _globals->_player.setVisage(_globals->getFlag(13) ? 2170 : 0); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setPriority2(-1); + _globals->_player.changeZoom(-1); + _globals->_player._moveDiff.y = 3; + + _hotspot8.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + _hotspot9.setBounds(Rect(133, 0, 198, 91)); + _hotspot11.setBounds(Rect(142, 119, 176, 158)); + + _globals->_sceneItems.addItems(&_hotspot1, &_hotspot2, &_hotspot3, &_hotspot4, &_hotspot5, + &_hotspot6, &_hotspot7, &_hotspot10, &_hotspot9, &_hotspot11, &_hotspot8, NULL); + + _area1.setup(2153, 2, 1, 2100); + _area1._pt = Common::Point(200, 31); + _area2.setup(2153, 3, 1, 2150); + _area2._pt = Common::Point(200, 50); + _area3.setup(2153, 4, 1, 2320); + _area3._pt = Common::Point(200, 75); + _area4.setup(2153, 1, 1, 10); + _area4._pt = Common::Point(237, 77); + + switch (_globals->_sceneManager._previousScene) { + case 2120: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + _globals->_player.setPosition(Common::Point(108, 99)); + break; + case 2200: + _globals->_player.disableControl(); + _globals->_player.setPosition(Common::Point(159, 240)); + _sceneMode = 2152; + setAction(&_sequenceManager, this, 2152, &_globals->_player, NULL); + break; + case 2280: + _globals->_player.disableControl(); + _globals->_player._angle = 180; + _globals->_player.setPosition(Common::Point(265, 80)); + + _hotspot2._frame = _hotspot2.getFrameCount(); + _sceneMode = 2157; + setAction(&_sequenceManager, this, 2157, &_hotspot2, NULL); + break; + case 2230: + _globals->_events.setCursor(CURSOR_WALK); + _globals->_player._strip = 4; + _globals->_player.setPosition(Common::Point(229, 139)); + break; + case 2100: + default: + _globals->_player.disableControl(); + _globals->_player.setPosition(Common::Point(158, 95)); + _globals->_player.setStrip(3); + _sceneMode = 2151; + + setAction(&_sequenceManager, this, 2151, &_globals->_player, &_hotspot1, NULL); + break; + } + + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160; +} + +void Scene2150::synchronise(Serialiser &s) { + Scene::synchronise(s); + _rect1.synchronise(s); + _rect2.synchronise(s); +} + +void Scene2150::signal() { + switch (_sceneMode) { + case 2151: + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.enableControl(); + break; + case 2152: + case 2153: + case 2157: + _globals->_player.enableControl(); + break; + case 2154: + _globals->_sceneManager.changeScene(2120); + break; + case 2155: + _globals->_sceneManager.changeScene(2230); + break; + case 2156: + _globals->_sceneManager.changeScene(2280); + break; + } +} + +void Scene2150::dispatch() { + Scene::dispatch(); + + if (!_action) { + if (_rect1.contains(_globals->_player._position)) { + _globals->_player.disableControl(); + _sceneMode = 2156; + setAction(&_sequenceManager, this, 2156, &_globals->_player, &_hotspot2, NULL); + } + if (_rect2.contains(_globals->_player._position)) { + _globals->_player.disableControl(); + _sceneMode = 2155; + setAction(&_sequenceManager, this, 2155, &_globals->_player, &_hotspot4, NULL); + } + if (_globals->_player._position.y >= 196) { + _globals->_player.disableControl(); + SceneItem::display2(2150, 20); + + _sceneMode = 2153; + setAction(&_sequenceManager, this, 2153, &_globals->_player, NULL); + } + } +} + +/*-------------------------------------------------------------------------- + * Scene 2200 - Starcraft - AutoDoc + * + *--------------------------------------------------------------------------*/ + +void Scene2200::Action1::signal() { + Scene2200 *scene = (Scene2200 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(6); + break; + case 1: + scene->_hotspot4.animate(ANIM_MODE_5, this); + break; + case 2: + SceneItem::display2(2200, 7); + _globals->_sceneManager.changeScene(2150); + remove(); + break; + } +} + +void Scene2200::Action2::signal() { + Scene2200 *scene = (Scene2200 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(3); + break; + case 1: + setDelay(30); + break; + case 2: + scene->_hotspot4.animate(ANIM_MODE_5, this); + break; + case 3: + scene->_hotspot4.setStrip(4); + setDelay(30); + break; + case 4: + _globals->_events.setCursor(CURSOR_WALK); + scene->_stripManager.start(2040, this, scene); + break; + case 5: + scene->_hotspot4.setStrip(4); + scene->_hotspot4.animate(ANIM_MODE_NONE, NULL); + _globals->_player._uiEnabled = true; + remove(); + break; + } +} + +void Scene2200::Action3::signal() { + Scene2200 *scene = (Scene2200 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + scene->_soundHandler2.startSound(103); + + scene->_hotspot4.setStrip(4); + scene->_hotspot4.animate(ANIM_MODE_NONE, NULL); + _globals->_player.disableControl(); + + scene->_hotspot2.postInit(); + scene->_hotspot2.setVisage(2201); + scene->_hotspot2._strip = 2; + scene->_hotspot2.setPosition(Common::Point(218, 0)); + + Common::Point pt(218, 63); + NpcMover *mover = new NpcMover(); + scene->_hotspot2.addMover(mover, &pt, this); + break; + } + case 1: + scene->_soundHandler2.startSound(104); + scene->_hotspot4.setStrip(2); + scene->_hotspot4.setFrame(2); + setDelay(120); + break; + case 2: + if (_globals->getFlag(83)) { + _actionIndex = 8; + setDelay(5); + } else { + for (List<SceneObject *>::iterator i = _globals->_sceneObjects->begin(); + i != _globals->_sceneObjects->end(); ++i) { + (*i)->hide(); + } + + _globals->_sceneManager._scene->loadScene(66); + + scene->_hotspot6.postInit(); + scene->_hotspot6.setVisage(66); + scene->_hotspot6.setPosition(Common::Point(160, 197)); + + scene->_hotspot7.postInit(); + scene->_hotspot7.setVisage(65); + scene->_hotspot7.setStrip(4); + scene->_hotspot7.setFrame(1); + scene->_hotspot7.setPosition(Common::Point(145, 165)); + + SceneItem::display(60, 1, SET_Y, 40, SET_X, 25, SET_FONT, 75, SET_BG_COLOUR, -1, SET_FG_COLOUR, 34, + SET_POS_MODE, 0, SET_WIDTH, 280, SET_KEEP_ONSCREEN, 1, LIST_END); + _state = 1; + setDelay(1800); + } + break; + case 3: + case 4: + case 5: + SceneItem::display(60, _actionIndex - 2, SET_Y, 40, SET_X, 25, SET_FONT, 75, SET_BG_COLOUR, -1, SET_FG_COLOUR, 34, + SET_POS_MODE, 0, SET_WIDTH, 280, SET_KEEP_ONSCREEN, 1, LIST_END); + setDelay(1800); + break; + case 6: + scene->_hotspot7.remove(); + SceneItem::display(0, 0); + _state = 0; + setDelay(5); + break; + case 7: + for (List<SceneObject *>::iterator i = _globals->_sceneObjects->begin(); + i != _globals->_sceneObjects->end(); ++i) + (*i)->show(); + + scene->_hotspot6.remove(); + _globals->_sceneManager._scene->loadScene(2200); + setDelay(5); + break; + case 8: + scene->_stripManager.start(2060, this, scene); + break; + case 9: + scene->_hotspot4.setStrip(4); + scene->_hotspot4.animate(ANIM_MODE_NONE, NULL); + break; + case 10: + _globals->_sceneManager.changeScene(2000); + remove(); + break; + } +} + +void Scene2200::Action3::process(Event &event) { + if (!event.handled && ((event.eventType == EVENT_KEYPRESS) || (event.eventType == EVENT_BUTTON_DOWN))) { + _state = 0; + event.handled = true; + setDelay(1); + } + + Action::process(event); +} + +void Scene2200::Action4::signal() { + Scene2200 *scene = (Scene2200 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(5); + break; + case 1: + scene->_stripManager.start(2202, this, scene); + break; + case 2: + scene->_hotspot4.setStrip(4); + scene->_hotspot4.animate(ANIM_MODE_NONE, NULL); + setDelay(10); + break; + case 3: + _globals->_player._uiEnabled = true; + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene2200::Hotspot3::doAction(int action) { + Scene2200 *scene = (Scene2200 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2200, 10); + break; + case CURSOR_USE: + SceneItem::display2(2200, 11); + break; + case CURSOR_TALK: + _globals->_player._uiEnabled = false; + scene->setAction(&scene->_action4); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2200::Hotspot5::doAction(int action) { + Scene2200 *scene = (Scene2200 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2200, 8); + break; + case CURSOR_USE: + SceneItem::display2(2200, 9); + break; + case CURSOR_TALK: + scene->_sceneMode = 2201; + _globals->_player._uiEnabled = false; + scene->setAction(&scene->_sequenceManager, scene, 2201, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2200::Hotspot9::doAction(int action) { + Scene2200 *scene = (Scene2200 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2200, _globals->getFlag(8) ? 1 : 0); + break; + case CURSOR_USE: + SceneItem::display2(2200, 3); + break; + case OBJECT_INFODISK: + if (_globals->_sceneManager._previousScene == 2310) { + scene->_soundHandler2.startSound(35); + _globals->_player.disableControl(); + scene->setAction(&scene->_action3); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + + +Scene2200::Scene2200(): + _hotspot1(0, CURSOR_LOOK, 2200, 5, CURSOR_USE, 2200, 6, LIST_END), + _hotspot10(0, CURSOR_LOOK, 2200, 4, LIST_END) { +} + +void Scene2200::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(0, 200, 200, 200); + loadScene(2200); + + _stripManager.addSpeaker(&_speakerMText); + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerSL); + _stripManager.addSpeaker(&_speakerQR); + _stripManager.addSpeaker(&_speakerQL); + _stripManager.addSpeaker(&_speakerMR); + _stripManager.addSpeaker(&_speakerGameText); + + _speakerQText._npc = &_globals->_player; + _speakerSText._npc = &_hotspot5; + _speakerMText._npc = &_hotspot3; + + _stripManager.setCallback(this); + + _hotspot5.postInit(); + _hotspot5.setVisage(2840); + _hotspot5.setPosition(Common::Point(50, 235)); + + _hotspot8.postInit(); + _hotspot8.setVisage(2840); + _hotspot8.setStrip(2); + _hotspot8.setPosition(Common::Point(96, 184)); + _hotspot8.setPriority2(236); + + _globals->_player.postInit(); + _globals->_player.setVisage(2640); + _globals->_player.setFrame2(3); + _globals->_player.setPosition(Common::Point(110, 233)); + _globals->_player.disableControl(); + + switch (_globals->_sceneManager._previousScene) { + case 2150: + _hotspot5.remove(); + _hotspot8.remove(); + break; + case 4000: + _globals->_soundHandler.startSound(100); + _globals->_soundHandler.proc5(true); + _globals->_player.remove(); + _hotspot5.remove(); + _hotspot8.remove(); + + _hotspot1.postInit(); + _hotspot1.setVisage(2202); + _hotspot1.setPosition(Common::Point(175, 173)); + _hotspot1.setPriority2(99); + + _hotspot3.postInit(); + _hotspot3.setVisage(2202); + _hotspot3._strip = 2; + _hotspot3.setPosition(Common::Point(152, 76)); + _hotspot3.setPriority2(100); + + _hotspot4.postInit(); + _hotspot4.setVisage(2202); + _hotspot4._strip = 3; + _hotspot4.setPosition(Common::Point(115, 76)); + _hotspot4.setPriority2(200); + + setAction(&_action1); + break; + case 2310: + default: + _globals->_inventory._infoDisk._sceneNumber = 1; + + _hotspot3.postInit(); + _hotspot3.setVisage(2215); + _hotspot3.setPosition(Common::Point(144, 132)); + _globals->_sceneItems.push_back(&_hotspot3); + + _hotspot4.postInit(); + _hotspot4.setVisage(2215); + _hotspot4._strip = 2; + _hotspot4.setPosition(Common::Point(120, 78)); + _hotspot4.setPriority2(255); + _globals->_sceneItems.push_back(&_hotspot4); + + _soundHandler1.startSound(101); + _soundHandler2.startSound(100); + _globals->_soundHandler.proc5(true); + + _globals->_sceneItems.push_back(&_hotspot5); + setAction(&_action2); + break; + } + + _exitRect = Rect(0, 0, 35, SCREEN_HEIGHT); + _hotspot9.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + _hotspot10.setBounds(Rect(87, 43, 149, 109)); + + _globals->_sceneItems.addItems(&_hotspot10, &_hotspot9, NULL); + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160; +} + +void Scene2200::stripCallback(int v) { + switch (v) { + case 1: + _hotspot4.setStrip(3); + _hotspot4.animate(ANIM_MODE_7, 0, NULL); + break; + case 2: + _hotspot4.setStrip(4); + _hotspot4.animate(ANIM_MODE_NONE, NULL); + break; + } +} + +void Scene2200::synchronise(Serialiser &s) { + Scene::synchronise(s); + _exitRect.synchronise(s); +} + +void Scene2200::signal() { + if ((_sceneMode == 2201) || (_sceneMode == 2202)) + _globals->_player._uiEnabled = true; +} + +void Scene2200::dispatch() { + Scene::dispatch(); + + if (!_action) { + if (_exitRect.contains(_globals->_player._position)) + _globals->_sceneManager.changeScene(2150); + } +} + +/*-------------------------------------------------------------------------- + * Scene 2222 - Stasis Field Map + * + *--------------------------------------------------------------------------*/ + +void Scene2222::Action1::signal() { + Scene2222 *scene = (Scene2222 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(5); + break; + case 1: + scene->_stripManager.start(2222, this); + break; + case 2: + setDelay(30); + break; + case 3: + _globals->_sceneManager.changeScene(1000); + break; + } +} + +void Scene2222::Action2::signal() { + Scene2222 *scene = (Scene2222 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(60); + break; + case 1: + scene->_stripManager.start(5700, this); + break; + case 2: + setDelay(120); + break; + case 3: + _globals->_sceneManager._fadeMode = FADEMODE_GRADUAL; + _globals->_sceneManager.changeScene(2100); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene2222::postInit(SceneObjectList *OwnerList) { + loadScene((_globals->_sceneManager._previousScene == 2000) ? 3400 : 3450); + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerMText); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerSR); + _stripManager.addSpeaker(&_speakerML); + + _hotspot1.postInit(); + _hotspot1.setVisage(3401); + _hotspot1.setStrip2(1); + _hotspot1._frame = 1; + _hotspot1.animate(ANIM_MODE_2, 0); + + _hotspot2.postInit(); + _hotspot2.setVisage(3401); + _hotspot2.setStrip2(2); + _hotspot2._frame = 2; + _hotspot2.animate(ANIM_MODE_2, 0); + + _hotspot3.postInit(); + _hotspot3.setVisage(3401); + _hotspot3.setStrip2(2); + _hotspot3._frame = 3; + _hotspot3.animate(ANIM_MODE_2, 0); + + _hotspot4.postInit(); + _hotspot4.setVisage(3401); + _hotspot4.setStrip2(2); + _hotspot4._frame = 4; + _hotspot4.animate(ANIM_MODE_2, 0); + + _hotspot5.postInit(); + _hotspot5.setVisage(3401); + _hotspot5.setStrip2(2); + _hotspot5._frame = 5; + _hotspot5.animate(ANIM_MODE_2, 0); + + if (_globals->_sceneManager._previousScene == 2100) { + _hotspot1.setPosition(Common::Point(61, 101)); + _hotspot2.setPosition(Common::Point(239, 149)); + _hotspot3.setPosition(Common::Point(184, 85)); + _hotspot4.setPosition(Common::Point(105, 165)); + _hotspot5.remove(); + + setAction(&_action2); + } else { + _hotspot1.setPosition(Common::Point(110, 108)); + _hotspot2.setPosition(Common::Point(175, 136)); + _hotspot3.setPosition(Common::Point(162, 96)); + _hotspot4.setPosition(Common::Point(118, 141)); + _hotspot5.setPosition(Common::Point(124, 107)); + + setAction(&_action1); + } + + _soundHandler.startSound(116); + _globals->_sceneManager._scene->_sceneBounds.centre(_hotspot1._position); + + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160; +} + + +/*-------------------------------------------------------------------------- + * Scene 2230 - Starcraft - Quinn's Room + * + *--------------------------------------------------------------------------*/ + +void Scene2230::Action1::signal() { + Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + switch (scene->_field30A) { + case 1: + scene->setAction(&scene->_action3); + break; + case 2: + scene->setAction(&scene->_action6); + break; + default: + setDelay(10); + break; + } + break; + case 1: { + Common::Point pt(84, 74); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 2: + scene->_hotspot1.animate(ANIM_MODE_5, this); + break; + case 3: { + Common::Point pt(63, 60); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 4: + scene->_hotspot1.animate(ANIM_MODE_6, this); + break; + case 5: + _globals->_sceneManager.changeScene(2150); + break; + } +} + +void Scene2230::Action2::signal() { + Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + switch (scene->_field30A) { + case 2: + scene->setAction(&scene->_action6, this); + break; + default: + setDelay(10); + break; + } + break; + case 1: { + _globals->_player.disableControl(); + scene->_field30A = 1; + _globals->_player._regionBitList |= ~0x80; + Common::Point pt(160, 96); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 2: + _globals->_player.setVisage(2235); + _globals->_player.setStrip2(1); + _globals->_player.setPriority2(100); + _globals->_player._frame = 1; + _globals->_player.setPosition(Common::Point(200, 68)); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 3: + scene->_soundHandler.startSound(157); + _globals->_player._moveDiff = Common::Point(1, 1); + _globals->_player.setAction(&scene->_action4); + _globals->_player._uiEnabled = true; + + _globals->_events.setCursor(CURSOR_USE); + remove(); + break; + } +} + +void Scene2230::Action3::signal() { + Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + _globals->_player.setAction(NULL); + _globals->_player._moveDiff = Common::Point(5, 3); + _globals->_player.setStrip2(_globals->_player._strip); + + Common::Point pt(190, 74); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + + scene->_soundHandler.proc3(); + break; + } + case 1: + _globals->_player._strip = 3; + _globals->_player._frame = 1; + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 2: + _globals->_player._regionBitList |= 0x80; + scene->_field30A = 0; + + _globals->_player.setVisage(0); + _globals->_player.setStrip2(-1); + _globals->_player.setPriority2(-1); + _globals->_player.setPosition(Common::Point(164, 96)); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player._canWalk = true; + + _globals->_events.setCursor(CURSOR_USE); + remove(); + } +} + +void Scene2230::Action4::signal() { + switch (_actionIndex++) { + case 0: + Common::Point pt(190 + _globals->_randomSource.getRandomNumber(9), 68); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + _actionIndex = 0; + break; + } +} + +void Scene2230::Action5::signal() { + Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + switch (scene->_field30A) { + case 2: + scene->setAction(&scene->_action3, this); + break; + default: + setDelay(10); + break; + } + break; + case 1: { + _globals->_player.disableControl(); + Common::Point pt(209, 124); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 2: + _globals->_player.setPriority2(1430); + _globals->_player.setVisage(2232); + _globals->_player._strip = 1; + _globals->_player._frame = 1; + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 3: + _globals->_events.setCursor(CURSOR_USE); + _globals->_player._uiEnabled = true; + scene->_field30A = 2; + remove(); + break; + } +} + +void Scene2230::Action6::signal() { + Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player._strip = 2; + _globals->_player._frame = 1; + _globals->_player.setPriority2(-1); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 1: + scene->_field30A = 0; + _globals->_player.setVisage(0); + _globals->_player._strip = 1; + _globals->_player._canWalk = true; + _globals->_player.animate(ANIM_MODE_1, NULL); + remove(); + break; + } +} + +void Scene2230::Action7::signal() { + Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + + switch (scene->_field30A) { + case 1: + scene->setAction(&scene->_action3, this); + break; + case 2: + scene->setAction(&scene->_action6, this); + break; + default: + setDelay(10); + break; + } + break; + case 1: { + Common::Point pt(140, 119); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 2: { + scene->_soundHandler.startSound(158); + scene->_hotspot8.setStrip2(2); + + Common::Point pt(scene->_hotspot8._position.x, 97); + NpcMover *mover = new NpcMover(); + scene->_hotspot8.addMover(mover, &pt, this); + break; + } + case 3: + scene->_hotspot2.postInit(); + scene->_hotspot2.setVisage(2231); + scene->_hotspot2._strip = 3; + scene->_hotspot2.setPosition(Common::Point(166, 116)); + scene->_hotspot2.setPriority2(131); + scene->_hotspot2.animate(ANIM_MODE_5, this); + + scene->_hotspot8._frame = 2; + break; + case 4: + _globals->_sceneItems.push_front(&scene->_hotspot10); + _globals->_sceneItems.push_front(&scene->_hotspot11); + _globals->_sceneItems.push_front(&scene->_hotspot12); + + scene->_hotspot2.remove(); + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene2230::Action8::signal() { + Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + + switch (scene->_field30A) { + case 1: + scene->setAction(&scene->_action3, this); + break; + case 2: + scene->setAction(&scene->_action6, this); + break; + default: + setDelay(10); + break; + } + break; + case 1: { + Common::Point pt(140, 119); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 2: { + _globals->_sceneItems.remove(&scene->_hotspot10); + _globals->_sceneItems.remove(&scene->_hotspot11); + _globals->_sceneItems.remove(&scene->_hotspot12); + + switch (scene->_field30A) { + case 1: + scene->setAction(&scene->_action3, this); + break; + case 2: + scene->setAction(&scene->_action6, this); + break; + default: + setDelay(10); + break; + } + break; + } + case 3: + scene->_hotspot2.postInit(); + scene->_hotspot2.setVisage(2231); + scene->_hotspot2._strip = 3; + scene->_hotspot2._frame = scene->_hotspot2.getFrameCount(); + scene->_hotspot2.setPosition(Common::Point(166, 116)); + scene->_hotspot2.setPriority2(131); + scene->_hotspot2.animate(ANIM_MODE_6, this); + break; + case 4: { + scene->_soundHandler.startSound(158); + scene->_hotspot2.remove(); + scene->_hotspot8._frame = 1; + + Common::Point pt(scene->_hotspot8._position.x, 133); + NpcMover *mover = new NpcMover(); + scene->_hotspot8.addMover(mover, &pt, this); + break; + } + case 5: + scene->_hotspot8.setStrip2(1); + _globals->_player.enableControl(); + + remove(); + break; + } +} + + +/*--------------------------------------------------------------------------*/ + +void Scene2230::Hotspot1::doAction(int action) { + Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2230, 0); + break; + case CURSOR_USE: + scene->setAction(&scene->_action1); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2230::Hotspot3::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(4)) + SceneItem::display2(2230, 1); + else { + SceneItem::display2(2230, 1); + SceneItem::display2(2230, 2); + SceneItem::display2(2230, 3); + _globals->setFlag(4); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2230::Hotspot4::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(30)) + SceneItem::display2(2230, 6); + else if (_globals->getFlag(29)) { + SceneItem::display2(2230, 5); + _globals->setFlag(30); + } else { + SceneItem::display2(2230, 4); + _globals->setFlag(29); + } + break; + case CURSOR_USE: + SceneItem::display2(2230, 7); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2230::Hotspot5::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(5)) + SceneItem::display2(2230, 9); + else { + _globals->setFlag(5); + SceneItem::display2(2230, 8); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2230::Hotspot6::doAction(int action) { + Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(6)) + SceneItem::display2(2230, 11); + else { + _globals->setFlag(6); + SceneItem::display2(2230, 10); + } + break; + case CURSOR_USE: + if (scene->_field30A == 1) + scene->setAction(&scene->_action3); + else if (_globals->getFlag(13)) + SceneItem::display2(2230, 28); + else + scene->setAction(&scene->_action2); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2230::Hotspot7::doAction(int action) { + Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(7)) + SceneItem::display2(2230, 13); + else { + _globals->setFlag(6); + SceneItem::display2(2230, 12); + } + break; + case CURSOR_USE: + if (scene->_field30A == 2) + scene->setAction(&scene->_action6); + else if (_globals->getFlag(13)) + SceneItem::display2(2230, 29); + else + scene->setAction(&scene->_action5); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2230::Hotspot8::doAction(int action) { + Scene2230 *scene = (Scene2230 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + if (scene->_hotspot8._strip == 1) { + if (_globals->getFlag(22)) + SceneItem::display2(2230, 19); + else { + _globals->setFlag(22); + SceneItem::display2(2230, 14); + } + } else { + if (_globals->getFlag(25)) + SceneItem::display2(2230, 21); + else { + _globals->setFlag(25); + SceneItem::display2(2230, 20); + } + } + break; + case CURSOR_USE: + if (scene->_hotspot8._strip == 1) + scene->setAction(&scene->_action7); + else + scene->setAction(&scene->_action8); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2230::Hotspot10::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(26)) + SceneItem::display2(2230, 25); + else { + _globals->setFlag(26); + SceneItem::display2(2230, 24); + } + break; + case CURSOR_USE: + SceneItem::display2(2230, 28); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2230::Hotspot11::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(27)) + SceneItem::display2(2230, 23); + else { + _globals->setFlag(27); + SceneItem::display2(2230, 22); + } + break; + case CURSOR_USE: + SceneItem::display2(2230, 28); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2230::Hotspot12::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(28)) + SceneItem::display2(2230, 27); + else { + _globals->setFlag(28); + SceneItem::display2(2230, 26); + } + break; + case CURSOR_USE: + SceneItem::display2(2230, 28); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene2230::Scene2230(): + _hotspot9(0, CURSOR_LOOK, 2230, 16, CURSOR_USE, 2230, 18, LIST_END) { +} + +void Scene2230::postInit(SceneObjectList *OwnerList) { + loadScene(2230); + Scene::postInit(); + setZoomPercents(75, 80, 120, 100); + + _hotspot1.postInit(); + _hotspot1.setVisage(2230); + _hotspot1._frame = 1; + _hotspot1.animate(ANIM_MODE_NONE, 0); + _hotspot1.setPosition(Common::Point(72, 69)); + _hotspot1.changeZoom(100); + + _hotspot8.postInit(); + _hotspot8.setVisage(2231); + _hotspot8._frame = 1; + _hotspot8.animate(ANIM_MODE_NONE, 0); + _hotspot8.setPosition(Common::Point(164, 133)); + _hotspot8.changeZoom(100); + _hotspot8.setPriority2(129); + + _rect1 = Rect(59, 64, 89, 74); + + _globals->_player.postInit(); + _globals->_player.setVisage(_globals->getFlag(13) ? 2170 : 0); + _globals->_player.animate(ANIM_MODE_1, 0); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setPosition(Common::Point(80, 80)); + _globals->_player._moveDiff.y = 3; + _globals->_player._regionBitList |= 0x80; + _globals->_player.changeZoom(-1); + + _field30A = 0; + _globals->_player.enableControl(); + + _hotspot5.setBounds(Rect(108, 34, 142, 76)); + _hotspot4.setBounds(Rect(92, 14, 106, 57)); + _hotspot6.setBounds(Rect(169, 58, 261, 95)); + _hotspot7.setBounds(Rect(111, 117, 222, 158)); + _hotspot3.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + _hotspot10.setBounds(Rect(170, 96, 176, 106)); + _hotspot11.setBounds(Rect(158, 109, 164, 115)); + _hotspot12.setBounds(Rect(170, 109, 177, 115)); + + _globals->_sceneItems.addItems(&_hotspot8, &_hotspot5, &_hotspot4, &_hotspot6, &_hotspot7, + &_hotspot1, &_hotspot3, NULL); + + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160; +} + +void Scene2230::synchronise(Serialiser &s) { + Scene::synchronise(s); + _rect1.synchronise(s); + s.syncAsSint16LE(_field30A); +} + +void Scene2230::dispatch() { + Scene::dispatch(); + + if (!_action) { + if (_rect1.contains(_globals->_player._position)) + setAction(&_action1); + } +} + +/*-------------------------------------------------------------------------- + * Scene 2280 - Starcraft - Storage Room + * + *--------------------------------------------------------------------------*/ + +void Scene2280::Action1::signal() { + Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + _globals->_player.disableControl(); + Common::Point pt(192, 97); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 1: + scene->_soundHandler.startSound(162); + scene->_hotspot16.animate(ANIM_MODE_5, this); + break; + case 2: { + Common::Point pt(218, 87); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 3: + _globals->_player.setStrip(3); + setDelay(10); + break; + case 4: + _globals->_player.setPriority2(1); + scene->_soundHandler.startSound(162); + scene->_hotspot16.animate(ANIM_MODE_6, this); + break; + case 5: + _globals->_sceneManager.changeScene(7000); + break; + } +} + +void Scene2280::Action2::signal() { + Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + _globals->_player.disableControl(); + Common::Point pt(94, 117); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 1: + scene->_soundHandler.startSound(265); + + _globals->_player.setVisage(2162); + _globals->_player._frame = 1; + _globals->_player._strip = 1; + _globals->_player.animate(ANIM_MODE_5, this); + + scene->_hotspot8.remove(); + scene->_hotspot10.remove(); + break; + case 2: + _globals->_player._frame = 1; + _globals->_player._strip = 2; + _globals->_player.animate(ANIM_MODE_4, 3, 1, this); + break; + case 3: + _globals->_player.animate(ANIM_MODE_5, this); + scene->_hotspot12.remove(); + break; + case 4: + scene->_soundHandler.startSound(266); + _globals->_player.setVisage(2170); + _globals->_player._frame = 1; + _globals->_player._strip = 4; + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player._moveDiff = Common::Point(4, 1); + + _globals->setFlag(13); + SceneItem::display2(2280, 37); + + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene2280::Action3::signal() { + Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + _globals->_player.disableControl(); + Common::Point pt(94, 117); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 1: + scene->_soundHandler.startSound(265); + + _globals->_player.setVisage(2162); + _globals->_player._frame = 6; + _globals->_player._strip = 2; + _globals->_player.animate(ANIM_MODE_4, 3, -1, this); + break; + case 2: + scene->_hotspot12.postInit(); + scene->_hotspot12.setVisage(2280); + scene->_hotspot12._strip = 2; + scene->_hotspot12._frame = 3; + scene->_hotspot12.setPosition(Common::Point(88, 76)); + scene->_hotspot12.setPriority2(1); + + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 3: + _globals->_player._strip = 1; + _globals->_player._frame = 12; + + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 4: + scene->_hotspot8.postInit(); + scene->_hotspot8.setVisage(2280); + scene->_hotspot8._strip = 2; + scene->_hotspot8._frame = 1; + scene->_hotspot8.animate(ANIM_MODE_NONE, NULL); + scene->_hotspot8.setPosition(Common::Point(79, 108)); + scene->_hotspot8.changeZoom(100); + scene->_hotspot8.setPriority2(1); + + scene->_hotspot10.postInit(); + scene->_hotspot10.setVisage(2280); + scene->_hotspot10._strip = 2; + scene->_hotspot10._frame = 2; + scene->_hotspot10.animate(ANIM_MODE_NONE, NULL); + scene->_hotspot10.setPosition(Common::Point(79, 104)); + scene->_hotspot10.changeZoom(100); + scene->_hotspot10.setPriority2(1); + + _globals->clearFlag(13); + + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player._strip = 4; + _globals->_player._moveDiff = Common::Point(3, 5); + + SceneItem::display2(2280, 38); + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene2280::Action4::signal() { + Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + switch (_state) { + case 1: + case 51: { + Common::Point pt(163, 67); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 6: + case 50: { + Common::Point pt(173, 63); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + } + break; + } + case 1: + _globals->_player.setVisage(2161); + _globals->_player._strip = 1; + _globals->_player._frame = 1; + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 2: + switch (_state) { + case 1: + scene->_hotspot18.remove(); + _globals->_inventory._scanner._sceneNumber = 1; + break; + case 6: + scene->_hotspot17.remove(); + _globals->_inventory._medkit._sceneNumber = 1; + break; + case 50: + scene->_hotspot17.postInit(); + scene->_hotspot17.setVisage(2161); + scene->_hotspot17._strip = 2; + scene->_hotspot17._frame = 1; + scene->_hotspot17.animate(ANIM_MODE_NONE, NULL); + scene->_hotspot17.setPosition(Common::Point(162, 39)); + scene->_hotspot17.changeZoom(100); + scene->_hotspot17.setPriority2(1); + + _globals->_inventory._medkit._sceneNumber = 2280; + _globals->_sceneItems.push_front(&scene->_hotspot17); + break; + case 51: + scene->_hotspot18.postInit(); + scene->_hotspot18.setVisage(2161); + scene->_hotspot18._strip = 2; + scene->_hotspot18._frame = 2; + scene->_hotspot18.animate(ANIM_MODE_NONE, NULL); + scene->_hotspot18.setPosition(Common::Point(152, 43)); + scene->_hotspot18.changeZoom(100); + scene->_hotspot18.setPriority2(1); + + _globals->_inventory._scanner._sceneNumber = 2280; + _globals->_sceneItems.push_front(&scene->_hotspot18); + break; + } + + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 3: + _globals->_player.enableControl(); + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player._strip = 2; + + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene2280::Hotspot1::doAction(int action) { + Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(16)) + SceneItem::display2(2280, 22); + else { + _globals->setFlag(16); + SceneItem::display2(2230, 21); + } + break; + case CURSOR_USE: + if (!_globals->getFlag(15)) + SceneItem::display2(2280, 23); + else if (!_globals->getFlag(13)) + SceneItem::display2(2280, 46); + else { + _globals->_player.disableControl(); + scene->setAction(&scene->_action1); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2280::Hotspot2::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(2)) + SceneItem::display2(2280, 1); + else { + _globals->setFlag(2); + SceneItem::display2(2280, 0); + } + break; + case CURSOR_USE: + SceneItem::display2(2280, 2); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2280::Hotspot4::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(21)) + SceneItem::display2(2280, 33); + else { + _globals->setFlag(21); + SceneItem::display2(2280, 32); + } + break; + case CURSOR_USE: + SceneItem::display2(2280, 34); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2280::Hotspot7::doAction(int action) { + Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2280, 24); + break; + case OBJECT_SCANNER: + if (_globals->getFlag(13)) + SceneItem::display2(2280, 43); + else { + _globals->_player.disableControl(); + scene->_action4._state = 51; + _globals->_events.setCursor(CURSOR_WALK); + _globals->_events._currentCursor = CURSOR_700; + scene->setAction(&scene->_action4); + } + break; + case OBJECT_MEDKIT: + if (_globals->getFlag(13)) + SceneItem::display2(2280, 43); + else { + _globals->_player.disableControl(); + scene->_action4._state = 50; + _globals->_events.setCursor(CURSOR_WALK); + _globals->_events._currentCursor = CURSOR_700; + scene->setAction(&scene->_action4); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2280::Hotspot8::doAction(int action) { + Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2280, 3); + break; + case CURSOR_USE: + _globals->_player.disableControl(); + scene->setAction(&scene->_action2); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2280::Hotspot10::doAction(int action) { + Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2280, 4); + break; + case CURSOR_USE: + _globals->_player.disableControl(); + scene->setAction(&scene->_action2); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2280::Hotspot12::doAction(int action) { + Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2280, 11); + break; + case CURSOR_USE: + _globals->_player.disableControl(); + scene->setAction(&scene->_action2); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2280::Hotspot14::doAction(int action) { + Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2280, 3); + break; + case CURSOR_USE: + _globals->_player.disableControl(); + if (_globals->getFlag(13)) + scene->setAction(&scene->_action3); + else + scene->setAction(&scene->_action2); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2280::Hotspot17::doAction(int action) { + Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(18)) + SceneItem::display2(2280, 26); + else { + _globals->setFlag(18); + SceneItem::display2(2280, 25); + } + break; + case CURSOR_USE: + if (_globals->getFlag(13)) + SceneItem::display2(2280, 29); + else { + _globals->_player.disableControl(); + scene->_action4._state = 6; + scene->setAction(&scene->_action4); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2280::Hotspot18::doAction(int action) { + Scene2280 *scene = (Scene2280 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(19)) + SceneItem::display2(2280, 28); + else { + _globals->setFlag(19); + SceneItem::display2(2280, 27); + } + break; + case CURSOR_USE: + if (_globals->getFlag(13)) + SceneItem::display2(2280, 29); + else { + _globals->_player.disableControl(); + scene->_action4._state = 1; + scene->setAction(&scene->_action4); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene2280::Scene2280(): + _hotspot3(0, CURSOR_LOOK, 2280, 30, CURSOR_USE, 31, 0, LIST_END), + _hotspot5(0, CURSOR_LOOK, 2280, 35, CURSOR_USE, 2280, 36, LIST_END), + _hotspot6(0, CURSOR_LOOK, 2280, 19, CURSOR_USE, 2280, 20, LIST_END), + _hotspot9(0, CURSOR_LOOK, 2280, 5, CURSOR_USE, 2280, 6, LIST_END), + _hotspot11(0, CURSOR_LOOK, 2280, 7, CURSOR_USE, 2280, 8, LIST_END), + _hotspot13(0, CURSOR_LOOK, 2280, 9, CURSOR_USE, 2280, 10, LIST_END), + _hotspot15(0, CURSOR_LOOK, 2280, 45, LIST_END), + _hotspot16(0, CURSOR_LOOK, 2280, 16, CURSOR_USE, 2280, 42, LIST_END) { +} + +void Scene2280::postInit(SceneObjectList *OwnerList) { + loadScene(2280); + Scene::postInit(); + setZoomPercents(0, 70, 200, 100); + + _hotspot16.postInit(); + _hotspot16.setVisage(2281); + _hotspot16.setPosition(Common::Point(208, 90)); + _hotspot16.setPriority2(80); + + if (_globals->_inventory._medkit._sceneNumber == 2280) { + _hotspot17.postInit(); + _hotspot17.setVisage(2161); + _hotspot17._strip = 2; + _hotspot17.setPosition(Common::Point(162, 39)); + _hotspot17.setPriority2(1); + + _globals->_sceneItems.push_back(&_hotspot17); + } + + if (_globals->_inventory._scanner._sceneNumber == 2280) { + _hotspot18.postInit(); + _hotspot18.setVisage(2161); + _hotspot18._strip = 2; + _hotspot18._frame = 2; + _hotspot17.setPosition(Common::Point(152, 43)); + _hotspot17.setPriority2(1); + + _globals->_sceneItems.push_back(&_hotspot17); + } + + if (!_globals->getFlag(13)) { + _hotspot8.postInit(); + _hotspot8.setVisage(2280); + _hotspot8._strip = 2; + _hotspot8.setPosition(Common::Point(79, 108)); + _hotspot8.setPriority2(1); + + _hotspot10.postInit(); + _hotspot10.setVisage(2280); + _hotspot10._strip = 2; + _hotspot10._frame = 2; + _hotspot10.setPosition(Common::Point(79, 104)); + _hotspot10.setPriority2(2); + + _hotspot12.postInit(); + _hotspot12.setVisage(2280); + _hotspot12._strip = 2; + _hotspot12._frame = 3; + _hotspot12.setPosition(Common::Point(88, 76)); + _hotspot12.setPriority2(1); + + _globals->_sceneItems.addItems(&_hotspot8, &_hotspot10, &_hotspot12, NULL); + } + + _hotspot14.setBounds(Rect(70, 50, 90, 104)); + + _hotspot9.postInit(); + _hotspot9.setVisage(2280); + _hotspot9.setPosition(Common::Point(104, 96)); + _hotspot9.setPriority2(1); + + _hotspot11.postInit(); + _hotspot11.setVisage(2280); + _hotspot11._frame = 2; + _hotspot11.setPosition(Common::Point(130, 79)); + _hotspot11.setPriority2(1); + + _hotspot13.postInit(); + _hotspot13.setVisage(2280); + _hotspot13._frame = 3; + _hotspot13.setPosition(Common::Point(113, 63)); + _hotspot13.setPriority2(1); + + _hotspot1.setBounds(Rect(225, 70, 234, 80)); + _hotspot2.setBounds(Rect(44, 78, 56, 105)); + _hotspot3.setBounds(Rect(47, 108, 56, 117)); + _hotspot4.setBounds(Rect(56, 78, 69, 101)); + _hotspot5.setBounds(Rect(56, 108, 66, 113)); + _hotspot6.setBounds(Rect(261, 39, 276, 90)); + _hotspot7.setBounds(Rect(142, 19, 174, 38)); + _hotspot15.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + + _exitRect = Rect(145, 180, 195, 195); + + _globals->_player.postInit(); + _globals->_player.setVisage(_globals->getFlag(13) ? 2170 : 0); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setPosition(Common::Point(146, 161)); + _globals->_player.changeZoom(-1); + _globals->_player._moveDiff = Common::Point(4, 3); + + if ((_globals->_sceneManager._previousScene != 7300) && (_globals->_sceneManager._previousScene != 7000)) { + _globals->_player.enableControl(); + } else { + _globals->setFlag(109); + _globals->_player.setPriority2(76); + _globals->_player.disableControl(); + + _sceneMode = 2281; + setAction(&_sequenceManager, this, 2281, &_globals->_player, &_hotspot16, NULL); + + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + } + + _globals->_sceneItems.addItems(&_hotspot13, &_hotspot11, &_hotspot9, &_hotspot14, &_hotspot7, + &_hotspot6, &_hotspot2, &_hotspot3, &_hotspot4, &_hotspot5, &_hotspot1, &_hotspot16, &_hotspot15, NULL); + + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160; +} + +void Scene2280::signal() { + if (_sceneMode == 2281) { + _globals->_player.setPriority2(-1); + _globals->_player.enableControl(); + } +} + +void Scene2280::dispatch() { + Scene::dispatch(); + if (!_action) { + if (_exitRect.contains(_globals->_player._position)) + _globals->_sceneManager.changeScene(2150); + } +} + +void Scene2280::synchronise(Serialiser &s) { + Scene::synchronise(s); + _exitRect.synchronise(s); +} + +/*-------------------------------------------------------------------------- + * Scene 2300 - Starcraft - Hanger Bay + * + *--------------------------------------------------------------------------*/ + +void Scene2300::Action1::signal() { + Scene2300 *scene = (Scene2300 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(10); + break; + case 1: { + Common::Point pt(SCREEN_WIDTH, SCREEN_HEIGHT); + NpcMover *mover = new NpcMover(); + scene->_hotspot2.addMover(mover, &pt, this); + break; + } + case 2: { + scene->_hotspot8.setAction(&scene->_action4); + scene->_soundHandler2.startSound(21); + + Common::Point pt1(95, scene->_hotspot5._position.y); + NpcMover *mover1 = new NpcMover(); + scene->_hotspot5.addMover(mover1, &pt1, this); + + Common::Point pt2(99, scene->_hotspot6._position.y); + NpcMover *mover2 = new NpcMover(); + scene->_hotspot6.addMover(mover2, &pt2, NULL); + break; + } + case 3: + setDelay(2); + _globals->_player._uiEnabled = true; + _globals->_events.setCursor(CURSOR_WALK); + break; + case 4: { + scene->_hotspot5.setVisage(93); + scene->_hotspot6.setVisage(94); + scene->_hotspot5.setStrip(1); + scene->_hotspot6.setStrip(1); + scene->_hotspot5.changeZoom(50); + scene->_hotspot6.changeZoom(50); + scene->_hotspot5._moveDiff.x = 5; + scene->_hotspot6._moveDiff.x = 5; + scene->_hotspot5.animate(ANIM_MODE_1, NULL); + scene->_hotspot6.animate(ANIM_MODE_1, NULL); + + Common::Point pt1(178, 147); + NpcMover *mover1 = new NpcMover(); + scene->_hotspot5.addMover(mover1, &pt1, this); + + Common::Point pt2(170, 145); + NpcMover *mover2 = new NpcMover(); + scene->_hotspot6.addMover(mover2, &pt2, this); + break; + } + case 6: + scene->_soundHandler1.startSound(28); + _globals->_player.disableControl(); + + scene->_hotspot2.setVisage(40); + scene->_hotspot2.setStrip(4); + scene->_hotspot2.setFrame(1); + scene->_hotspot2.animate(ANIM_MODE_5, NULL); + + _globals->_player.setVisage(40); + _globals->_player.setStrip(2); + _globals->_player.setFrame(1); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 7: + _globals->_soundHandler.startSound(77, this); + break; + case 8: + _globals->_game.endGame(2300, 0); + break; + case 9: + if (scene->_hotspot5._mover) + scene->_hotspot5.addMover(NULL); + if (scene->_hotspot6._mover) + scene->_hotspot6.addMover(NULL); + + scene->_hotspot5.animate(ANIM_MODE_NONE, NULL); + scene->_hotspot6.animate(ANIM_MODE_NONE, NULL); + + _globals->_player.disableControl(); + _globals->_player.setVisage(2672); + _globals->_player._strip = 5; + _globals->_player._frame = 1; + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 10: + _globals->_player.setVisage(2674); + _globals->_player._strip = 5; + _globals->_player._frame = 1; + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 11: + scene->_soundHandler1.startSound(28); + + scene->_hotspot5._strip = 2; + scene->_hotspot6._strip = 2; + scene->_hotspot5._frame = 1; + scene->_hotspot6._frame = 1; + scene->_hotspot5.animate(ANIM_MODE_5, NULL); + scene->_hotspot6.animate(ANIM_MODE_5, NULL); + scene->_hotspot5.setPriority2(20); + scene->_hotspot6.setPriority2(20); + + _globals->_player.setVisage(2672); + _globals->_player._strip = 5; + _globals->_player._frame = _globals->_player.getFrameCount(); + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 12: + scene->_soundHandler1.startSound(77); + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setStrip(4); + _globals->_player._uiEnabled = false; + setDelay(60); + break; + case 13: + scene->_stripManager.start(2300, this); + break; + case 14: + setDelay(5); + _actionIndex = 16; + break; + case 15: { + Common::Point pt1(101, 148); + PlayerMover *mover1 = new PlayerMover(); + _globals->_player.addMover(mover1, &pt1, this); + + Common::Point pt2(scene->_hotspot5._position.x + 5, scene->_hotspot5._position.y + 5); + NpcMover *mover2 = new NpcMover(); + scene->_hotspot2.addMover(mover2, &pt2, NULL); + break; + } + case 16: + _globals->_sceneManager.changeScene(2000); + remove(); + break; + } +} + +void Scene2300::Action2::signal() { + Scene2300 *scene = (Scene2300 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(30); + break; + case 1: { + Common::Point pt(153, 135); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 2: + _globals->_events.setCursor(CURSOR_WALK); + scene->_stripManager.start(2030, this); + break; + case 3: + _globals->_player.enableControl(); + setDelay(600); + break; + case 4: { + _globals->_player.disableControl(); + + scene->_hotspot2.postInit(); + scene->_hotspot2.setVisage(2801); + scene->_hotspot2.setPosition(Common::Point(109, 145)); + scene->_hotspot2.changeZoom(50); + scene->_hotspot2.animate(ANIM_MODE_1, NULL); + scene->_hotspot2.setObjectWrapper(new SceneObjectWrapper()); + + Common::Point pt(160, 145); + NpcMover *mover = new NpcMover(); + scene->_hotspot2.addMover(mover, &pt, this); + break; + } + case 5: + scene->_stripManager.start(2032, this); + break; + case 6: + scene->_hotspot2.setVisage(93); + scene->_hotspot2.setStrip(3); + scene->_hotspot2.setFrame(1); + scene->_hotspot2.animate(ANIM_MODE_5, this); + + scene->_soundHandler1.startSound(28); + scene->_soundHandler2.startSound(97); + break; + case 7: + scene->_hotspot7._strip = 2; + scene->_hotspot7._frame = 1; + scene->_hotspot7.animate(ANIM_MODE_7, this); + break; + case 8: + scene->_hotspot2.animate(ANIM_MODE_6, this); + break; + case 9: + scene->_stripManager.start(2035, this); + break; + case 10: + _globals->_sceneManager.changeScene(2310); + break; + } +} + +void Scene2300::Action3::signal() { + Scene2300 *scene = (Scene2300 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + Common::Point pt(153, 135); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 1: + _globals->_player.disableControl(); + _globals->_player.setVisage(2672); + _globals->_player._strip = 2; + _globals->_player._frame = 1; + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 2: + _globals->_player.setVisage(2674); + _globals->_player._strip = 2; + _globals->_player._frame = 1; + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 3: + scene->_soundHandler1.startSound(97); + scene->_soundHandler2.startSound(28); + + scene->_hotspot7._strip = 2; + scene->_hotspot7._frame = 1; + scene->_hotspot7.animate(ANIM_MODE_5, this); + + _globals->_player.setVisage(2672); + _globals->_player._strip = 2; + _globals->_player._frame = _globals->_player.getFrameCount(); + _globals->_player.animate(ANIM_MODE_6, NULL); + break; + case 4: + scene->_soundHandler2.startSound(97); + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setStrip(1); + scene->_stripManager.start(2034, this); + break; + case 5: + setDelay(10); + break; + case 6: + _globals->_sceneManager.changeScene(2310); + break; + } +} + +void Scene2300::Action4::signal() { + Scene2300 *scene = (Scene2300 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->_hotspot8.animate(ANIM_MODE_5, this); + scene->_soundHandler1.startSound(11); + break; + case 1: + scene->_hotspot9.postInit(); + scene->_hotspot9.setVisage(2301); + scene->_hotspot9.setStrip2(2); + scene->_hotspot9.setFrame(3); + scene->_hotspot9.setPosition(Common::Point(273, 199)); + scene->_hotspot9.setPriority2(19); + scene->_hotspot9.animate(ANIM_MODE_5, this); + scene->_soundHandler1.startSound(11); + break; + case 2: + scene->_hotspot8.remove(); + + scene->_hotspot10.postInit(); + scene->_hotspot10.setVisage(2301); + scene->_hotspot10.setStrip(3); + scene->_hotspot10.setFrame(4); + scene->_hotspot10.setPosition(Common::Point(292, 113)); + scene->_hotspot10.animate(ANIM_MODE_5, this); + scene->_soundHandler1.startSound(11); + break; + case 3: + scene->_soundHandler1.startSound(13); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene2300::Hotspot5::doAction(int action) { + Scene2300 *scene = (Scene2300 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_STUNNER: + _globals->_player.disableControl(); + _globals->_player.addMover(NULL); + scene->_action1.setActionIndex(9); + scene->_action1.setDelay(1); + break; + case CURSOR_LOOK: + SceneItem::display2(2300, 3); + break; + case CURSOR_USE: + SceneItem::display2(2300, 4); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2300::Hotspot6::doAction(int action) { + Scene2300 *scene = (Scene2300 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_STUNNER: + scene->setAction(&scene->_action3); + break; + case CURSOR_LOOK: + SceneItem::display2(2300, 2); + break; + case CURSOR_USE: + SceneItem::display2(2300, 21); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene2300::Scene2300(): + _hotspot11(0, CURSOR_LOOK, 2300, 6, CURSOR_USE, 2300, 14, LIST_END), + _hotspot12(0, CURSOR_LOOK, 2300, 5, CURSOR_USE, 2300, 13, LIST_END), + _hotspot13(0, CURSOR_LOOK, 2300, 9, CURSOR_USE, 2300, 20, LIST_END), + _hotspot14(0, CURSOR_LOOK, 2300, 7, CURSOR_USE, 2300, 15, LIST_END), + _hotspot15(0, CURSOR_LOOK, 2300, 1, LIST_END) { +} + +void Scene2300::postInit(SceneObjectList *OwnerList) { + loadScene(2300); + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + _stripManager.addSpeaker(&_speakerSL); + _stripManager.addSpeaker(&_speakerML); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerSText); + + _globals->_inventory._stunner._sceneNumber = 1; + _globals->_inventory._infoDisk._sceneNumber = 1; + + _hotspot8.postInit(); + _hotspot8.setVisage(2301); + _hotspot8.setPosition(Common::Point(288, 74)); + + _globals->_soundHandler.startSound(96); + if (_globals->_sceneManager._previousScene == 2000) { + _hotspot8.remove(); + + _hotspot9.postInit(); + _hotspot9.setVisage(2301); + _hotspot9.setStrip2(2); + _hotspot9._frame = _hotspot9.getFrameCount(); + _hotspot9.setPosition(Common::Point(273, 199)); + _hotspot9.setPriority2(1); + + _hotspot10.postInit(); + _hotspot10.setVisage(2301); + _hotspot10.setStrip(3); + _hotspot10._frame = _hotspot10.getFrameCount(); + _hotspot10.setPosition(Common::Point(292, 113)); + + _globals->_player.postInit(); + _globals->_player.setVisage(0); + _globals->_player.setPosition(Common::Point(109, 139)); + _globals->_player.changeZoom(40); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.disableControl(); + + _hotspot7.postInit(); + _hotspot7.setVisage(2302); + _hotspot7.animate(ANIM_MODE_2, NULL); + _hotspot7.setPosition(Common::Point(229, 125)); + _hotspot7._numFrames = 5; + + _soundHandler1.startSound(95); + _soundHandler2.startSound(96); + _globals->_sceneItems.push_back(&_hotspot7); + + setAction(&_action2); + } else { + _hotspot8._numFrames = 3; + + _hotspot3.postInit(); + _hotspot3.setVisage(2331); + _hotspot3.setStrip(7); + _hotspot3.setPosition(Common::Point(231, 190)); + _hotspot3.changeZoom(40); + + _hotspot2.postInit(); + _hotspot2.setVisage(2801); + _hotspot2.setPosition(Common::Point(269, 195)); + _hotspot2.changeZoom(50); + _hotspot2.animate(ANIM_MODE_1, NULL); + _hotspot2.setObjectWrapper(new SceneObjectWrapper()); + + _hotspot1.postInit(); + _hotspot1.setVisage(2331); + _hotspot1.setStrip(7); + _hotspot1.setPosition(Common::Point(255, 190)); + _hotspot1.changeZoom(40); + + _globals->_player.postInit(); + _globals->_player.setVisage(0); + _globals->_player.setPosition(Common::Point(203, 191)); + _globals->_player.changeZoom(40); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.disableControl(); + + _hotspot5.postInit(); + _hotspot5.setVisage(91); + _hotspot5.setPosition(Common::Point(343, 145)); + _hotspot5._moveDiff = Common::Point(35, 35); + _hotspot5.changeZoom(40); + _hotspot5.setObjectWrapper(new SceneObjectWrapper()); + + _hotspot6.postInit(); + _hotspot6.setVisage(92); + _hotspot6.setPosition(Common::Point(343, 130)); + _hotspot6._moveDiff = Common::Point(35, 35); + _hotspot6.changeZoom(40); + _hotspot6.setObjectWrapper(new SceneObjectWrapper()); + + _globals->_sceneItems.push_back(&_hotspot5); + setAction(&_action1); + } + + _hotspot12._sceneRegionId = 8; + _hotspot11._sceneRegionId = 9; + _hotspot13._sceneRegionId = 10; + _hotspot14._sceneRegionId = 11; + + _hotspot15.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + _globals->_sceneItems.addItems(&_hotspot12, &_hotspot11, &_hotspot13, &_hotspot14, &_hotspot15, NULL); +} + +/*-------------------------------------------------------------------------- + * Scene 2310 - Starcraft - Copy Protection Screen + * + *--------------------------------------------------------------------------*/ + +Scene2310::Scene2310() { + _pageList[0].set(0, 0, 0, 0, 0, 0); + _pageList[1].set(1, 0, 3, 2, 1, 4); + _pageList[2].set(2, 1, 4, 3, 2, 0); + _pageList[3].set(3, 2, 0, 4, 3, 1); + _pageList[4].set(4, 3, 1, 0, 2, 4); + _pageList[5].set(5, 4, 2, 1, 3, 0); + _pageList[6].set(6, 0, 4, 2, 3, 1); + _pageList[7].set(7, 1, 0, 2, 4, 3); + _pageList[8].set(8, 2, 1, 3, 0, 4); + _pageList[9].set(9, 3, 2, 4, 1, 0); + _pageList[10].set(10, 4, 1, 2, 0, 3); + _pageList[11].set(11, 0, 2, 3, 4, 1); + _pageList[12].set(12, 1, 2, 0, 4, 3); + _pageList[13].set(13, 2, 4, 0, 3, 1); + _pageList[14].set(14, 3, 4, 1, 0, 2); + _pageList[15].set(15, 4, 3, 1, 2, 0); + _pageList[16].set(16, 0, 1, 4, 2, 3); + _pageList[17].set(17, 1, 3, 4, 0, 2); + _pageList[18].set(18, 2, 3, 0, 1, 4); + _pageList[19].set(19, 3, 0, 1, 4, 2); + _pageList[20].set(20, 4, 0, 3, 1, 2); +} + +void Scene2310::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + loadScene(2301); + Common::Point pointList[5] = { Common::Point(142, 82), Common::Point(158, 82), Common::Point(174, 82), + Common::Point(190, 82), Common::Point(205, 82) }; + + for (int idx = 0; idx < 5; ++idx) { + _wireList[idx].postInit(); + _wireList[idx].setVisage(2300); + _wireList[idx]._strip = idx + 1; + _wireList[idx]._frame = 1; + _wireList[idx].setPosition(pointList[idx]); + } + + _rectList[0].set(135, 70, 151, 140); + _rectList[1].set(151, 70, 167, 140); + _rectList[2].set(167, 70, 183, 140); + _rectList[3].set(183, 70, 199, 140); + _rectList[4].set(199, 70, 215, 140); + + _globals->_player.disableControl(); + _globals->_events.setCursor(CURSOR_WALK); + + _wireIndex = 5; + _pageIndex = _globals->_randomSource.getRandomNumber(19) + 1; + signal(); +} + +void Scene2310::signal() { + switch (_sceneMode++) { + case 0: { + Common::String fmtString = _vm->_dataManager->getMessage(2300, 22); + Common::String msg = Common::String::format(fmtString.c_str(), _pageList[_pageIndex]._pageNumber); + + _sceneText._width = 280; + _sceneText._textMode = ALIGN_CENTRE; + _sceneText._colour1 = 35; + _sceneText._fontNumber = 2; + _sceneText.setup(msg); + _sceneText.setPriority2(255); + _sceneText.setPosition(Common::Point(30, 20)); + break; + } + case 1: { + Common::String msg = _vm->_dataManager->getMessage(2300, 23); + _sceneText.setup(msg); + _sceneText.setPriority2(255); + _sceneText.setPosition(Common::Point(30, 170)); + + _globals->_sceneObjects->draw(); + _globals->_events.waitForPress(); + + _sceneText.hide(); + _globals->_sceneObjects->draw(); + + _globals->_sceneManager.changeScene(2200); + break; + } + } +} + +void Scene2310::synchronise(Serialiser &s) { + Scene::synchronise(s); + + s.syncAsSint16LE(_wireIndex); + s.syncAsSint16LE(_pageIndex); +} + +void Scene2310::process(Event &event) { + int frameNum = 0; + + if (!event.handled && (event.eventType == EVENT_BUTTON_DOWN)) { + int idx = 0; + while (idx < 5) { + if (_rectList[idx].contains(event.mousePos)) + break; + ++idx; + } + + if (idx < 5) { + // In handled rectangle area + if (_wireIndex == 5) { + // No wire is currently active, so start moving designated wire + _wireIndex = idx; + frameNum = idx + 2; + + if (event.mousePos.y > 105) + idx = findObject(idx); + + if (idx != 5) { + _wireList[idx].hide(); + _globals->_sceneObjects->draw(); + _wireList[idx].setFrame(frameNum); + + _wireList[idx].show(); + _globals->_sceneObjects->draw(); + } + } else { + // End the moving of the currently active wire + _wireList[_wireIndex].setFrame(idx + 2); + _wireIndex = 5; + + // Check if solution has been reached + int idx2 = 0; + do { + int objIndex = findObject(idx2); + if (_pageList[_pageIndex]._connectionList[idx2] != objIndex) + // Mismatch + break; + } while (++idx2 < 5); + + if (idx2 == 5) + // All the entries are correct + signal(); + } + + event.handled = true; + } else if (_wireIndex != 5) { + // Reset the active wire back to unplugged + _wireList[_wireIndex].setFrame(1); + _wireIndex = 5; + } + } +} + +void Scene2310::dispatch() { + if ((_vm->getFeatures() & GF_CD) && !ConfMan.getBool("copy_protection")) { + // CD version of Ringworld has the copy protection disabled + signal(); + } else if (_wireIndex != 5) { + for (int idx = 0; idx < 5; ++idx) { + if (_rectList[idx].contains(_globals->_events._mousePos)) { + _wireList[_wireIndex].setFrame(idx + 2); + return; + } + } + + _wireList[_wireIndex].setFrame(1); + } +} + +int Scene2310::findObject(int objIndex) { + for (int idx = 0; idx < 5; ++idx) { + if (_wireList[idx]._frame == (objIndex + 2)) + return idx; + } + + return 5; +} + +/*-------------------------------------------------------------------------- + * Scene 2320 - Starcraft - Lander Bay + * + *--------------------------------------------------------------------------*/ + +void Scene2320::Action1::signal() { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(10); + if (_globals->_sceneManager._previousScene == 2120) + _actionIndex = 3; + break; + case 1: { + Common::Point pt(513, 144); + NpcMover *mover = new NpcMover(); + scene->_hotspot11.addMover(mover, &pt, this); + break; + } + case 2: { + Common::Point pt(510, 164); + NpcMover *mover = new NpcMover(); + scene->_hotspot11.addMover(mover, &pt, this); + break; + } + case 3: + setAction(&scene->_sequenceManager2, this, 2328, &scene->_hotspot11, NULL); + break; + case 4: + scene->_hotspot11.animate(ANIM_MODE_NONE); + setDelay(120); + _actionIndex = 3; + break; + } +} + +void Scene2320::Action2::signal() { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + scene->_soundHandler.startSound(253); + scene->_hotspot13.setPriority2(99); + + Common::Point pt(scene->_hotspot13._position.x, 200); + NpcMover *mover = new NpcMover(); + scene->_hotspot13.addMover(mover, &pt, this); + break; + } + case 1: + scene->_hotspot13.hide(); + remove(); + break; + } +} + +void Scene2320::Action3::signal() { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + Common::Point pt(320, 86); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 1: + scene->_soundHandler.startSound(162); + scene->_hotspot6.animate(ANIM_MODE_5, this); + break; + case 2: { + Common::Point pt(320, 79); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 3: + scene->_hotspot6.setPriority2(scene->_hotspot6._priority - 1); + _globals->_player._strip = 3; + setDelay(10); + break; + case 4: + scene->_area1.display(); + scene->_area2.display(); + scene->_area3.display(); + scene->_area4.display(); + + scene->_area3.draw(true); + _state = 0; + _globals->_events.setCursor(CURSOR_USE); + + while (!_state && !_vm->getEventManager()->shouldQuit()) { + // Wait for an event + Event event; + if (!_globals->_events.getEvent(event)) { + g_system->updateScreen(); + g_system->delayMillis(10); + continue; + } + + if (scene->_area1._bounds.contains(event.mousePos)) { + scene->_area1.draw(true); + scene->_area3.draw(false); + _state = scene->_area1._actionId; + } + if (scene->_area2._bounds.contains(event.mousePos)) { + scene->_area3.draw(false); + scene->_area2.draw(true); + _state = scene->_area2._actionId; + } + if (scene->_area3._bounds.contains(event.mousePos)) { + scene->_area3.draw(true); + _state = scene->_area3._actionId; + } + } + + scene->_soundHandler.startSound(161); + scene->_area1.restore(); + scene->_area2.restore(); + scene->_area3.restore(); + scene->_area4.restore(); + + if (_state == 2320) { + setDelay(10); + } else { + scene->_soundHandler.startSound(162); + scene->_hotspot6.animate(ANIM_MODE_6, this); + } + break; + case 5: { + if (_state == 2320) + _globals->_player.setPriority2(-1); + else + _globals->_sceneManager.changeScene(_state); + + Common::Point pt(320, 86); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 6: + scene->_soundHandler.startSound(162); + scene->_hotspot6.animate(ANIM_MODE_6, this); + break; + case 7: + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene2320::Action4::signal() { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(3); + break; + case 1: { + Common::Point pt(213, 84); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 2: + case 16: + _globals->_player.setVisage(2109); + _globals->_player.setStrip(2); + _globals->_player.setFrame(1); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 3: + _globals->_player.animate(ANIM_MODE_6, NULL); + scene->setAction(&scene->_action2); + break; + case 4: { + scene->_hotspot16.postInit(); + scene->_hotspot16.setVisage(2331); + scene->_hotspot16.setStrip(3); + scene->_hotspot16.setPriority2(149); + scene->_hotspot16.setPosition(Common::Point(320, 202)); + scene->_hotspot16.show(); + + Common::Point pt(320, 121); + NpcMover *mover = new NpcMover(); + scene->_hotspot16.addMover(mover, &pt, this); + break; + } + case 5: { + scene->_hotspot16.setPriority2(200); + Common::Point pt(320, 180); + NpcMover *mover = new NpcMover(); + scene->_hotspot16.addMover(mover, &pt, this); + break; + } + case 6: { + scene->_hotspot16.setPriority2(-1); + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, NULL); + + Common::Point pt(233, 176); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 7: { + Common::Point pt(291, 194); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 8: + _globals->_player.setStrip(5); + _globals->_player.setFrame(1); + setDelay(13); + break; + case 9: + if (!_globals->getFlag(109)) { + SceneItem::display2(2320, 19); + } else { + _globals->_sceneManager.changeScene(7600); + } + break; + case 10: + if (_globals->getFlag(109)) { + _globals->_soundHandler.startSound(40); + _globals->_soundHandler.proc5(true); + + Common::Point pt(303, 240); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + } else { + setDelay(3); + } + break; + case 11: + if (_globals->getFlag(109)) { + _globals->_sceneManager.changeScene(7600); + } else { + SceneItem::display2(2320, 19); + setDelay(3); + } + break; + case 12: + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 13: + _globals->_player.setVisage(0); + _globals->_player.setPosition(Common::Point(291, 194)); + _globals->_player.setStrip(5); + _globals->_player.setFrame(1); + _globals->_player.animate(ANIM_MODE_1, NULL); + + scene->_hotspot16.show(); + setDelay(3); + break; + case 14: { + Common::Point pt(233, 176); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 15: { + Common::Point pt(213, 85); + PlayerMover *mover = new PlayerMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 17: { + _globals->_player.animate(ANIM_MODE_6, NULL); + scene->_hotspot16.setPriority2(160); + + Common::Point pt(320, 121); + NpcMover *mover = new NpcMover(); + scene->_hotspot16.addMover(mover, &pt, this); + break; + } + case 18: { + Common::Point pt(320, 202); + PlayerMover *mover = new PlayerMover(); + scene->_hotspot16.addMover(mover, &pt, this); + break; + } + case 19: { + scene->_hotspot16.remove(); + scene->_soundHandler.startSound(253); + + scene->_hotspot13.show(); + Common::Point pt(319, 157); + NpcMover *mover = new NpcMover(); + scene->_hotspot13.addMover(mover, &pt, this); + break; + } + case 20: + _globals->_player.enableControl(); + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, NULL); + + scene->_hotspot13.setPriority2(1); + remove(); + break; + } +} + +void Scene2320::Action5::signal() { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + ADD_PLAYER_MOVER(163, 126); + break; + case 1: + ADD_PLAYER_MOVER(165, 132); + break; + case 2: + setDelay(2); + break; + case 3: + if (!_globals->getFlag(59)) + setDelay(10); + else + scene->_stripManager.start(2323, this); + break; + case 4: + _globals->_player.setVisage(2347); + _globals->_player.setStrip(1); + _globals->_player.setFrame(1); + _globals->_player.setPriority2(137); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 5: + _globals->_player.setStrip(2); + _globals->_player.setFrame(1); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 6: + if (_globals->getFlag(72)) + _globals->_sceneManager.changeScene(7000); + else if (_globals->getFlag(59)) + _globals->_sceneManager.changeScene(5000); + else if (!_globals->getFlag(43) || (_globals->_inventory._ale._sceneNumber != 1)) + setDelay(10); + else { + scene->_hotspot11.setAction(NULL); + scene->_hotspot11.setVisage(2705); + scene->_hotspot11.animate(ANIM_MODE_1, NULL); + scene->_hotspot11.setObjectWrapper(new SceneObjectWrapper()); + + Common::Point pt(185, 135); + NpcMover *mover = new NpcMover(); + scene->_hotspot11.addMover(mover, &pt, NULL); + + _globals->clearFlag(53); + scene->_stripManager.start(2325, this); + } + break; + case 7: + setDelay(10); + break; + case 8: + _globals->_sceneManager.changeScene(4000); + break; + } +} + +void Scene2320::Action6::signal() { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(30); + break; + case 1: + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 2: + _globals->_player.setStrip(1); + _globals->_player.setFrame(1); + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 3: + _globals->_player.setVisage(0); + _globals->_player.setStrip(3); + _globals->_player.setPriority2(-1); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.animate(ANIM_MODE_1, NULL); + + setDelay(60); + break; + case 4: + if ((_globals->_sceneManager._previousScene != 4000) || _globals->getFlag(43)) + setDelay(3); + else if (_globals->getFlag(35)) { + _globals->setFlag(43); + scene->_stripManager.start(4200, this); + _globals->setFlag(69); + } else if (_globals->getFlag(36)) { + setDelay(3); + } else { + _globals->setFlag(43); + scene->_stripManager.start(4210, this); + break; + } + break; + case 5: + if (_globals->_sceneObjects->contains(&scene->_hotspot11)) { + scene->_hotspot11.setAction(&scene->_action1); + + if (_globals->_sceneObjects->contains(&scene->_hotspot10)) { + ADD_MOVER(scene->_hotspot10, 491, 160); + } else { + setDelay(60); + } + + _globals->_sceneItems.push_front(&scene->_hotspot11); + } else { + setDelay(3); + } + break; + case 6: + _globals->_events.setCursor(CURSOR_WALK); + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene2320::Action7::signal() { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(30); + break; + case 1: + _globals->_soundHandler.startSound(162); + scene->_hotspot6.animate(ANIM_MODE_5, this); + break; + case 2: + scene->_hotspot10.setPriority2(-1); + ADD_MOVER_NULL(scene->_hotspot10, 321, 94); + scene->_hotspot11.setPriority2(-1); + ADD_MOVER_NULL(scene->_hotspot11, 346, 85); + + _globals->_player.setPriority2(-1); + ADD_MOVER(_globals->_player, 297, 89); + break; + case 3: + ADD_PLAYER_MOVER(462, 182); + break; + case 4: + ADD_MOVER(scene->_hotspot11, 391, 88); + break; + case 5: + ADD_MOVER(scene->_hotspot11, 500, 164); + ADD_MOVER(scene->_hotspot10, 382, 93); + _globals->_player.setStrip(3); + break; + case 6: + ADD_MOVER_NULL(scene->_hotspot10, 491, 160); + ADD_MOVER(_globals->_player, 391, 88); + + _globals->_player.setStrip(1); + _globals->_player.setFrame(1); + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 7: + ADD_PLAYER_MOVER(462, 182); + break; + case 8: + _globals->_player.setStrip(7); + setDelay(15); + break; + case 9: + scene->_stripManager.start(6020, this); + break; + case 10: + setDelay(6); + break; + case 11: + scene->_stripManager.start(6022, this); + break; + case 12: + _globals->_player.enableControl(); + _globals->_inventory._stasisBox._sceneNumber = 2320; + break; + } +} + +void Scene2320::Action8::signal() { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(5); + break; + case 1: + ADD_PLAYER_MOVER(462, 182); + break; + case 2: + _globals->_player.setStrip(7); + setDelay(5); + break; + case 3: + scene->_speakerGameText.setTextPos(Common::Point(_globals->_sceneManager._scene->_sceneBounds.left + 30, 10)); + scene->_stripManager.start(_globals->getFlag(75) ? 6030 : 2320, this); + break; + case 4: + if (_globals->getFlag(75)) + setDelay(3); + else + _globals->_player.enableControl(); + break; + case 5: + _globals->_inventory._stasisBox._sceneNumber = 2320; + scene->_sceneMode = 2326; + scene->_speakerGameText.setTextPos(Common::Point(_globals->_sceneManager._scene->_sceneBounds.left + 30, 10)); + scene->setAction(&scene->_sequenceManager1, scene, 2326, &_globals->_player, &scene->_hotspot11, NULL); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene2320::Hotspot5::doAction(int action) { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2320, 13); + break; + case CURSOR_USE: + if (_globals->getFlag(70)) + SceneItem::display2(2320, 33); + else if (_globals->getFlag(13)) + SceneItem::display2(2320, 18); + else + scene->setAction(&scene->_action5); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2320::Hotspot6::doAction(int action) { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2320, 2); + break; + case CURSOR_USE: + _globals->_player.disableControl(); + scene->setAction(&scene->_action3); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2320::Hotspot8::doAction(int action) { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2320, 23); + break; + case CURSOR_USE: + scene->_sceneMode = 2336; + scene->setAction(&scene->_sequenceManager1, scene, 2336, &_globals->_player, this, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2320::Hotspot10::doAction(int action) { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2320, 26); + break; + case CURSOR_TALK: + _globals->_player.disableControl(); + scene->_sceneMode = 2329; + + if (_globals->getFlag(13)) { + scene->_stripManager.start(2337, scene); + } else if (_globals->getFlag(70)) { + scene->setAction(&scene->_action8); + } else if (_globals->getFlag(109)) { + scene->setAction(&scene->_sequenceManager1, scene, 2337, NULL); + } else if (!_state) { + ++_state; + scene->setAction(&scene->_sequenceManager1, scene, 2334, NULL); + } else { + scene->setAction(&scene->_sequenceManager1, scene, 2335, NULL); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2320::Hotspot11::doAction(int action) { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2320, 25); + break; + case CURSOR_TALK: + _globals->_player.disableControl(); + scene->_sceneMode = 2329; + + if (_globals->getFlag(13)) { + _globals->_player.disableControl(); + scene->_sceneMode = 5000; + scene->_stripManager.start(2336, scene); + } else if (_globals->getFlag(70)) { + scene->setAction(&scene->_action8); + } else { + scene->_sceneMode = 2329; + + if (_globals->_inventory._ale._sceneNumber == 1) { + scene->setAction(&scene->_sequenceManager1, scene, 2329, NULL); + } else if (!_globals->getFlag(110)) { + _globals->setFlag(110); + scene->setAction(&scene->_sequenceManager1, scene, 2330, NULL); + } else if (_globals->_inventory._peg._sceneNumber != 1) { + scene->setAction(&scene->_sequenceManager1, scene, 2331, NULL); + } else if (!_state) { + ++_state; + scene->setAction(&scene->_sequenceManager1, scene, 2332, NULL); + } else { + scene->setAction(&scene->_sequenceManager1, scene, 2333, NULL); + } + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2320::Hotspot12::doAction(int action) { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2320, 5); + break; + case CURSOR_USE: + if (_globals->getFlag(13)) + SceneItem::display2(2320, 24); + else { + _globals->_player.disableControl(); + scene->_sceneMode = 2322; + scene->setAction(&scene->_sequenceManager1, scene, 2322, &_globals->_player, NULL); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2320::Hotspot14::doAction(int action) { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2320, 17); + break; + case CURSOR_USE: + if (_globals->getFlag(24)) { + _globals->clearFlag(24); + _globals->_player.disableControl(); + + scene->_hotspot8.postInit(); + scene->_hotspot8.setVisage(2345); + scene->_hotspot8.setPosition(Common::Point(634, 65)); + scene->_hotspot8.hide(); + + _globals->_sceneItems.push_front(&scene->_hotspot8); + _globals->_inventory._waldos._sceneNumber = 2320; + + scene->_hotspot9.postInit(); + scene->_hotspot9.setVisage(2345); + scene->_hotspot9._strip = 6; + scene->_hotspot9.setPosition(Common::Point(536, 103)); + scene->_hotspot9.setPriority2(200); + scene->_hotspot9.hide(); + + scene->_hotspot16.postInit(); + scene->_hotspot16.setVisage(2345); + scene->_hotspot16.setStrip(8); + scene->_hotspot16.setPosition(Common::Point(536, 103)); + scene->_hotspot16.hide(); + + scene->_sceneMode = 2324; + scene->setAction(&scene->_sequenceManager1, scene, 2324, &_globals->_player, &scene->_hotspot7, + &scene->_hotspot8, &scene->_hotspot9, &scene->_hotspot16, NULL); + } else if (_globals->getFlag(13)) { + SceneItem::display2(2320, 24); + } else if (!_globals->getFlag(76)) { + SceneItem::display2(2320, 28); + } else if (!_globals->_inventory._waldos._sceneNumber) { + SceneItem::display2(2320, 27); + } else { + SceneItem::display2(2320, 29); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene2320::Hotspot15::doAction(int action) { + Scene2320 *scene = (Scene2320 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(2320, 16); + break; + case CURSOR_USE: + if (_globals->getFlag(13)) + SceneItem::display2(2320, 24); + else + scene->setAction(&scene->_action4); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + + +/*--------------------------------------------------------------------------*/ + +Scene2320::Scene2320(): + _hotspot1(0, CURSOR_LOOK, 2320, 0, LIST_END), + _hotspot2(0, CURSOR_LOOK, 2320, 1, LIST_END), + _hotspot3(0, CURSOR_LOOK, 2320, 11, LIST_END), + _hotspot4(0, CURSOR_LOOK, 2320, 14, LIST_END), + _hotspot13(0, CURSOR_LOOK, 2320, 12, LIST_END) +{ +} + +void Scene2320::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(60, 75, 100, 100); + + _stripManager.addSpeaker(&_speakerMR); + _stripManager.addSpeaker(&_speakerML); + _stripManager.addSpeaker(&_speakerMText); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerQL); + _stripManager.addSpeaker(&_speakerQR); + _stripManager.addSpeaker(&_speakerSR); + _stripManager.addSpeaker(&_speakerSL); + _stripManager.addSpeaker(&_speakerSAL); + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerGameText); + + _speakerMText._npc = &_hotspot11; + _speakerQText._npc = &_globals->_player; + _hotspotPtr = &_hotspot10; + + _hotspot6.postInit(); + _hotspot6.setVisage(2321); + _hotspot6.setPosition(Common::Point(320, 67)); + + _hotspot7.postInit(); + _hotspot7.setVisage(2344); + _hotspot7.setPosition(Common::Point(604, 92)); + + _hotspot13.postInit(); + _hotspot13.setVisage(2323); + _hotspot13.setPosition(Common::Point(319, 157)); + _hotspot13.setPriority2(1); + + _hotspot12.postInit(); + _hotspot12.setVisage(2321); + _hotspot12._strip = 4; + _hotspot12.animate(ANIM_MODE_8, 0, NULL); + _hotspot12.setPosition(Common::Point(412, 46)); + + if (_globals->_inventory._waldos._sceneNumber == 2320) { + _hotspot8.postInit(); + _hotspot8.setVisage(2345); + _hotspot8.setStrip(5); + _hotspot8.setFrame(8); + _hotspot8.setPosition(Common::Point(541, 103)); + _hotspot8.setPriority2(201); + + _globals->_sceneItems.push_back(&_hotspot8); + } + + _area1.setup(2100, 2, 1, 2150); + _area1._pt = Common::Point(200, 31); + _area2.setup(2153, 3, 1, 2150); + _area2._pt = Common::Point(200, 50); + _area3.setup(2153, 4, 1, 2320); + _area3._pt = Common::Point(200, 75); + _area4.setup(2153, 1, 1, 10); + _area4._pt = Common::Point(237, 77); + + if (_globals->getFlag(43)) { + _hotspot11.postInit(); + _hotspot11.setVisage(2705); + _hotspot11._strip = 3; + _hotspot11.setPosition(Common::Point(510, 156)); + _hotspot11._state = 0; + _hotspot11.setAction(&_action1); + + _globals->_sceneItems.push_back(&_hotspot11); + } + + _globals->_player.postInit(); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setPosition(Common::Point(320, 79)); + _globals->_player.setPriority2(10); + _globals->_player.changeZoom(-1); + _globals->_player._moveDiff.y = 3; + _globals->_player.disableControl(); + + if (_globals->getFlag(114)) { + _hotspot10.postInit(); + _hotspot10.setVisage(2806); + _hotspot10.setPosition(Common::Point(481, 162)); + _hotspot10.changeZoom(-1); + _hotspot10.setStrip(5); + _hotspot10._state = 0; + + _globals->_sceneItems.push_back(&_hotspot10); + } + + if (_globals->getFlag(70)) { + _hotspot11.postInit(); + _hotspot11.setVisage(2705); + _hotspot11.setPosition(Common::Point(500, 164)); + + _hotspot10.postInit(); + _hotspot10.setVisage(2806); + _hotspot10.setPosition(Common::Point(481, 162)); + _hotspot10.changeZoom(-1); + _hotspot10.setStrip(5); + + _globals->_sceneItems.addItems(&_hotspot11, &_hotspot10, NULL); + } + + switch (_globals->_sceneManager._previousScene) { + case 2120: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + + _globals->_player.setPriority2(-1); + _globals->_player.setPosition(Common::Point(389, 72)); + _globals->_player.enableControl(); + break; + case 4000: + if (!_globals->getFlag(36) && !_globals->getFlag(43)) { + _hotspot11.postInit(); + _hotspot11.setVisage(2705); + _hotspot11.setPosition(Common::Point(178, 118)); + _hotspot11.animate(ANIM_MODE_1, NULL); + } + // Deliberate fall-through + case 4250: + case 5000: + case 7000: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + if ((_globals->_sceneManager._previousScene == 7000) && !_globals->getFlag(80)) + _globals->setFlag(36); + + _globals->_player.disableControl(); + _globals->_player.animate(ANIM_MODE_NONE, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setVisage(2347); + _globals->_player.setStrip(2); + _globals->_player.setFrame(5); + _globals->_player.setPriority2(137); + _globals->_player.setPosition(Common::Point(165, 132)); + + setAction(&_action6); + break; + case 6100: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + + _hotspot8.postInit(); + _hotspot8.setVisage(2345); + _hotspot8.setPosition(Common::Point(634, 65)); + _hotspot8.hide(); + + _sceneMode = 2325; + setAction(&_sequenceManager1, this, 2325, &_globals->_player, &_hotspot6, &_hotspot8, &_hotspot7, NULL); + break; + case 7600: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + _soundHandler.startSound(21); + + _globals->_player.setVisage(2323); + _globals->_player.setStrip(2); + _globals->_player.setFrame(_globals->_player.getFrameCount()); + _globals->_player.setPosition(Common::Point(303, 176)); + _globals->_player.setPriority2(-1); + _globals->_player.disableControl(); + + _hotspot13.setPosition(Common::Point(319, 199)); + + _hotspot16.postInit(); + _hotspot16.setVisage(2331); + _hotspot16._strip = 3; + _hotspot16.setPriority2(160); + _hotspot16.setPosition(Common::Point(320, 202)); + _hotspot16.hide(); + + _sceneMode = 2338; + setAction(&_sequenceManager1, this, 2338, &_globals->_player, &_hotspot16, &_hotspot13, NULL); + break; + default: + switch (_globals->_stripNum) { + case 2101: + _globals->_player.disableControl(); + _globals->_player.setStrip(3); + _globals->_player.setPosition(Common::Point(307, 84)); + + _hotspot11.postInit(); + _hotspot11.setVisage(2705); + _hotspot11._strip = 2; + _hotspot11.setPriority2(10); + _hotspot11.setPosition(Common::Point(322, 80)); + _hotspot11.setObjectWrapper(new SceneObjectWrapper()); + _hotspot11.animate(ANIM_MODE_1, NULL); + + _hotspot10.postInit(); + _hotspot10.setVisage(2806); + _hotspot10.setObjectWrapper(new SceneObjectWrapper()); + _hotspot10.changeZoom(-1); + _hotspot10.setPriority2(10); + _hotspot10.setPosition(Common::Point(318, 89)); + _hotspot10._strip = 3; + _hotspot10.animate(ANIM_MODE_1, NULL); + + setAction(&_action7); + break; + case 6100: + _hotspot8.postInit(); + _hotspot8.setVisage(2345); + _hotspot8.setPosition(Common::Point(634, 65)); + _hotspot8.hide(); + + _sceneMode = 2325; + setAction(&_sequenceManager1, this, 2325, &_globals->_player, &_hotspot6, &_hotspot8, &_hotspot7, NULL); + break; + default: + _globals->_soundHandler.startSound(160); + _globals->_soundHandler.proc5(true); + _sceneMode = 2321; + + _globals->_player.setStrip(3); + setAction(&_sequenceManager1, this, 2321, &_globals->_player, &_hotspot6, NULL); + break; + } + } + + _globals->_stripNum = 0; + _globals->_sceneManager._scene->_sceneBounds.centre(_globals->_player._position); + loadScene(2320); + + _hotspot14._sceneRegionId = 8; + _hotspot1.setBounds(Rect(0, 0, 640, 200)); + _hotspot2.setBounds(Rect(278, 0, 362, 61)); + _hotspot3.setBounds(Rect(282, 62, 367, 98)); + _hotspot4.setBounds(Rect(67, 38, 112, 113)); + _hotspot5.setBounds(Rect(104, 122, 174, 157)); + _hotspot15.setBounds(Rect(191, 53, 205, 63)); + + _globals->_sceneItems.addItems(&_hotspot14, &_hotspot15, &_hotspot5, &_hotspot6, &_hotspot12, + &_hotspot13, &_hotspot4, &_hotspot3, &_hotspot2, &_hotspot1, NULL); +} + +void Scene2320::synchronise(Serialiser &s) { + Scene::synchronise(s); + SYNC_POINTER(_hotspotPtr); +} + +void Scene2320::signal() { + switch (_sceneMode) { + case 2321: + case 2327: + case 2329: + if (_globals->getFlag(43) && !_hotspot11._action) + _hotspot11.setAction(&_action1); + _globals->_player.enableControl(); + break; + case 2322: + _globals->_sceneManager.changeScene(2120); + break; + case 2323: + _globals->_player.disableControl(); + break; + case 2338: + case 2324: + _hotspot16.remove(); + _globals->_player.enableControl(); + break; + case 2325: + _globals->setFlag(76); + _globals->clearFlag(70); + _globals->_stripNum = 6100; + _globals->_sceneManager.changeScene(2100); + break; + case 2326: + _globals->clearFlag(70); + _globals->_inventory._nullifier._sceneNumber = 1; + _globals->_stripNum = 2321; + _globals->_sceneManager.changeScene(2100); + break; + case 2336: + _globals->setFlag(77); + _globals->_inventory._waldos._sceneNumber = 1; + _hotspot8.remove(); + break; + case 5000: + _globals->_player.enableControl(); + break; + } +} + +/*-------------------------------------------------------------------------- + * Scene 2400 - Descending in Lander + * + *--------------------------------------------------------------------------*/ + +void Scene2400::Action1::signal() { + switch (_actionIndex++) { + case 0: + setDelay(60); + break; + case 1: + ADD_MOVER(_globals->_player, 160, 71); + break; + case 2: + ADD_MOVER(_globals->_player, 160, 360); + break; + case 3: + _globals->_player._moveDiff = Common::Point(1, 1); + ADD_MOVER(_globals->_player, 140, 375); + break; + case 4: + ADD_MOVER(_globals->_player, 87, 338); + break; + case 5: + _globals->_player.hide(); + setDelay(60); + break; + case 6: + _globals->_sceneManager.changeScene(4000); + break; + } +} + +void Scene2400::Action1::dispatch() { + Action::dispatch(); + if ((_actionIndex == 4) && (_globals->_player._percent > 5)) + _globals->_player.changeZoom(_globals->_player._percent - 2); +} + +/*--------------------------------------------------------------------------*/ + +void Scene2400::postInit(SceneObjectList *OwnerList) { + loadScene(2400); + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + _globals->_player.postInit(); + _globals->_player.setVisage(2410); + _globals->_player.setPosition(Common::Point(340, -10)); + _globals->_player.animate(ANIM_MODE_2, NULL); + _globals->_player.disableControl(); + + setAction(&_action1); + + _globals->_sceneManager._scene->_sceneBounds.centre(_globals->_player._position.x, _globals->_player._position.y); + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.left / 160) * 160; + + _globals->_soundHandler.startSound(153); +} + +} // End of namespace tSage diff --git a/engines/tsage/ringworld_scenes3.h b/engines/tsage/ringworld_scenes3.h new file mode 100644 index 0000000000..420307ca99 --- /dev/null +++ b/engines/tsage/ringworld_scenes3.h @@ -0,0 +1,905 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/scene_logic.h $ + * $Id: scene_logic.h 232 2011-02-12 11:56:38Z dreammaster $ + * + */ + +#ifndef TSAGE_RINGWORLD_SCENES3_H +#define TSAGE_RINGWORLD_SCENES3_H + +#include "common/scummsys.h" +#include "tsage/core.h" +#include "tsage/converse.h" +#include "tsage/ringworld_logic.h" + +namespace tSage { + +class Scene2000: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + class Action5: public Action { + public: + virtual void signal(); + }; + class Action6: public Action { + public: + virtual void signal(); + }; + class Action7: public Action { + public: + virtual void signal(); + }; + class Action8: public Action { + public: + virtual void signal(); + }; + class Action9: public Action { + public: + virtual void signal(); + }; + class Action10: public Action { + public: + virtual void signal(); + }; + class Action11: public Action { + public: + virtual void signal(); + }; + class Action12: public Action { + public: + virtual void signal(); + }; + class Action13: public Action { + public: + virtual void signal(); + }; + class Action14: public Action { + public: + virtual void signal(); + }; + +public: + SpeakerSL _speakerSL; + SpeakerQR _speakerQR; + SpeakerMR _speakerMR; + SpeakerQText _speakerQText; + SpeakerMText _speakerMText; + SpeakerSText _speakerSText; + SpeakerHText _speakerHText; + SpeakerGameText _speakerGameText; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Action5 _action5; + Action6 _action6; + Action7 _action7; + Action8 _action8; + Action9 _action9; + Action10 _action10; + Action11 _action11; + Action12 _action12; + Action13 _action13; + Action14 _action14; + SceneObject _object1, _object2, _object3, _object4, _object5; + SceneObject _object6, _object7, _object8, _object9, _object10; + SoundHandler _soundHandler1, _soundHandler2; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void stripCallback(int v); +}; + +class Scene2100: public Scene { + /* Actions */ + class Action1: public ActionExt { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + class Action5: public Action { + public: + virtual void signal(); + }; + class Action6: public Action { + public: + virtual void signal(); + }; + class Action7: public Action { + public: + virtual void signal(); + }; + class Action8: public Action { + public: + virtual void signal(); + }; + class Action9: public Action { + public: + virtual void signal(); + }; + class Action10: public Action { + public: + virtual void signal(); + }; + class Action11: public Action { + public: + virtual void signal(); + }; + class Action12: public Action { + public: + virtual void signal(); + }; + class Action13: public Action { + public: + virtual void signal(); + }; + class Action14: public Action { + public: + virtual void signal(); + }; + class Action15: public Action { + public: + virtual void signal(); + }; + class Action16: public Action { + public: + virtual void signal(); + }; + class Action17: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot2: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot3: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot4: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot8: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot10: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot14: public SceneObject { + public: + virtual void doAction(int action); + }; + + /* Objects */ + class Object1: public SceneObject { + public: + virtual void doAction(int action); + }; + class Object2: public SceneObject { + public: + virtual void doAction(int action); + }; + class Object3: public SceneObject { + public: + virtual void doAction(int action); + }; +public: + SequenceManager _sequenceManager; + SoundHandler _soundHandler; + SpeakerMText _speakerMText; + SpeakerMR _speakerMR; + SpeakerQL _speakerQL; + SpeakerQR _speakerQR; + SpeakerQText _speakerQText; + SpeakerGameText _speakerGameText; + SpeakerSText _speakerSText; + SpeakerSL _speakerSL; + SpeakerSAL _speakerSAL; + SpeakerHText _speakerHText; + + DisplayHotspot _hotspot1; + Hotspot2 _hotspot2; + Hotspot3 _hotspot3; + Hotspot4 _hotspot4; + DisplayHotspot _hotspot5, _hotspot6, _hotspot7; + Hotspot8 _hotspot8; + DisplayHotspot _hotspot9; + Hotspot10 _hotspot10; + DisplayHotspot _hotspot11, _hotspot12, _hotspot13; + Hotspot14 _hotspot14; + DisplayHotspot _hotspot15; + + Object1 _object1; + Object2 _object2; + Object3 _object3; + SceneObject _object4; + + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Action5 _action5; + Action6 _action6; + Action7 _action7; + Action8 _action8; + Action9 _action9; + Action10 _action10; + Action11 _action11; + Action12 _action12; + Action13 _action13; + Action14 _action14; + Action15 _action15; + Action16 _action16; + Action17 _action17; + int _field1800; + SceneArea _area1, _area2, _area3, _area4; + + Scene2100(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void stripCallback(int v); + virtual void signal(); +}; + +class Scene2120: public Scene { + /* Actions */ + class Entry { + public: + int _size; + int _lineNum; + int _visage; + + Entry() { _size = 0; _lineNum = 0; _visage = 0; } + Entry(int size, int lineNum, int visage) { _size = size; _lineNum = lineNum; _visage = visage; } + }; + + class Action1: public Action { + private: + Common::Array<Entry> _entries; + public: + Action1(); + + virtual void signal(); + virtual void dispatch(); + }; + +public: + SoundHandler _soundHandler; + SceneObject _topicArrowHotspot, _arrowHotspot, _visageHotspot; + SceneObject _subjectButton, _nextPageButton, _previousPageButton, _exitButton; + Action1 _action1; + Rect _listRect; + int _dbMode, _prevDbMode; + bool _visageVisable; + int _subjectIndex; + int _lineOffset; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void synchronise(Serialiser &s); +}; + +class Scene2150: public Scene { + /* Actions */ + class Action1: public ActionExt { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot1: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot2: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot4: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot7: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot10: public SceneObject { + public: + virtual void doAction(int action); + }; +public: + SoundHandler _soundHandler; + SequenceManager _sequenceManager; + SpeakerGameText _speakerGameText; + + Rect _rect1, _rect2; + Hotspot1 _hotspot1; + Hotspot2 _hotspot2; + DisplayHotspot _hotspot3; + Hotspot4 _hotspot4; + DisplayHotspot _hotspot5, _hotspot6; + Hotspot7 _hotspot7; + DisplayHotspot _hotspot8, _hotspot9; + Hotspot10 _hotspot10; + DisplayHotspot _hotspot11; + SceneObject _hotspot12, _hotspot13, _hotspot14; + SceneArea _area1, _area2, _area3, _area4; + Action1 _action1; + Action2 _action2; + + Scene2150(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void synchronise(Serialiser &s); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene2200: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public ActionExt { + public: + virtual void signal(); + virtual void process(Event &event); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot3: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot5: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot9: public SceneObject { + public: + virtual void doAction(int action); + }; +public: + SequenceManager _sequenceManager; + SpeakerMText _speakerMText; + SpeakerSText _speakerSText; + SpeakerQText _speakerQText; + SpeakerSL _speakerSL; + SpeakerQR _speakerQR; + SpeakerQL _speakerQL; + SpeakerMR _speakerMR; + SpeakerGameText _speakerGameText; + Rect _exitRect; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + DisplayHotspot _hotspot1; + Hotspot3 _hotspot3; + Hotspot5 _hotspot5; + Hotspot9 _hotspot9; + DisplayHotspot _hotspot10; + SceneObject _hotspot2, _hotspot4; + SceneObject _hotspot6, _hotspot7, _hotspot8; + SoundHandler _soundHandler1, _soundHandler2; + + Scene2200(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void stripCallback(int v); + virtual void synchronise(Serialiser &s); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene2222: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + +public: + SoundHandler _soundHandler; + SpeakerSText _speakerSText; + SpeakerMText _speakerMText; + SpeakerQText _speakerQText; + SpeakerML _speakerML; + SpeakerSR _speakerSR; + Action1 _action1; + Action2 _action2; + SceneObject _hotspot1, _hotspot2, _hotspot3, _hotspot4, _hotspot5; + + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + +class Scene2230: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + class Action5: public Action { + public: + virtual void signal(); + }; + class Action6: public Action { + public: + virtual void signal(); + }; + class Action7: public Action { + public: + virtual void signal(); + }; + class Action8: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot1: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot3: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot4: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot5: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot6: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot7: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot8: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot10: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot11: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot12: public SceneObject { + public: + virtual void doAction(int action); + }; +public: + SoundHandler _soundHandler; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Action5 _action5; + Action6 _action6; + Action7 _action7; + Action8 _action8; + Hotspot1 _hotspot1; + Hotspot3 _hotspot3; + Hotspot4 _hotspot4; + SceneObject _hotspot2; + Hotspot5 _hotspot5; + Hotspot6 _hotspot6; + Hotspot7 _hotspot7; + Hotspot8 _hotspot8; + DisplayHotspot _hotspot9; + Hotspot10 _hotspot10; + Hotspot11 _hotspot11; + Hotspot12 _hotspot12; + Rect _rect1; + int _field30A; + + Scene2230(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void synchronise(Serialiser &s); + virtual void dispatch(); +}; + +class Scene2280: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public ActionExt { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot1: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot2: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot4: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot7: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot8: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot10: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot12: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot14: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot15: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot16: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot17: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot18: public SceneObject { + public: + virtual void doAction(int action); + }; + +public: + SoundHandler _soundHandler; + SequenceManager _sequenceManager; + Rect _exitRect; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Hotspot1 _hotspot1; + Hotspot2 _hotspot2; + DisplayHotspot _hotspot3; + Hotspot4 _hotspot4; + DisplayHotspot _hotspot5, _hotspot6; + Hotspot7 _hotspot7; + Hotspot8 _hotspot8; + DisplayHotspot _hotspot9; + Hotspot10 _hotspot10; + DisplayHotspot _hotspot11; + Hotspot12 _hotspot12; + DisplayHotspot _hotspot13; + Hotspot14 _hotspot14; + DisplayHotspot _hotspot15, _hotspot16; + Hotspot17 _hotspot17; + Hotspot18 _hotspot18; + + Scene2280(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void synchronise(Serialiser &s); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene2300: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public ActionExt { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot5: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot6: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot12: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot13: public SceneObject { + public: + virtual void doAction(int action); + }; +public: + SoundHandler _soundHandler1, _soundHandler2; + SpeakerSL _speakerSL; + SpeakerML _speakerML; + SpeakerQText _speakerQText; + SpeakerSText _speakerSText; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + SceneObject _hotspot1, _hotspot2, _hotspot3, _hotspot4; + Hotspot5 _hotspot5; + Hotspot6 _hotspot6; + SceneObject _hotspot7, _hotspot8, _hotspot9, _hotspot10; + DisplayHotspot _hotspot11, _hotspot12, _hotspot13, _hotspot14, _hotspot15; + + Scene2300(); + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + +class Scene2310: public Scene { +private: + int findObject(int objIndex); + + /* Custom classes */ + class ProtectionEntry { + public: + int _pageNumber; + int _connectionList[5]; + + void set(int pageNumber, int v1, int v2, int v3, int v4, int v5) { + _pageNumber = pageNumber; + _connectionList[0] = v1; _connectionList[1] = v2; _connectionList[2] = v3; + _connectionList[3] = v4; _connectionList[4] = v5; + } + }; + +public: + SequenceManager _sequenceManager; + int _wireIndex, _pageIndex; + SceneObject _wireList[5]; + Rect _rectList[5]; + SceneText _sceneText; + ProtectionEntry _pageList[21]; + + Scene2310(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void synchronise(Serialiser &s); + virtual void signal(); + virtual void process(Event &event); + virtual void dispatch(); +}; + +class Scene2320: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public ActionExt { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + class Action5: public Action { + public: + virtual void signal(); + }; + class Action6: public Action { + public: + virtual void signal(); + }; + class Action7: public Action { + public: + virtual void signal(); + }; + class Action8: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot5: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot6: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot8: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot10: public SceneObjectExt { + public: + virtual void doAction(int action); + }; + class Hotspot11: public SceneObjectExt { + public: + virtual void doAction(int action); + }; + class Hotspot12: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot14: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot15: public SceneObject { + public: + virtual void doAction(int action); + }; +public: + SoundHandler _soundHandler; + SequenceManager _sequenceManager1, _sequenceManager2; + SpeakerMText _speakerMText; + SpeakerMR _speakerMR; + SpeakerML _speakerML; + SpeakerQText _speakerQText; + SpeakerQL _speakerQL; + SpeakerQR _speakerQR; + SpeakerSAL _speakerSAL; + SpeakerSL _speakerSL; + SpeakerSR _speakerSR; + SpeakerSText _speakerSText; + SpeakerGameText _speakerGameText; + SceneArea _area1, _area2, _area3, _area4; + DisplayHotspot _hotspot1, _hotspot2, _hotspot3, _hotspot4; + Hotspot5 _hotspot5; + Hotspot6 _hotspot6; + SceneObject _hotspot7, _hotspot9; + Hotspot8 _hotspot8; + Hotspot10 _hotspot10; + Hotspot11 _hotspot11; + Hotspot12 _hotspot12; + DisplayHotspot _hotspot13; + Hotspot14 _hotspot14; + Hotspot15 _hotspot15; + SceneObject _hotspot16; + SceneItem *_hotspotPtr; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Action5 _action5; + Action6 _action6; + Action7 _action7; + Action8 _action8; + + Scene2320(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void synchronise(Serialiser &s); + virtual void signal(); +}; + +class Scene2400: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + virtual void dispatch(); + }; +public: + Action1 _action1; + SceneObject _object; + + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/ringworld_scenes4.cpp b/engines/tsage/ringworld_scenes4.cpp new file mode 100644 index 0000000000..944930ad09 --- /dev/null +++ b/engines/tsage/ringworld_scenes4.cpp @@ -0,0 +1,253 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#include "common/config-manager.h" +#include "tsage/ringworld_scenes4.h" +#include "tsage/scenes.h" +#include "tsage/tsage.h" +#include "tsage/staticres.h" + +namespace tSage { + +/*-------------------------------------------------------------------------- + * Scene 3500 - Ringworld Scan + * + *--------------------------------------------------------------------------*/ + +void Scene3500::Action1::signal() { + Scene3500 *scene = (Scene3500 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(10); + break; + case 1: + scene->_stripManager.start(3500, this); + break; + case 2: + setDelay(3); + break; + case 3: + _globals->_sceneManager.changeScene(9999); + break; + } +} + +void Scene3500::Action2::signal() { + Scene3500 *scene = (Scene3500 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(10); + break; + case 1: + scene->_stripManager.start(3501, this); + break; + case 2: + setDelay(3); + break; + case 3: + _globals->_sceneManager.changeScene(2012); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene3500::postInit(SceneObjectList *OwnerList) { + loadScene((_globals->_stripNum == 3600) ? 3600 : 3500); + Scene::postInit(); + + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerMText); + _stripManager.addSpeaker(&_speakerSText); + + _globals->_sceneManager._scene->_sceneBounds.contain(_globals->_sceneManager._scene->_backgroundBounds); + _globals->_sceneOffset.x = (_globals->_sceneManager._scene->_sceneBounds.top / 160) * 160; + + setAction((_globals->_stripNum == 3600) ? (Action *)&_action2 : (Action *)&_action1); +} + +/*-------------------------------------------------------------------------- + * Scene 3700 - Remote Viewer + * + *--------------------------------------------------------------------------*/ + +#define VIEW_FRAME_DELAY 10 + +Scene3700::Viewer::Viewer() { + _images1.setVisage(3705, 1); + _images2.setVisage(3705, 2); + + _frameList[0] = 1; + for (int idx = 1; idx <= 3; ++idx) + _frameList[idx] = _globals->_randomSource.getRandomNumber(4) + 1; + + _active = true; + _countdownCtr = 0; + _percentList[0] = 120; + _percentList[1] = 50; + _percentList[2] = 75; + _percentList[3] = 114; +} + +void Scene3700::Viewer::synchronise(Serialiser &s) { + SceneObject::synchronise(s); + s.syncAsByte(_active); + s.syncAsSint16LE(_countdownCtr); + for (int idx = 0; idx < 4; ++idx) { + s.syncAsSint16LE(_frameList[idx]); + s.syncAsSint16LE(_percentList[idx]); + } +} + +void Scene3700::Viewer::dispatch() { + if (_active) { + if (_countdownCtr-- <= 0) { + _countdownCtr = VIEW_FRAME_DELAY; + + for (int idx = 3; idx > 1; --idx) + _frameList[idx] = _frameList[idx - 1]; + + int newFrame; + do { + newFrame = _globals->_randomSource.getRandomNumber(4) + 1; + } while (newFrame == _frameList[2]); + + _frameList[1] = newFrame; + _flags |= OBJFLAG_PANES; + } + } +} + +void Scene3700::Viewer::reposition() { + _bounds = Rect(123, 40, 285, 123); +} + +void Scene3700::Viewer::draw() { + Region *priorityRegion = _globals->_sceneManager._scene->_priorities.find(1); + + for (int idx = 0; idx < 4; ++idx) { + Visage &v = (idx == 0) ? _images1 : _images2; + + GfxSurface img = v.getFrame(_frameList[idx]); + Rect destRect = img.getBounds(); + destRect.resize(img, (_position.x - _globals->_sceneOffset.x), + (_position.y - _globals->_sceneOffset.y - _yDiff), _percentList[idx]); + + destRect.translate(-_globals->_sceneManager._scene->_sceneBounds.left, + -_globals->_sceneManager._scene->_sceneBounds.top); + + _globals->gfxManager().copyFrom(img, destRect, priorityRegion); + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene3700::Action1::signal() { + Scene3700 *scene = (Scene3700 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(10); + break; + case 1: + scene->_stripManager.start(2162, this); + break; + case 2: + scene->_viewer._active = false; + setDelay(90); + break; + case 3: + scene->_soundHandler.startSound(196); + scene->_viewer.hide(); + + scene->_hotspot1.postInit(); + scene->_hotspot1.setVisage(3710); + scene->_hotspot1.setStrip(1); + scene->_hotspot1.setFrame(1); + scene->_hotspot1.setPosition(Common::Point(204, 120)); + + setDelay(90); + break; + case 4: + scene->_soundHandler.startSound(197); + scene->_hotspot1.hide(); + + scene->_hotspot2.postInit(); + scene->_hotspot2.setVisage(3710); + scene->_hotspot2.setStrip(2); + scene->_hotspot2.setFrame(1); + scene->_hotspot2.setPosition(Common::Point(204, 120)); + + setDelay(30); + break; + case 5: + scene->_soundHandler.startSound(198); + scene->_hotspot2.hide(); + scene->_hotspot1.show(); + setDelay(90); + break; + case 6: + scene->_stripManager.start(2166, this); + break; + case 7: + setDelay(60); + break; + case 8: + scene->_hotspot1.remove(); + scene->_hotspot2.show(); + _globals->setFlag(59); + setDelay(30); + break; + case 9: + _globals->_sceneManager.changeScene(2100); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene3700::postInit(tSage::SceneObjectList *OwnerList) { + Scene::postInit(); + loadScene(3700); + + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerMText); + _stripManager.addSpeaker(&_speakerMR); + _speakerSText.setTextPos(Common::Point(20, 15)); + _speakerMText.setTextPos(Common::Point(20, 15)); + + _viewer.postInit(); + _viewer.setVisage(3705); + _viewer.setStrip(1); + _viewer.setFrame(2); + _viewer.setPosition(Common::Point(195, 83)); + + setAction(&_action1); + _globals->_soundHandler.startSound(195); +} + +} // End of namespace tSage diff --git a/engines/tsage/ringworld_scenes4.h b/engines/tsage/ringworld_scenes4.h new file mode 100644 index 0000000000..4179d1a256 --- /dev/null +++ b/engines/tsage/ringworld_scenes4.h @@ -0,0 +1,95 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/scene_logic.h $ + * $Id: scene_logic.h 232 2011-02-12 11:56:38Z dreammaster $ + * + */ + +#ifndef TSAGE_RINGWORLD_SCENES4_H +#define TSAGE_RINGWORLD_SCENES4_H + +#include "common/scummsys.h" +#include "tsage/core.h" +#include "tsage/converse.h" +#include "tsage/ringworld_logic.h" + +namespace tSage { + +class Scene3500: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; +public: + SpeakerSText _speakerSText; + SpeakerMText _speakerMText; + SpeakerQText _speakerQText; + Action1 _action1; + Action2 _action2; + + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + +class Scene3700: public Scene { + /* Custom classes */ + class Viewer: public SceneObject { + public: + Visage _images1; + Visage _images2; + + int _frameList[4]; + int _percentList[4]; + bool _active; + int _countdownCtr; + + Viewer(); + virtual Common::String getClassName() { return "Viewer"; } + virtual void synchronise(Serialiser &s); + virtual void dispatch(); + virtual void reposition(); + virtual void draw(); + }; + + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; +public: + Viewer _viewer; + Action1 _action1; + SceneObject _hotspot1, _hotspot2; + SpeakerSText _speakerSText; + SpeakerMText _speakerMText; + SpeakerMR _speakerMR; + SoundHandler _soundHandler; + + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/ringworld_scenes5.cpp b/engines/tsage/ringworld_scenes5.cpp new file mode 100644 index 0000000000..a8a1055338 --- /dev/null +++ b/engines/tsage/ringworld_scenes5.cpp @@ -0,0 +1,4356 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#include "common/config-manager.h" +#include "tsage/ringworld_scenes5.h" +#include "tsage/scenes.h" +#include "tsage/tsage.h" +#include "tsage/staticres.h" + +namespace tSage { + +/*-------------------------------------------------------------------------- + * Scene 4000 - Village + * + *--------------------------------------------------------------------------*/ + +void Scene4000::Action1::signal() { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + scene->_hotspot5.postInit(); + scene->_hotspot5.setVisage(2870); + scene->_hotspot5.setObjectWrapper(new SceneObjectWrapper()); + scene->_hotspot5.animate(ANIM_MODE_1, NULL); + scene->_hotspot5.setPosition(Common::Point(116, 160)); + + ADD_PLAYER_MOVER_NULL(scene->_hotspot5, 208, 169); + + _globals->_inventory._ale._sceneNumber = 0; + _globals->clearFlag(42); + _globals->clearFlag(36); + _globals->clearFlag(43); + _globals->clearFlag(37); + break; + } + case 1: { + scene->_hotspot9.postInit(); + scene->_hotspot9.setVisage(4001); + scene->_hotspot9.animate(ANIM_MODE_1, NULL); + scene->_hotspot9.setObjectWrapper(new SceneObjectWrapper()); + scene->_hotspot9.setPosition(Common::Point(314, 132)); + + ADD_PLAYER_MOVER_NULL(scene->_hotspot9, 288, 167); + + scene->_hotspot4.postInit(); + scene->_hotspot4.setVisage(4006); + scene->_hotspot4.animate(ANIM_MODE_1, NULL); + scene->_hotspot4.setStrip(1); + scene->_hotspot4.setPosition(Common::Point(207, 136)); + + ADD_PLAYER_MOVER_NULL(scene->_hotspot4, 220, 151); + + scene->_hotspot7.postInit(); + scene->_hotspot7.setVisage(2701); + scene->_hotspot7.animate(ANIM_MODE_1, NULL); + scene->_hotspot7.setObjectWrapper(new SceneObjectWrapper()); + scene->_hotspot7._moveDiff = Common::Point(4, 2); + scene->_hotspot7.setPosition(Common::Point(300, 135)); + + ADD_PLAYER_MOVER_NULL(_globals->_player, 266, 169); + break; + } + case 2: + scene->_stripManager.start(4400, this); + break; + case 3: { + Common::Point pt1(30, 86); + PlayerMover *mover1 = new PlayerMover(); + scene->_hotspot7.addMover(mover1, &pt1, this); + + ADD_PLAYER_MOVER_NULL(scene->_hotspot5, 3, 86); + break; + } + case 4: + ADD_MOVER(scene->_hotspot7, -30, 86); + ADD_MOVER(scene->_hotspot5, -40, 86); + break; + case 5: + _globals->_soundHandler.startSound(155); + _globals->setFlag(43); + _globals->setFlag(114); + scene->_stripManager.start(4430, this); + break; + case 6: + ADD_PLAYER_MOVER_THIS(scene->_hotspot4, 277, 175); + ADD_PLAYER_MOVER_NULL(_globals->_player, 258, 187); + break; + case 7: + scene->_stripManager.start(4440, this); + break; + case 8: + setDelay(30); + break; + case 9: + _globals->setFlag(96); + _globals->_sceneManager.changeScene(4025); + break; + } +} + +void Scene4000::Action2::signal() { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setAction(&scene->_sequenceManager1, this, 4001, &_globals->_player, NULL); + + scene->_hotspot5.postInit(); + scene->_hotspot5.setVisage(2801); + scene->_hotspot5.animate(ANIM_MODE_1, NULL); + scene->_hotspot5.setObjectWrapper(new SceneObjectWrapper()); + scene->_hotspot5._moveDiff.x = 5; + scene->_hotspot5.setPosition(Common::Point(-8, 88)); + + scene->_hotspot3.setAction(&scene->_sequenceManager3, NULL, 4003, &scene->_hotspot5, NULL); + scene->_hotspot7.setAction(&scene->_sequenceManager2, NULL, 4002, &scene->_hotspot7, NULL); + break; + case 1: + _globals->_player.disableControl(); + + scene->_hotspot3.remove(); + ADD_MOVER(scene->_hotspot9, scene->_hotspot5._position.x + 30, scene->_hotspot5._position.y - 10); + break; + case 2: + _globals->_player.checkAngle(&scene->_hotspot9); + scene->_hotspot5.checkAngle(&scene->_hotspot9); + scene->_hotspot7.checkAngle(&scene->_hotspot9); + scene->_stripManager.start(4000, this); + break; + case 3: + scene->_hotspot2.setVisage(4017); + scene->_hotspot2.animate(ANIM_MODE_1, NULL); + scene->_hotspot2.setStrip(2); + + ADD_MOVER(scene->_hotspot2, 116, 160); + ADD_MOVER(scene->_hotspot5, 116, 160); + + _globals->setFlag(37); + break; + case 4: + break; + case 5: + scene->_stripManager.start(4010, this); + break; + case 6: + ADD_PLAYER_MOVER_NULL(scene->_hotspot9, 230, 149); + ADD_PLAYER_MOVER(210, 136); + ADD_PLAYER_MOVER_NULL(scene->_hotspot7, 210, 133); + break; + case 7: + _globals->_sceneManager.changeScene(4045); + break; + } +} + +void Scene4000::Action3::signal() { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->_hotspot8.setVisage(4017); + scene->_hotspot8.setFrame2(-1); + scene->_hotspot8.animate(ANIM_MODE_1, NULL); + scene->_hotspot8.setObjectWrapper(new SceneObjectWrapper()); + ADD_MOVER(scene->_hotspot8, 118, 145); + break; + case 1: + scene->_hotspot8.remove(); + remove(); + break; + } +} + +void Scene4000::Action4::signal() { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player._uiEnabled = false; + ADD_MOVER(_globals->_player, 257, 57); + break; + case 1: + _globals->_player.setVisage(4000); + _globals->_player.setPosition(Common::Point(258, 83)); + _globals->_player._frame = 1; + _globals->_player._strip = 3; + _globals->_player.animate(ANIM_MODE_4, 2, 1, this); + break; + case 2: + scene->_hotspot6.postInit(); + scene->_hotspot6.setVisage(4000); + scene->_hotspot6.setStrip(7); + scene->_hotspot6.setFrame(3); + scene->_hotspot6.setPosition(Common::Point(268, 44)); + + _globals->_inventory._rope._sceneNumber = 4000; + _globals->_events.setCursor(CURSOR_USE); + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 3: + _globals->_player.setVisage(2602); + _globals->_player.setPosition(Common::Point(257, 57)); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player._uiEnabled = true; + + _globals->setFlag(41); + remove(); + break; + } +} + +void Scene4000::Action5::signal() { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(15); + break; + case 1: + scene->_stripManager.start(_globals->_stripNum, this); + break; + case 2: + setDelay(10); + break; + case 3: + scene->_hotspot8.setVisage(4017); + scene->_hotspot8.animate(ANIM_MODE_1, NULL); + scene->_hotspot8.setFrame2(-1); + scene->_hotspot8.setAction(&scene->_action3); + + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene4000::Action6::signal() { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(30); + break; + case 1: + setAction(&scene->_sequenceManager1, this, 4001, &_globals->_player, NULL); + + if (!_globals->getFlag(36)) + scene->_hotspot7.setAction(&scene->_sequenceManager2, NULL, 4002, &scene->_hotspot7, NULL); + break; + case 2: + _globals->_player.disableControl(); + ADD_MOVER(scene->_hotspot9, _globals->_player._position.x + 30, _globals->_player._position.y - 5); + break; + case 3: + scene->_stripManager.start(_globals->getFlag(35) ? 4500 : 4502, this); + break; + case 4: + _globals->clearFlag(35); + ADD_MOVER_NULL(scene->_hotspot9, 292, 138); + ADD_PLAYER_MOVER(283, 147); + + if (!_globals->getFlag(36)) { + ADD_PLAYER_MOVER_NULL(scene->_hotspot7, 280, 150); + } + break; + case 5: + _globals->_sceneManager.changeScene(4100); + break; + } +} + +void Scene4000::Action7::signal() { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + + scene->_hotspot6.setFrame(1); + ADD_MOVER(_globals->_player, 247, 53); + break; + case 1: + _globals->_player.setVisage(4008); + _globals->_player.setStrip(4); + _globals->_player.setFrame(1); + _globals->_player.setPriority2(16); + _globals->_player.setPosition(Common::Point(260, 55)); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 2: + _globals->_sceneManager.changeScene(4050); + break; + } +} + +void Scene4000::Action8::signal() { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + if (_globals->getFlag(41)) + scene->_hotspot6.setFrame(2); + + ADD_MOVER(_globals->_player, 289, 53); + break; + case 1: + _globals->_player.setVisage(4008); + _globals->_player.setStrip(5); + _globals->_player.setPriority(16); + _globals->_player.setFrame(1); + _globals->_player.setPosition(Common::Point(283, 52)); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 2: + _globals->_player.remove(); + setDelay(60); + break; + case 3: + _globals->_soundHandler.startSound(170); + scene->_hotspot27.setVisage(4000); + scene->_hotspot27.setStrip(6); + scene->_hotspot27.animate(ANIM_MODE_2, NULL); + setDelay(60); + break; + case 4: + _globals->_soundHandler.startSound(77, this); + break; + case 5: + _globals->_game.endGame(4000, 15); + remove(); + break; + } +} + +void Scene4000::Action9::signal() { + switch (_actionIndex++) { + case 0: + setDelay(_globals->_randomSource.getRandomNumber(119) + 240); + break; + case 1: + static_cast<SceneObject *>(_owner)->animate(ANIM_MODE_8, 1, this); + _actionIndex = 0; + break; + } +} + +void Scene4000::Action10::signal() { + switch (_actionIndex++) { + case 0: + setDelay(_globals->_randomSource.getRandomNumber(119) + 240); + break; + case 1: + static_cast<SceneObject *>(_owner)->animate(ANIM_MODE_8, 1, this); + _actionIndex = 0; + break; + } +} + +void Scene4000::Action11::signal() { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + ADD_MOVER(scene->_hotspot3, -30, 70); + break; + case 1: + setDelay(60); + break; + case 2: + scene->_hotspot5.postInit(); + scene->_hotspot5.setVisage(2801); + scene->_hotspot5.animate(ANIM_MODE_1, NULL); + scene->_hotspot5.setObjectWrapper(new SceneObjectWrapper()); + scene->_hotspot5._moveDiff.x = 4; + scene->_hotspot5.setPosition(Common::Point(-8, 88)); + + setAction(&scene->_sequenceManager1, this, 4001, &_globals->_player, NULL); + + scene->_hotspot7.setPosition(Common::Point(-210, 139)); + scene->_hotspot7.setAction(&scene->_sequenceManager2, NULL, 4002, &scene->_hotspot7, NULL); + scene->_hotspot3.setAction(&scene->_sequenceManager3, NULL, 4003, &scene->_hotspot5, NULL); + break; + case 3: + scene->_stripManager.start(8000, this); + break; + case 4: + ADD_MOVER(scene->_hotspot4, 263, 187); + scene->_hotspot4.animate(ANIM_MODE_1, NULL); + break; + case 5: + scene->_soundHandler1.proc3(); + scene->_hotspot11.remove(); + + ADD_MOVER(_globals->_player, 340, 163); + ADD_MOVER_NULL(scene->_hotspot7, 340, 169); + ADD_MOVER_NULL(scene->_hotspot5, 340, 165); + break; + case 6: + _globals->_sceneManager.changeScene(4250); + break; + } +} + +void Scene4000::Action12::signal() { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(5); + break; + case 1: + _globals->_events.setCursor(CURSOR_WALK); + scene->_stripManager.start(4015, this); + break; + case 2: + _globals->setFlag(32); + if (scene->_stripManager._field2E8 == 275) { + _globals->setFlag(82); + ADD_MOVER_NULL(scene->_hotspot9, 292, 138); + ADD_PLAYER_MOVER(283, 147); + } else { + setDelay(30); + } + break; + case 3: + if (scene->_stripManager._field2E8 == 275) { + _globals->_sceneManager.changeScene(4100); + } else { + ADD_PLAYER_MOVER_THIS(scene->_hotspot9, 300, 132); + } + break; + case 4: + scene->_hotspot9.hide(); + scene->_stripManager.start(4020, this); + break; + case 5: + _globals->setFlag(35); + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene4000::Action13::signal() { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(3); + break; + case 1: + scene->_soundHandler2.startSound(151); + scene->_soundHandler2.proc5(true); + ADD_MOVER(scene->_hotspot3, -30, 70); + break; + case 2: + scene->_soundHandler2.proc4(); + _globals->_sceneManager.changeScene(4010); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene4000::Hotspot7::doAction(int action) { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_STUNNER: + SceneItem::display2(4000, 31); + break; + case CURSOR_LOOK: + SceneItem::display2(4000, 29); + break; + case CURSOR_TALK: + if (_globals->getFlag(31)) { + if (!_globals->getFlag(111)) { + _globals->setFlag(111); + _globals->_stripNum = 4070; + } else if (!_globals->getFlag(33)) + _globals->_stripNum = 4094; + else if (!_globals->getFlag(112)) { + _globals->setFlag(112); + _globals->_stripNum = 4300; + } else if (!_globals->getFlag(113)) { + _globals->setFlag(113); + _globals->_stripNum = 4093; + } else + _globals->_stripNum = 4094; + } else { + if (!_globals->getFlag(33)) + _globals->_stripNum = 4094; + else if (!_globals->getFlag(112)) { + _globals->setFlag(112); + _globals->_stripNum = 4300; + } else + _globals->_stripNum = 4094; + } + + scene->setAction(&scene->_action5); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4000::Hotspot8::doAction(int action) { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_STUNNER: + SceneItem::display2(4000, 26); + break; + case CURSOR_LOOK: + SceneItem::display2(4000, 25); + break; + case CURSOR_TALK: + if (_globals->_inventory._peg._sceneNumber == 1) + SceneItem::display2(4000, 34); + else { + switch (_ctr) { + case 0: + _globals->_stripNum = 4090; + break; + case 1: + _globals->_stripNum = 4091; + break; + case 2: + _globals->_stripNum = 4092; + break; + default: + SceneItem::display2(4000, 34); + break; + } + + if (_globals->_stripNum) { + setAction(NULL); + addMover(NULL); + ++_ctr; + scene->setAction(&scene->_action5); + } + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4000::Hotspot9::doAction(int action) { + switch (action) { + case OBJECT_STUNNER: + SceneItem::display2(4000, 28); + break; + case CURSOR_LOOK: + SceneItem::display2(4000, 27); + break; + case CURSOR_TALK: + error("*** Do we need dialog."); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4000::Hotspot10::doAction(int action) { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4000, 30); + break; + case CURSOR_USE: + _globals->_player.disableControl(); + if (_globals->getFlag(40)) { + scene->_sceneMode = 4005; + scene->setAction(&scene->_sequenceManager1, scene, 4005, &_globals->_player, NULL); + } else { + scene->_sceneMode = 4004; + scene->setAction(&scene->_sequenceManager1, scene, 4004, &_globals->_player, &scene->_hotspot10, NULL); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4000::Hotspot12::doAction(int action) { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4000, 13); + break; + case OBJECT_SCANNER: + SceneItem::display2(4000, 19); + break; + case OBJECT_STUNNER: + SceneItem::display2(4000, 20); + break; + case CURSOR_USE: + if (_globals->getFlag(40)) + SceneItem::display2(4000, 37); + else { + _globals->_player.disableControl(); + if (_globals->_sceneObjects->contains(&scene->_hotspot7)) + _globals->clearFlag(96); + + scene->_sceneMode = 4012; + scene->setAction(&scene->_sequenceManager1, scene, 4012, &_globals->_player, NULL); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4000::Hotspot13::doAction(int action) { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4000, 21); + break; + case OBJECT_ROPE: + if (_globals->getFlag(40)) + scene->setAction(&scene->_action4); + else + SceneItem::display2(4000, 22); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4000::Hotspot::doAction(int action) { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4000, 16); + break; + case OBJECT_SCANNER: + SceneItem::display2(4000, 17); + break; + case OBJECT_STUNNER: + SceneItem::display2(4000, 18); + break; + case OBJECT_LADDER: + _globals->_player.disableControl(); + + scene->_hotspot10.postInit(); + scene->_hotspot10.setVisage(4000); + scene->_hotspot10.setStrip(5); + scene->_hotspot10.setPosition(Common::Point(245, 147)); + scene->_hotspot10.hide(); + _globals->_sceneItems.push_front(&scene->_hotspot10); + + if (_globals->_sceneObjects->contains(&scene->_hotspot8)) { + scene->_hotspot8.setAction(NULL); + ADD_MOVER_NULL(scene->_hotspot8, 118, 145); + } + + scene->_sceneMode = 4004; + scene->setAction(&scene->_sequenceManager1, scene, 4011, &_globals->_player, &scene->_hotspot10, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4000::Hotspot17::doAction(int action) { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4000, 23); + break; + case CURSOR_USE: + if (_globals->getFlag(40)) + scene->setAction(&scene->_action7); + else + SceneItem::display2(4000, 24); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4000::Hotspot18::doAction(int action) { + Scene4000 *scene = (Scene4000 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4000, 36); + break; + case CURSOR_USE: + if (_globals->getFlag(40)) + scene->setAction(&scene->_action8); + else + SceneItem::display2(4000, 24); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4000::Hotspot23::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4000, _globals->getFlag(31) ? 10 : 9); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene4000::Scene4000(): + _hotspot11(0, CURSOR_LOOK, 4000, 14, CURSOR_USE, 4000, 32, OBJECT_STUNNER, 4000, 33, + OBJECT_SCANNER, 4000, 19, LIST_END), + _hotspot19(0, CURSOR_LOOK, 4000, 7, LIST_END), + _hotspot20(0, CURSOR_LOOK, 4000, 3, LIST_END), + _hotspot21(0, CURSOR_LOOK, 4000, 1, LIST_END), + _hotspot22(0, CURSOR_LOOK, 4000, 8, LIST_END), + _hotspot24(0, CURSOR_LOOK, 4000, 11, LIST_END), + _hotspot25(0, CURSOR_LOOK, 4000, 4, LIST_END), + _hotspot26(0, CURSOR_LOOK, 4000, 0, LIST_END) { +} + +void Scene4000::postInit(SceneObjectList *OwnerList) { + loadScene(4000); + Scene::postInit(); + setZoomPercents(0, 20, 70, 50); + + _stripManager.addSpeaker(&_speakerQR); + _stripManager.addSpeaker(&_speakerML); + _stripManager.addSpeaker(&_speakerMR); + _stripManager.addSpeaker(&_speakerSR); + _stripManager.addSpeaker(&_speakerCHFL); + _stripManager.addSpeaker(&_speakerPL); + _stripManager.addSpeaker(&_speakerPText); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerCHFR); + _stripManager.addSpeaker(&_speakerQL); + _stripManager.addSpeaker(&_speakerCHFText); + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerMText); + + _speakerCHFText._npc = &_hotspot9; + _speakerSText._npc = &_hotspot5; + _speakerMText._npc = &_hotspot7; + _speakerPText._npc = &_hotspot4; + _speakerQText._npc = &_globals->_player; + + _hotspot13.setBounds(Rect(263, 41, 278, 55)); + _hotspot14.setBounds(Rect(140, 177, 140 /*96*/, 204)); + _hotspot15.setBounds(Rect(227, 101, 264, 143)); + _hotspot16.setBounds(Rect(306, 100, 319, 148)); + _hotspot17.setBounds(Rect(231, 53, 254, 60)); + _hotspot18.setBounds(Rect(285, 51, 310, 60)); + _hotspot26.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + _hotspot21.setBounds(Rect(28, 7, 53, 64)); + _hotspot22.setBounds(Rect(125, 155, 140, 189)); + _hotspot23.setBounds(Rect(205, 102, 220, 142)); + _hotspot24.setBounds(Rect(270, 111, 297, 147)); + + _hotspot19._sceneRegionId = 16; + _hotspot20._sceneRegionId = 18; + _hotspot25._sceneRegionId = 17; + + _hotspot1.postInit(); + _hotspot1.setVisage(4000); + _hotspot1.setPriority2(1); + _hotspot1.setFrame(2); + _hotspot1.setPosition(Common::Point(242, 59)); + _hotspot1.animate(ANIM_MODE_2, NULL); + + _hotspot27.postInit(); + _hotspot27.setVisage(4000); + _hotspot27.setStrip(2); + _hotspot27.setPriority2(1); + _hotspot27.setFrame(2); + _hotspot27.setPosition(Common::Point(299, 59)); + _hotspot27.animate(ANIM_MODE_2, NULL); + + if (_globals->_inventory._ladder._sceneNumber != 4000) { + _hotspot8.postInit(); + _hotspot8.setVisage(4018); + _hotspot8.setObjectWrapper(new SceneObjectWrapper()); + _hotspot8._strip = 2; + _hotspot8._numFrames = 5; + _hotspot8.setPosition(Common::Point(306, 154)); + _hotspot8.setAction(&_action9); + } + + _hotspot12.postInit(); + _hotspot12.setVisage(4000); + _hotspot12.setStrip(3); + _hotspot12.setFrame(3); + _hotspot12.setPriority2(200); + _hotspot12.setPosition(Common::Point(281, 176)); + + if (_globals->getFlag(34)) { + _soundHandler1.startSound(156); + + _hotspot11.postInit(); + _hotspot11.setVisage(4000); + _hotspot11.setStrip(4); + _hotspot11.setPosition(Common::Point(312, 174)); + _hotspot11.setPriority2(200); + _hotspot11.animate(ANIM_MODE_8, 0, NULL); + + _globals->_sceneItems.push_back(&_hotspot11); + } + + _globals->_player.postInit(); + _globals->_player.setVisage(2602); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setPosition(Common::Point(-28, 86)); + + if (!_globals->getFlag(36) && !_globals->getFlag(43)) { + _hotspot7.postInit(); + _hotspot7.setVisage(2701); + _hotspot7.animate(ANIM_MODE_1, NULL); + _hotspot7.setObjectWrapper(new SceneObjectWrapper()); + _hotspot7._moveDiff = Common::Point(4, 2); + _hotspot7.setPosition(Common::Point(-210, 139)); + + _globals->_sceneItems.push_back(&_hotspot7); + } + + switch (_globals->_sceneManager._previousScene) { + case 2320: + _globals->_soundHandler.startSound(155); + + if (_globals->_inventory._ale._sceneNumber == 1) { + _hotspot9.postInit(); + _hotspot9.setVisage(4001); + _hotspot9.animate(ANIM_MODE_1, NULL); + _hotspot9.setObjectWrapper(new SceneObjectWrapper()); + _hotspot9.setPosition(Common::Point(314, 132)); + + setAction(&_action6); + } else { + _globals->_player.disableControl(); + _sceneMode = 4001; + setAction(&_sequenceManager1, this, 4001, &_globals->_player, NULL); + + if (!_globals->getFlag(36) && !_globals->getFlag(43)) + _hotspot7.setAction(&_sequenceManager2, NULL, 4002, &_hotspot7, NULL); + } + + if (_globals->getFlag(42)) + _hotspot8.setAction(&_action3); + else if (_globals->getFlag(91)) + _hotspot8.remove(); + break; + + case 4010: + _hotspot7.setPosition(Common::Point(-210, 139)); + + _hotspot9.postInit(); + _hotspot9.setVisage(4001); + _hotspot9.animate(ANIM_MODE_1, NULL); + _hotspot9.setObjectWrapper(new SceneObjectWrapper()); + _hotspot9.setPosition(Common::Point(314, 132)); + + _hotspot2.postInit(); + _hotspot2.setVisage(4018); + _hotspot2._strip = 1; + _hotspot2._numFrames = 5; + _hotspot2.setPosition(Common::Point(182, 146)); + _hotspot2.setAction(&_action10); + + setAction(&_action2); + break; + + case 4025: + if (_globals->_inventory._ladder._sceneNumber != 4000) + _hotspot8.remove(); + + _globals->_player.setPosition(Common::Point(260, 185)); + + if (!_globals->getFlag(36) && !_globals->getFlag(43)) + _hotspot7.setPosition(Common::Point(246, 146)); + + if (_globals->getFlag(96)) { + _hotspot4.postInit(); + _hotspot4.setVisage(4006); + _hotspot4.animate(ANIM_MODE_1, NULL); + _hotspot4.setObjectWrapper(new SceneObjectWrapper()); + _hotspot4.setPosition(Common::Point(290, 163)); + } + + if (_globals->_stripNum == 4025) { + _soundHandler1.startSound(182); + _hotspot11.remove(); + + _hotspot5.postInit(); + _hotspot5.setVisage(2801); + _hotspot5.animate(ANIM_MODE_1, NULL); + _hotspot5.setObjectWrapper(new SceneObjectWrapper()); + _hotspot5._moveDiff.x = 4; + _hotspot5.setPosition(Common::Point(-18, 86)); + + _globals->_player.disableControl(); + + if (!_globals->getFlag(96)) { + _hotspot4.postInit(); + _hotspot4.setVisage(4006); + _hotspot4.animate(ANIM_MODE_1, NULL); + _hotspot4.setObjectWrapper(new SceneObjectWrapper()); + _hotspot4.setPosition(Common::Point(195, 128)); + + Common::Point pt(268, 157); + PlayerMover *mover = new PlayerMover(); + _hotspot4.addMover(mover, &pt, NULL); + } + + _sceneMode = 4003; + setAction(&_sequenceManager1, this, 4003, &_hotspot5, NULL); + } else if (_globals->getFlag(96)) { + _globals->_player.disableControl(); + _sceneMode = 4013; + setAction(&_sequenceManager1, this, 4013, &_hotspot4, NULL); + } + + _globals->clearFlag(96); + break; + + case 4045: + _globals->_player.enableControl(); + + if (_globals->_inventory._ladder._sceneNumber != 4000) { + _hotspot8.postInit(); + _hotspot8.setVisage(4017); + _hotspot8.animate(ANIM_MODE_1, NULL); + _hotspot8.setPosition(Common::Point(199, 188)); + _hotspot8.setAction(&_action3); + } + + _globals->_player.setPosition(Common::Point(208, 153)); + if (!_globals->getFlag(36) && !_globals->getFlag(43)) + _hotspot7.setPosition(Common::Point(246, 146)); + + if (_globals->getFlag(39)) { + _globals->clearFlag(39); + + _hotspot4.postInit(); + _hotspot4.setVisage(4006); + _hotspot4.animate(ANIM_MODE_1, NULL); + _hotspot4.setObjectWrapper(new SceneObjectWrapper()); + _hotspot4.setPosition(Common::Point(219, 150)); + + _globals->_player.disableControl(); + setAction(&_sequenceManager1, this, 4010, &_globals->_player, NULL); + } + + if (_globals->_stripNum == 4000) { + _globals->_stripNum = 0; + + _hotspot9.postInit(); + _hotspot9.setVisage(4001); + _hotspot9.animate(ANIM_MODE_1, NULL); + _hotspot9.setObjectWrapper(new SceneObjectWrapper()); + _hotspot9.setPosition(Common::Point(231, 159)); + _hotspot9.setStrip(4); + + setAction(&_action12); + } + break; + + case 4050: + _globals->_soundHandler.startSound(155); + _globals->_player.disableControl(); + + if (_globals->_stripNum == 4050) { + _globals->_player.setVisage(4008); + _globals->_player.setStrip(4); + _globals->_player.setFrame(_globals->_player.getFrameCount()); + _globals->_player.setPriority2(16); + _globals->_player.setPosition(Common::Point(260, 55)); + + _sceneMode = 4007; + setAction(&_sequenceManager1, this, 4007, &_globals->_player, NULL); + } else { + _globals->_player.setPosition(Common::Point(208, 153)); + _globals->_player.enableControl(); + } + + if (_globals->_inventory._ladder._sceneNumber != 4000) + _hotspot8.remove(); + break; + + case 4100: + _globals->_player.enableControl(); + _globals->_player.setPosition(Common::Point(270, 155)); + + if (_globals->getFlag(42) && (_globals->_inventory._ladder._sceneNumber != 4000)) { + _hotspot8.setVisage(4017); + _hotspot8.animate(ANIM_MODE_1, NULL); + _hotspot8.setPosition(Common::Point(244, 151)); + _hotspot8.setAction(&_action3); + } + + if (!_globals->getFlag(36) && !_globals->getFlag(43)) + _hotspot7.setPosition(Common::Point(246, 146)); + break; + + default: + _globals->_soundHandler.startSound(155); + + _hotspot3.postInit(); + _hotspot3.setVisage(4002); + _hotspot3._moveDiff = Common::Point(10, 10); + _hotspot3.setPosition(Common::Point(-100, 80)); + _hotspot3.changeZoom(-1); + _hotspot3.setPosition(Common::Point(130, -1)); + _hotspot3.animate(ANIM_MODE_2, NULL); + + if (_globals->_stripNum == 9000) { + _hotspot4.postInit(); + _hotspot4.setVisage(4006); + _hotspot4.setPosition(Common::Point(235, 153)); + + _hotspot9.postInit(); + _hotspot9.setVisage(4001); + _hotspot9.setStrip(3); + _hotspot9.setPosition(Common::Point(255, 153)); + + setAction(&_action11); + _globals->_inventory._ladder._sceneNumber = 4100; + _globals->_inventory._rope._sceneNumber = 4150; + + _soundHandler1.startSound(156); + + _hotspot11.postInit(); + _hotspot11.setVisage(4000); + _hotspot11.setStrip(4); + _hotspot11.setPosition(Common::Point(312, 174)); + _hotspot11.setPriority2(200); + _hotspot11.animate(ANIM_MODE_8, 0, NULL); + } else { + if (!_globals->getFlag(37)) { + _hotspot2.postInit(); + _hotspot2.setVisage(4018); + _hotspot2._strip = 1; + _hotspot2._numFrames = 5; + _hotspot2.setPosition(Common::Point(182, 146)); + _hotspot2.setAction(&_action10); + } + + _hotspot7.setPosition(Common::Point(-210, 139)); + setAction(&_action13); + } + break; + } + + if (_globals->_inventory._ladder._sceneNumber == 4000) { + _hotspot10.postInit(); + _hotspot10.setVisage(4000); + _hotspot10.setStrip(5); + _hotspot10.setPosition(Common::Point(245, 147)); + + _globals->_sceneItems.push_back(&_hotspot10); + } + + if (_globals->_inventory._rope._sceneNumber == 4000) { + _hotspot6.postInit(); + _hotspot6.setVisage(4000); + _hotspot6.setStrip(7); + _hotspot6.setPriority2(1); + _hotspot6.setPosition(Common::Point(268, 44)); + } + + _globals->_sceneItems.addItems(&_hotspot8, &_hotspot17, &_hotspot18, &_hotspot14, &_hotspot15, + &_hotspot16, &_hotspot12, &_hotspot13, &_hotspot21, &_hotspot20, &_hotspot22, &_hotspot23, + &_hotspot24, &_hotspot25, &_hotspot19, &_hotspot26, NULL); +} + +void Scene4000::signal() { + switch (_sceneMode) { + case 4001: + _globals->_player.enableControl(); + break; + case 4002: + case 4011: + break; + case 4003: + _sceneMode = 4014; + setAction(&_sequenceManager1, this, 4014, &_globals->_player, &_hotspot5, NULL); + break; + case 4004: + _globals->_inventory._ladder._sceneNumber = 4000; + // Deliberate fall-through + case 4007: + _globals->_events.setCursor(CURSOR_USE); + _globals->setFlag(40); + break; + case 4005: + _globals->_player.enableControl(); + _globals->_events.setCursor(CURSOR_WALK); + _globals->clearFlag(40); + break; + case 4006: + _globals->_sceneManager.changeScene(4045); + break; + case 4008: + _globals->_sceneManager.changeScene(2320); + break; + case 4009: + _globals->_sceneManager.changeScene(2200); + break; + case 4010: + _globals->setFlag(38); + _hotspot4.remove(); + break; + case 4012: + _globals->_player.checkAngle(&_hotspot12); + _globals->_sceneManager.changeScene(4025); + break; + case 4013: + _globals->_player.enableControl(); + _hotspot4.remove(); + break; + case 4014: + _globals->_sceneManager.changeScene(4250); + break; + case 4015: + ADD_MOVER_NULL(_hotspot7, 0, _hotspot7._position.y - 5); + break; + } +} + +void Scene4000::dispatch() { + Scene::dispatch(); + + if ((_globals->_player.getRegionIndex() == 10) || (_globals->_player.getRegionIndex() == 6)) + _globals->_player.setPriority2(200); + if (_globals->_player.getRegionIndex() == 11) + _globals->_player.setPriority2(-1); + if (_globals->_player.getRegionIndex() == 5) + _globals->_player.setPriority2(94); + + if (_globals->_sceneObjects->contains(&_hotspot5)) { + if ((_hotspot5.getRegionIndex() == 10) || (_hotspot5.getRegionIndex() == 6)) + _hotspot5.setPriority2(200); + if (_hotspot5.getRegionIndex() == 11) + _hotspot5.setPriority2(-1); + if (_hotspot5.getRegionIndex() == 5) + _hotspot5.setPriority2(94); + } + + if (_globals->_sceneObjects->contains(&_hotspot7)) { + if (!_hotspot7._mover) + _hotspot7.checkAngle(&_globals->_player); + if (!_action && _globals->_player.getRegionIndex() == 23) { + ADD_MOVER_NULL(_hotspot7, 204, 186); + } + + if ((_hotspot7.getRegionIndex() == 10) || (_hotspot7.getRegionIndex() == 6)) + _hotspot7.setPriority2(200); + if (_hotspot7.getRegionIndex() == 11) + _hotspot7.setPriority2(-1); + if (_hotspot7.getRegionIndex() == 5) + _hotspot7.setPriority2(94); + } + + if (!_action) { + if ((_globals->_inventory._peg._sceneNumber == 1) && _globals->getFlag(34) && + _globals->getFlag(37) && !_globals->getFlag(40)) { + _globals->_player.disableControl(); + _soundHandler1.startSound(177); + _globals->_soundHandler.startSound(178); + + setAction(&_action1); + } + + if (_globals->_player.getRegionIndex() == 2) + _globals->_sceneManager.changeScene(4045); + if (_globals->_player.getRegionIndex() == 15) + _globals->_sceneManager.changeScene(4100); + + if ((_globals->_player._position.x > 5) && (_globals->_player._position.y < 100)) { + _globals->_player.disableControl(); + + if (!_globals->_sceneObjects->contains(&_hotspot7) || (_hotspot7._position.y <= 100)) { + _sceneMode = 4008; + setAction(&_sequenceManager1, this, 4008, &_globals->_player, NULL); + } else { + _sceneMode = 4015; + _globals->_player.addMover(NULL); + setAction(&_sequenceManager1, this, 4015, &_globals->_player, &_hotspot7, NULL); + } + } + } +} + +/*-------------------------------------------------------------------------- + * Scene 4010 - Village - Outside Lander + * + *--------------------------------------------------------------------------*/ + +void Scene4010::postInit(SceneObjectList *OwnerList) { + loadScene(4010); + Scene::postInit(); + setZoomPercents(0, 20, 70, 50); + + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerMText); + _speakerSText._npc = &_hotspot1; + _speakerMText._npc = &_hotspot2; + _speakerQText._npc = &_globals->_player; + + _globals->_player.postInit(); + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setPosition(Common::Point(-38, 175)); + _globals->_player.changeZoom(75); + + _hotspot2.postInit(); + _hotspot2.setVisage(2705); + _hotspot2.animate(ANIM_MODE_1, NULL); + _hotspot2.setObjectWrapper(new SceneObjectWrapper()); + _hotspot2._moveDiff = Common::Point(4, 2); + _hotspot2.setPosition(Common::Point(-50, 185)); + _hotspot2.changeZoom(75); + + _hotspot1.postInit(); + _hotspot1.setVisage(2806); + _hotspot1.setPosition(Common::Point(-20, 175)); + _hotspot1.changeZoom(75); + _hotspot1.animate(ANIM_MODE_1, NULL); + _hotspot1.setObjectWrapper(new SceneObjectWrapper()); + + _globals->_player.disableControl(); + setAction(&_sequenceManager, this, 4017, &_globals->_player, &_hotspot1, &_hotspot2, NULL); +} + +void Scene4010::signal() { + _globals->_sceneManager.changeScene(4000); +} + +/*-------------------------------------------------------------------------- + * Scene 4025 - Village - Puzzle Board + * + *--------------------------------------------------------------------------*/ + +void Scene4025::Action1::signal() { + Scene4025 *scene = (Scene4025 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->_armHotspot._strip = scene->_pegPtr->_armStrip; + scene->_armHotspot._frame = 4; + scene->_armHotspot.animate(ANIM_MODE_4, 2, -1, this); + + if (scene->_pegPtr->_armStrip > 3) { + if (scene->_hole1._armStrip == scene->_pegPtr->_armStrip) + scene->_hole1._pegPtr = NULL; + if (scene->_hole2._armStrip == scene->_pegPtr->_armStrip) + scene->_hole2._pegPtr = NULL; + if (scene->_hole3._armStrip == scene->_pegPtr->_armStrip) + scene->_hole3._pegPtr = NULL; + if (scene->_hole4._armStrip == scene->_pegPtr->_armStrip) + scene->_hole4._pegPtr = NULL; + if (scene->_hole5._armStrip == scene->_pegPtr->_armStrip) + scene->_hole5._pegPtr = NULL; + } + break; + case 1: + scene->_pegPtr->hide(); + + if (scene->_pegPtr2) { + if (scene->_pegPtr->_armStrip == 3) + scene->_pegPtr2->_strip = 2; + + scene->_pegPtr2->setPosition(scene->_pegPtr->_position); + scene->_pegPtr2->show(); + scene->_pegPtr2->_armStrip = scene->_pegPtr->_armStrip; + } + + scene->_pegPtr->_armStrip = 0; + scene->_pegPtr->setPosition(Common::Point(-10, -10)); + scene->_pegPtr2 = scene->_pegPtr; + scene->_armHotspot.animate(ANIM_MODE_5, this); + break; + + case 2: + _globals->_player._uiEnabled = true; + _globals->_events.setCursor(CURSOR_USE); + remove(); + break; + } +} + +void Scene4025::Action2::signal() { + Scene4025 *scene = (Scene4025 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->_armHotspot._strip = scene->_holePtr->_armStrip; + scene->_armHotspot.animate(ANIM_MODE_4, 2, -1, this); + break; + case 1: + if (!scene->_pegPtr2) { + // Getting a peg from a hole + scene->_holePtr->_pegPtr->hide(); + scene->_pegPtr = scene->_holePtr->_pegPtr; + scene->_pegPtr->_armStrip = 0; + scene->_pegPtr->setPosition(Common::Point(-10, -10)); + scene->_pegPtr2 = scene->_holePtr->_pegPtr; + scene->_holePtr->_pegPtr = NULL; + } else { + // Placing a peg into a hole + scene->_pegPtr2 = NULL; + if (scene->_holePtr->_pegPtr) { + scene->_holePtr->_pegPtr->hide(); + scene->_pegPtr2 = scene->_holePtr->_pegPtr; + } + + assert(scene->_pegPtr); + scene->_pegPtr->setPosition(scene->_holePtr->_newPosition); + scene->_pegPtr->setStrip(1); + scene->_pegPtr->show(); + scene->_pegPtr->_armStrip = scene->_holePtr->_armStrip; + + scene->_holePtr->_pegPtr = scene->_pegPtr; + scene->_pegPtr = scene->_pegPtr2; + } + scene->_armHotspot.animate(ANIM_MODE_5, this); + break; + case 2: + _globals->_player._uiEnabled = true; + _globals->_events.setCursor(CURSOR_USE); + remove(); + break; + } +} + +void Scene4025::Action3::signal() { + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + _globals->_scenePalette.addRotation(64, 111, -1); + setDelay(120); + break; + case 1: + _globals->clearFlag(34); + _globals->_stripNum = 4025; + _globals->_sceneManager.changeScene(4000); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene4025::Hole::synchronise(Serialiser &s) { + SceneObject::synchronise(s); + SYNC_POINTER(_pegPtr); + s.syncAsSint16LE(_armStrip); + s.syncAsSint16LE(_newPosition.x); + s.syncAsSint16LE(_newPosition.y); +} + +void Scene4025::Hole::doAction(int action) { + Scene4025 *scene = (Scene4025 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4025, 3); + break; + case CURSOR_USE: + if (!scene->_pegPtr && !_pegPtr) { + setAction(&scene->_sequenceManager, scene, 4028, NULL); + } else { + _globals->_player.disableControl(); + scene->_holePtr = this; + scene->setAction(&scene->_action2); + } + break; + case OBJECT_PEG: + if (!scene->_pegPtr2) { + _globals->_player.disableControl(); + _globals->_events.setCursor(CURSOR_USE); + _globals->_inventory._peg._sceneNumber = 4025; + + scene->_pegPtr = &scene->_peg5; + scene->_holePtr = this; + scene->_pegPtr->_armStrip = 0; + scene->_pegPtr2 = scene->_pegPtr; + + scene->setAction(&scene->_action2); + } else { + scene->_sceneMode = 4027; + scene->setAction(&scene->_sequenceManager, scene, 4027, NULL); + } + break; + } +} + +void Scene4025::Peg::synchronise(Serialiser &s) { + SceneObject::synchronise(s); + s.syncAsSint16LE(_field88); + SYNC_POINTER(_armStrip); +} + +void Scene4025::Peg::doAction(int action) { + Scene4025 *scene = (Scene4025 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4025, 1); + break; + case CURSOR_USE: + _globals->_player.disableControl(); + scene->_pegPtr = this; + scene->setAction(&scene->_action1); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene4025::Scene4025(): Scene() { + _holePtr = NULL; + _pegPtr = _pegPtr2 = NULL; +} + +void Scene4025::postInit(SceneObjectList *OwnerList) { + loadScene(4025); + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + _globals->_events.setCursor(CURSOR_USE); + _pegPtr = _pegPtr2 = NULL; + + _peg1.postInit(); + _peg1._field88 = 1; + _peg1.setVisage(4025); + _peg1.setStrip(2); + _peg1.setFrame(1); + _peg1.setPosition(Common::Point(203, 61)); + + _peg2.postInit(); + _peg2._field88 = 4; + _peg2.setVisage(4025); + _peg2.setStrip(2); + _peg2.setFrame(2); + _peg2.setPosition(Common::Point(195, 57)); + + _peg3.postInit(); + _peg3._field88 = 0; + _peg3.setVisage(4025); + _peg3.setStrip(2); + _peg3.setFrame(3); + _peg3.setPosition(Common::Point(202, 66)); + + _peg4.postInit(); + _peg4._field88 = 3; + _peg4.setVisage(4025); + _peg4.setStrip(2); + _peg4.setFrame(4); + _peg4.setPosition(Common::Point(194, 68)); + + _peg5.postInit(); + _peg5._field88 = 2; + _peg5.setVisage(4025); + _peg5.setStrip(1); + _peg5.setFrame(5); + _peg5.hide(); + + _hole1.postInit(); + _hole1.setVisage(4025); + _hole1.setStrip(1); + _hole1.setFrame2(6); + _hole1.setPosition(Common::Point(123, 51)); + _hole1._pegPtr = NULL; + _hole1._newPosition = Common::Point(123, 44); + _hole1._armStrip = 8; + + _hole2.postInit(); + _hole2.setVisage(4025); + _hole2.setStrip(1); + _hole2.setFrame2(7); + _hole2.setPosition(Common::Point(167, 51)); + _hole2._pegPtr = NULL; + _hole2._newPosition = Common::Point(166, 44); + _hole2._armStrip = 7; + + _hole3.postInit(); + _hole3.setVisage(4025); + _hole3.setStrip(1); + _hole3.setFrame2(8); + _hole3.setPosition(Common::Point(145, 69)); + _hole3._pegPtr = NULL; + _hole3._newPosition = Common::Point(145, 60); + _hole3._armStrip = 6; + + _hole4.postInit(); + _hole4.setVisage(4025); + _hole4.setStrip(1); + _hole4.setFrame2(6); + _hole4.setPosition(Common::Point(123, 87)); + _hole4._pegPtr = NULL; + _hole4._newPosition = Common::Point(123, 80); + _hole4._armStrip = 5; + + _hole5.postInit(); + _hole5.setVisage(4025); + _hole5.setStrip(1); + _hole5.setFrame2(10); + _hole5.setPosition(Common::Point(167, 87)); + _hole5._pegPtr = NULL; + _hole5._newPosition = Common::Point(166, 80); + _hole5._armStrip = 4; + + _hole1.setPriority2(1); + _hole2.setPriority2(1); + _hole3.setPriority2(1); + _hole4.setPriority2(1); + _hole5.setPriority2(1); + + _armHotspot.postInit(); + _armHotspot.setVisage(4025); + _armHotspot.setPosition(Common::Point(190, 161)); + _armHotspot.setStrip(3); + _armHotspot.setFrame(4); + + _globals->_sceneItems.addItems(&_hole1, &_hole2, &_hole3, &_hole4, &_hole5, + &_peg1, &_peg2, &_peg3, &_peg4, &_peg5, NULL); + + _globals->_player._uiEnabled = true; + _globals->_player.disableControl(); + setAction(&_sequenceManager, this, 4026, NULL); +} + +void Scene4025::synchronise(Serialiser &s) { + Scene::synchronise(s); + SYNC_POINTER(_pegPtr); + SYNC_POINTER(_pegPtr2); + SYNC_POINTER(_holePtr); +} + +void Scene4025::remove() { + _globals->_scenePalette.clearListeners(); + Scene::remove(); +} + +void Scene4025::signal() { + if (_sceneMode != 4027) { + if (_sceneMode != 4028) { + _gfxButton.setText(EXIT_MSG); + _gfxButton._bounds.centre(144, 107); + _gfxButton.draw(); + _gfxButton._bounds.expandPanes(); + } + + _globals->_player._uiEnabled = true; + } + + _globals->_events.setCursor(CURSOR_USE); +} + +void Scene4025::process(Event &event) { + Scene::process(event); + + if (_gfxButton.process(event)) { + if (_globals->_inventory._peg._sceneNumber == 4025) + _globals->_inventory._peg._sceneNumber = 1; + + _globals->_sceneManager.changeScene(4000); + } +} + +void Scene4025::dispatch() { + if (!_action && (_peg1._armStrip == 7) && (_peg2._armStrip == 4) && (_peg3._armStrip == 8) && + (_peg4._armStrip == 5) && (_peg5._armStrip == 6)) + setAction(&_action3); + + Scene::dispatch(); +} + +/*-------------------------------------------------------------------------- + * Scene 4045 - Village - Temple Antechamber + * + *--------------------------------------------------------------------------*/ + +void Scene4045::Action1::signal() { + Scene4045 *scene = (Scene4045 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(60); + break; + case 1: + _globals->_events.setCursor(CURSOR_WALK); + scene->_stripManager.start(4040, this, scene); + break; + case 2: + scene->_hotspot5.animate(ANIM_MODE_NONE, NULL); + scene->_hotspot4.animate(ANIM_MODE_5, this); + break; + case 3: + setDelay(60); + break; + case 4: + scene->_hotspot4.animate(ANIM_MODE_6, this); + break; + case 5: + ADD_MOVER(_globals->_player, 150, 300); + break; + case 6: + _globals->_stripNum = 4000; + _globals->_sceneManager.changeScene(4000); + remove(); + break; + } +} + +void Scene4045::Action2::signal() { + Scene4045 *scene = (Scene4045 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(15); + break; + case 1: + scene->_stripManager.start(_globals->_stripNum, this, scene); + break; + case 2: + scene->_hotspot5.animate(ANIM_MODE_NONE, NULL); + setDelay(10); + break; + case 3: + if (_globals->getFlag(38)) { + _globals->_player.enableControl(); + remove(); + } else { + ADD_MOVER(_globals->_player, 150, 300); + } + break; + case 4: + _globals->setFlag(39); + _globals->_sceneManager.changeScene(4000); + break; + } +} + +void Scene4045::Action3::signal() { + Scene4045 *scene = (Scene4045 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + scene->_hotspot4.animate(ANIM_MODE_5, this); + break; + case 1: + scene->_stripManager.start(4504, this, scene); + break; + case 2: + scene->_hotspot4.animate(ANIM_MODE_6, NULL); + scene->_hotspot5.animate(ANIM_MODE_NONE, NULL); + ADD_MOVER(_globals->_player, 91, 1264); + break; + case 3: + _globals->_player.enableControl(); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene4045::Hotspot1::doAction(int action) { + Scene4045 *scene = (Scene4045 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_STUNNER: + SceneItem::display2(4045, 19); + break; + case CURSOR_LOOK: + SceneItem::display2(4045, (_strip == 1) ? 5 : 14); + break; + case CURSOR_USE: + SceneItem::display2(4045, 18); + break; + case CURSOR_TALK: + if (_strip == 5) { + setStrip(6); + animate(ANIM_MODE_NONE, 0); + } + if (_globals->_player._position.y < 135) { + scene->_sceneMode = 4046; + _numFrames = 10; + _globals->_player.disableControl(); + + scene->setAction(&scene->_sequenceManager, this, 4046, &_globals->_player, this, NULL); + } else { + if (!_globals->getFlag(31)) { + _globals->setFlag(31); + _globals->_stripNum = 4080; + } else if (!_globals->getFlag(38)) + _globals->_stripNum = 4060; + else + _globals->_stripNum = 4503; + + scene->setAction(&scene->_action2); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4045::Hotspot2::doAction(int action) { + Scene4045 *scene = (Scene4045 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4045, 9); + break; + case CURSOR_TALK: + scene->_sceneMode = 4102; + _globals->_player.disableControl(); + scene->setAction(&scene->_sequenceManager, scene, 4104, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4045::Hotspot6::doAction(int action) { + Scene4045 *scene = (Scene4045 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4045, 17); + break; + case CURSOR_USE: + if (_globals->_player._position.y < 135) { + SceneItem::display2(4045, 16); + _globals->_inventory._peg._sceneNumber = 1; + _globals->_events.setCursor(CURSOR_WALK); + remove(); + } else { + scene->_sceneMode = 4047; + _globals->_player.disableControl(); + scene->setAction(&scene->_sequenceManager, scene, 4047, &_globals->_player, &scene->_hotspot1, NULL); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene4045::Scene4045(): + _hotspot3(0, CURSOR_LOOK, 4045, 1, CURSOR_USE, 4100, 21, LIST_END), + _hotspot7(9, CURSOR_LOOK, 4045, 0, CURSOR_USE, 4045, 15, LIST_END), + _hotspot8(10, CURSOR_LOOK, 4045, 2, LIST_END), + _hotspot9(11, CURSOR_LOOK, 4045, 3, CURSOR_USE, 4045, 15, LIST_END), + _hotspot10(12, CURSOR_LOOK, 4045, 4, CURSOR_USE, 4045, 19, LIST_END), + _hotspot11(13, CURSOR_LOOK, 4045, 6, CURSOR_USE, 4045, 15, LIST_END), + _hotspot12(14, CURSOR_LOOK, 4045, 7, CURSOR_USE, 4045, 29, LIST_END), + _hotspot13(15, CURSOR_LOOK, 4045, 8, CURSOR_USE, 4045, 19, LIST_END), + _hotspot14(0, CURSOR_LOOK, 4045, 10, LIST_END) { + + _hotspot14.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); +} + +void Scene4045::postInit(SceneObjectList *OwnerList) { + loadScene(4045); + Scene::postInit(); + setZoomPercents(100, 60, 200, 100); + + _stripManager.addSpeaker(&_speakerQR); + _stripManager.addSpeaker(&_speakerML); + _stripManager.addSpeaker(&_speakerPR); + _stripManager.addSpeaker(&_speakerPText); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerQL); + _stripManager.setCallback(this); + + _speakerQText._textPos.y = 140; + + _hotspot3.postInit(); + _hotspot3.setVisage(4045); + _hotspot3.setPosition(Common::Point(47, 111)); + _hotspot3.animate(ANIM_MODE_2, NULL); + _hotspot3.setPriority2(156); + _globals->_sceneItems.push_back(&_hotspot3); + + _globals->_player.postInit(); + _globals->_player.setVisage(4200); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player._moveDiff = Common::Point(7, 4); + + _hotspot1.postInit(); + _hotspot1.setVisage(4051); + + _hotspot5.postInit(); + _hotspot5.setVisage(4051); + _hotspot5.setStrip(4); + _hotspot5.setPriority2(152); + + if(_globals->_sceneManager._previousScene == 4050) { + _globals->_soundHandler.startSound(155); + _globals->_player.setPosition(Common::Point(72, 128)); + _globals->_player.enableControl(); + + _hotspot1.setStrip(5); + _hotspot1.setPosition(Common::Point(173, 99)); + _hotspot1._numFrames = 1; + _hotspot1.animate(ANIM_MODE_2, NULL); + + _hotspot5.setPosition(Common::Point(177, 40)); + + if (_globals->_inventory._peg._sceneNumber == 4045) { + _hotspot6.postInit(); + _hotspot6.setVisage(4045); + _hotspot6.setStrip(2); + _hotspot6.setPosition(Common::Point(108, 82)); + _globals->_sceneItems.push_back(&_hotspot6); + } + } else { + _globals->_player.setPosition(Common::Point(108, 192)); + _globals->_player.setStrip(4); + + if (!_globals->getFlag(36) && !_globals->getFlag(43)) { + _hotspot2.postInit(); + _hotspot2.setVisage(4102); + _hotspot2.animate(ANIM_MODE_NONE, NULL); + _hotspot2.setStrip(3); + _hotspot2.changeZoom(-1); + _hotspot2.setPosition(Common::Point(66, 209)); + _globals->_sceneItems.push_back(&_hotspot2); + } + + if (_globals->getFlag(31)) { + _hotspot1.setVisage(4051); + _hotspot1.setStrip(5); + _hotspot1.setPosition(Common::Point(173, 99)); + _hotspot1._numFrames = 1; + _hotspot1.animate(ANIM_MODE_2, NULL); + + _hotspot5.setPosition(Common::Point(177, 40)); + + if (_globals->_inventory._peg._sceneNumber == 4045) { + _hotspot6.postInit(); + _hotspot6.setVisage(4045); + _hotspot6.setStrip(2); + _hotspot6.setPosition(Common::Point(108, 82)); + _globals->_sceneItems.push_back(&_hotspot6); + } + } else { + _hotspot1.setPosition(Common::Point(186, 149)); + + _hotspot4.postInit(); + _hotspot4.setVisage(4051); + _hotspot4.setStrip(2); + _hotspot4.setPriority2(152); + _hotspot4.setPosition(Common::Point(202, 80)); + + _hotspot5.setPosition(Common::Point(192, 77)); + _globals->setFlag(31); + setAction(&_action1); + + _globals->_player.disableControl(); + } + } + + _globals->_sceneItems.addItems(&_hotspot1, &_hotspot7, &_hotspot8, &_hotspot9, &_hotspot10, + &_hotspot13, &_hotspot11, &_hotspot12, &_hotspot14, NULL); +} + +void Scene4045::stripCallback(int v) { + switch (v) { + case 1: + _hotspot5.animate(ANIM_MODE_7, 0, NULL); + break; + case 2: + _hotspot5.animate(ANIM_MODE_NONE, NULL); + break; + } +} + +void Scene4045::signal() { + switch (_sceneMode) { + case 4046: + case 4047: + _hotspot5.animate(ANIM_MODE_NONE, NULL); + break; + case 4050: + _globals->_sceneManager.changeScene(4000); + break; + case 4102: + _globals->_player.enableControl(); + break; + } +} + +void Scene4045::dispatch() { + if (!_action) { + if (_globals->_player.getRegionIndex() == 8) { + _globals->_player.addMover(NULL); + if (_hotspot1._strip == 1) { + _globals->_player.disableControl(); + _sceneMode = 4046; + _hotspot1._numFrames = 10; + setAction(&_sequenceManager, this, 4046, &_globals->_player, &_hotspot1, NULL); + } else { + setAction(&_action3); + } + } + + if (_globals->_player.getRegionIndex() == 10) + _globals->_sceneManager.changeScene(4050); + if (_globals->_player._position.y >= 196) { + _sceneMode = 4050; + _globals->_player.disableControl(); + setAction(&_sequenceManager, this, 4105, &_globals->_player, NULL); + } + } + + Scene::dispatch(); +} + +/*-------------------------------------------------------------------------- + * Scene 4000 - Village - Temple + * + *--------------------------------------------------------------------------*/ + +void Scene4050::Action1::signal() { + Scene4050 *scene = (Scene4050 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(3); + break; + case 1: + ADD_PLAYER_MOVER(204, 152); + break; + case 2: + _globals->_player.checkAngle(&scene->_hotspot17); + + scene->_hotspot14.postInit(); + scene->_hotspot14.setVisage(4050); + scene->_hotspot14.setStrip(2); + scene->_hotspot14.setPosition(Common::Point(91, 154)); + scene->_hotspot14.setPriority2(200); + break; + case 3: + _globals->_events.waitForPress(); + _globals->setFlag(45); + scene->_hotspot14.remove(); + + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene4050::Action2::signal() { + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(120); + break; + case 1: + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 2: + _globals->_player.setVisage(4202); + _globals->_player.changeZoom(100); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setPosition(Common::Point(192, 130)); + + ADD_MOVER(_globals->_player, 215, 130); + break; + case 3: + _globals->_player.setVisage(4052); + _globals->_player.setStrip(5); + _globals->_player.setFrame(1); + _globals->_player.setPosition(Common::Point(236, 130)); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 4: + _globals->_player.setVisage(4202); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setPosition(Common::Point(210, 185)); + _globals->_player.setPriority2(-1); + _globals->_player.enableControl(); + + remove(); + break; + } +} + +void Scene4050::Action3::signal() { + switch (_actionIndex++) { + case 0: + ADD_PLAYER_MOVER(210, 185); + break; + case 1: + _globals->_player.setPriority2(200); + _globals->_player.setVisage(4052); + _globals->_player.setStrip(5); + _globals->_player.changeZoom(100); + _globals->_player.setFrame(_globals->_player.getFrameCount()); + _globals->_player.setPosition(Common::Point(236, 130)); + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 2: + _globals->_player.setVisage(4202); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setPosition(Common::Point(215, 130)); + ADD_MOVER(_globals->_player, 212, 130); + break; + case 3: + _globals->_stripNum = 4050; + _globals->_sceneManager.changeScene(4000); + break; + } +} + +void Scene4050::Action4::signal() { + Scene4050 *scene = (Scene4050 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + ADD_MOVER(_globals->_player, 189, 135); + _globals->_player.setPriority2(200); + break; + case 1: + _globals->_player._moveDiff.y = 3; + _globals->_player.setStrip2(3); + _globals->_player._frame = 1; + _globals->_player.setPosition(Common::Point(189, 129)); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 2: + _globals->_player.setVisage(4202); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setPosition(Common::Point(192, 130)); + _globals->_player.changeZoom(100); + ADD_MOVER(_globals->_player, 215, 130); + + scene->_hotspot16.postInit(); + scene->_hotspot16.setVisage(4052); + scene->_hotspot16.animate(ANIM_MODE_1, NULL); + scene->_hotspot16.setStrip2(6); + scene->_hotspot16.setPosition(Common::Point(160, 240)); + ADD_MOVER(scene->_hotspot16, 172, 188); + break; + case 3: + _globals->_player.setVisage(4052); + _globals->_player.setStrip(5); + _globals->_player.setFrame(1); + _globals->_player.setPosition(Common::Point(238, 130)); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 4: + _globals->_player.setVisage(4052); + _globals->_player.setStrip(2); + _globals->_player.setFrame(1); + _globals->_player.setPosition(Common::Point(216, 184)); + _globals->_player.setPriority2(-1); + break; + case 5: + scene->_hotspot16.setStrip2(4); + scene->_hotspot16.setFrame(1); + scene->_hotspot16.animate(ANIM_MODE_4, 4, 1, this);; + break; + case 6: + scene->_hotspot16.animate(ANIM_MODE_5, NULL); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 7: + _globals->_player.setVisage(4202); + _globals->_player.setStrip(6); + _globals->_player.setFrame(1); + + scene->_stripManager.start(4051, this); + break; + case 8: + setDelay(15); + break; + case 9: + _globals->_sceneManager.changeScene(4000); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene4050::Hotspot14::doAction(int action) { + Scene4050 *scene = (Scene4050 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4050, 14); + break; + case CURSOR_USE: + _globals->_player.disableControl(); + setAction(&scene->_action3); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4050::Hotspot17::doAction(int action) { + Scene4050 *scene = (Scene4050 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + scene->setAction(&scene->_action1); + break; + case CURSOR_USE: + SceneItem::display2(4050, 24); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene4050::Scene4050(): + _hotspot1(0, CURSOR_LOOK, 4050, 0, LIST_END), + _hotspot2(0, CURSOR_LOOK, 4050, 1, CURSOR_USE, 4050, 15, LIST_END), + _hotspot3(0, CURSOR_LOOK, 4050, 2, CURSOR_USE, 4050, 16, LIST_END), + _hotspot4(0, CURSOR_LOOK, 4050, 4, LIST_END), + _hotspot5(0, CURSOR_LOOK, 4050, 5, LIST_END), + _hotspot6(0, CURSOR_LOOK, 4050, 5, LIST_END), + _hotspot7(0, CURSOR_LOOK, 4050, 6, CURSOR_USE, 4050, 18, LIST_END), + _hotspot8(0, CURSOR_LOOK, 4050, 7, CURSOR_USE, 4050, 19, LIST_END), + _hotspot9(0, CURSOR_LOOK, 4050, 8, CURSOR_USE, 4050, 20, LIST_END), + _hotspot10(0, CURSOR_LOOK, 4050, 9, CURSOR_USE, 4050, 21, LIST_END), + _hotspot11(0, CURSOR_LOOK, 4050, 10, CURSOR_USE, 4050, 22, LIST_END), + _hotspot12(0, CURSOR_LOOK, 4050, 11, CURSOR_USE, 4050, 23, LIST_END), + _hotspot13(0, CURSOR_LOOK, 4050, 3, CURSOR_USE, 4050, 17, LIST_END) { +} + +void Scene4050::postInit(SceneObjectList *OwnerList) { + loadScene(4050); + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + _stripManager.addSpeaker(&_speakerPText); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerGameText); + + _globals->_player.postInit(); + + switch (_globals->_sceneManager._previousScene) { + case 4000: + if (_globals->getFlag(41)) { + _hotspot15.postInit(); + _hotspot15.setVisage(4054); + _hotspot15.setPosition(Common::Point(206, 103)); + _globals->_sceneItems.push_back(&_hotspot15); + + _globals->_player.setVisage(4008); + _globals->_player.setPosition(Common::Point(206, 62)); + _globals->_player.changeZoom(130); + _globals->_player.setPriority2(200); + _globals->_player.setStrip(2); + + setAction(&_action2); + _globals->_soundHandler.startSound(175); + } else { + _globals->_player.setVisage(5315); + _globals->_player.setPosition(Common::Point(189, 83)); + _globals->_player.changeZoom(130); + _globals->_player.setStrip2(2); + _globals->_player._moveDiff.y = 10; + _globals->_player.animate(ANIM_MODE_2, NULL); + + setAction(&_action4); + _globals->_soundHandler.startSound(176); + } + break; + case 4045: + _hotspot15.postInit(); + _hotspot15.setVisage(4054); + _hotspot15.setPosition(Common::Point(206, 103)); + _globals->_sceneItems.push_back(&_hotspot15); + + _globals->_player.setVisage(4202); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setPosition(Common::Point(193, 193)); + + _globals->_soundHandler.startSound(175); + break; + default: + break; + } + + _hotspot13.postInit(); + _hotspot13.setVisage(4053); + _hotspot13.animate(ANIM_MODE_2, NULL); + _hotspot13.setPosition(Common::Point(190, 97)); + + _hotspot17.postInit(); + _hotspot17.setVisage(4050); + _hotspot17.setPosition(Common::Point(209, 119)); + _hotspot17.setPriority2(2); + + _hotspot1.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + _hotspot2.setBounds(Rect(150, 25, 198, 125)); + _hotspot3.setBounds(Rect(56, 94, 88, 153)); + _hotspot4.setBounds(Rect(170, 7, 209, 18)); + _hotspot5.setBounds(Rect(190, 72, 212, 92)); + _hotspot6.setBounds(Rect(122, 75, 145, 93)); + _hotspot7.setBounds(Rect(109, 103, 263, 158)); + _hotspot8.setBounds(Rect(157, 160, 213, 173)); + _hotspot9.setBounds(Rect(95, 157, 120, 178)); + _hotspot10.setBounds(Rect(278, 43, 310, 115)); + _hotspot11.setBounds(Rect(263, 105, 279, 147)); + _hotspot12.setBounds(Rect(258, 154, 307, 180)); + + _globals->_sceneItems.addItems(&_hotspot17, &_hotspot12, &_hotspot11, &_hotspot10, &_hotspot13, + &_hotspot2, &_hotspot3, &_hotspot4, &_hotspot5, &_hotspot6, &_hotspot8, &_hotspot9, + &_hotspot7, &_hotspot1, NULL); +} + +void Scene4050::signal() { + +} + +void Scene4050::dispatch() { + +} + +/*-------------------------------------------------------------------------- + * Scene 4100 - Village - Hut + * + *--------------------------------------------------------------------------*/ + +void Scene4100::Action1::signal() { + Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(10); + break; + case 1: + scene->_stripManager.start(_globals->_stripNum, this); + break; + case 2: + setDelay(30); + break; + case 3: + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene4100::Action2::signal() { + Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->_hotspot2.postInit(); + scene->_hotspot2.changeZoom(95); + scene->_hotspot2.setVisage(4120); + scene->_hotspot2.animate(ANIM_MODE_1, NULL); + scene->_hotspot2.setStrip2(4); + scene->_hotspot2.setPriority2(100); + scene->_hotspot2.setPosition(Common::Point(214, 119)); + + setDelay(3); + break; + case 1: + ADD_MOVER(scene->_hotspot2, 249, 131); + break; + case 2: + scene->_hotspot2.setStrip2(3); + scene->_hotspot2.setFrame2(5); + scene->_hotspot2.animate(ANIM_MODE_NONE, NULL); + setDelay(3); + break; + case 3: + remove(); + break; + } +} + + +void Scene4100::Action3::signal() { + Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->clearFlag(43); + _globals->clearFlag(36); + setDelay(15); + break; + case 1: + scene->_stripManager.start(4505, this); + break; + case 2: + scene->setAction(&scene->_action2); + case 3: + scene->_stripManager.start(4510, this); + break; + case 4: + setDelay(15); + break; + case 5: + _globals->_sceneManager.changeScene(4150); + break; + } +} + +void Scene4100::Action4::signal() { + Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(30); + break; + case 1: + scene->_hotspot1.animate(ANIM_MODE_5, this); + break; + case 2: + scene->_hotspot1.setVisage(4105); + scene->_hotspot1.setFrame(1); + scene->_hotspot1.animate(ANIM_MODE_5, this); + break; + case 3: + _globals->clearFlag(43); + _globals->setFlag(42); + scene->_stripManager.start(4119, this); + case 4: + setDelay(15); + break; + case 5: + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene4100::Action5::signal() { + Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + ADD_PLAYER_MOVER(58, 151); + break; + case 1: + if (_globals->_inventory._ladder._sceneNumber == 4100) { + _globals->_inventory._ladder._sceneNumber = 1; + scene->_hotspot6.remove(); + } else { + scene->_hotspot6.postInit(); + scene->_hotspot6.setVisage(4101); + scene->_hotspot6.setPosition(Common::Point(49, 144)); + + _globals->_inventory._ladder._sceneNumber = 4100; + _globals->_sceneItems.push_front(&scene->_hotspot6); + } + + _globals->_player.enableControl(); + remove(); + break; + } +} + + +void Scene4100::Action6::signal() { + Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + scene->_stripManager.start(4103, this); + ADD_PLAYER_MOVER(245, 167); + break; + case 1: + _globals->_player.enableControl(); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene4100::Hotspot1::doAction(int action) { + Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4100, _globals->getFlag(42) ? 24 : 12); + break; + case OBJECT_STUNNER: + SceneItem::display2(4100, 16); + break; + case CURSOR_USE: + SceneItem::display2(4100, 22); + break; + case CURSOR_TALK: + if (_globals->_inventory._peg._sceneNumber == 1) { + _globals->_player.disableControl(); + scene->setAction(&scene->_sequenceManager, scene, 4109, NULL); + } else if (_globals->getFlag(42)) { + scene->setAction(&scene->_sequenceManager, scene, 4102, NULL); + } else { + if (_globals->getFlag(33)) + _globals->_stripNum = 4077; + else if (_globals->getFlag(82)) { + _globals->clearFlag(82); + _globals->_stripNum = 4100; + } else { + _globals->_stripNum = 4075; + _globals->setFlag(33); + } + + scene->setAction(&scene->_action1); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4100::Hotspot2::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + error("*** The Chief's daughter... WOW!"); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4100::Hotspot5::doAction(int action) { + Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4100, 14); + break; + case CURSOR_TALK: + scene->_sceneMode = 4102; + scene->setAction(&scene->_sequenceManager, scene, 4104, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4100::Hotspot6::doAction(int action) { + Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4100, 2); + break; + case CURSOR_USE: + if (_globals->getFlag(42)) { + _globals->_player.disableControl(); + scene->setAction(&scene->_action5); + } else { + scene->_sceneMode = 4102; + scene->setAction(&scene->_sequenceManager, scene, 4103, NULL); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + + +void Scene4100::Hotspot14::doAction(int action) { + Scene4100 *scene = (Scene4100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4100, 0); + break; + case OBJECT_LADDER: + _globals->_player.disableControl(); + scene->setAction(&scene->_action5); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + + +/*--------------------------------------------------------------------------*/ + +Scene4100::Scene4100(): + _hotspot3(0, CURSOR_LOOK, 4100, 10, CURSOR_USE, 4100, 21, LIST_END), + _hotspot4(0, CURSOR_LOOK, 4100, 8, LIST_END), + _hotspot7(0, CURSOR_USE, 4100, 3, CURSOR_USE, 4150, 29, LIST_END), + _hotspot8(0, CURSOR_LOOK, 4100, 5, LIST_END), + _hotspot9(0, CURSOR_LOOK, 4100, 6, CURSOR_USE, 4100, 20, LIST_END), + _hotspot10(0, CURSOR_LOOK, 4100, 7, CURSOR_USE, 4100, 19, LIST_END), + _hotspot11(0, CURSOR_LOOK, 4100, 8, CURSOR_USE, 4100, 18, LIST_END), + _hotspot12(0, CURSOR_LOOK, 4100, 9, LIST_END), + _hotspot13(0, CURSOR_LOOK, 4100, 11, CURSOR_USE, 4100, 17, LIST_END) { +} + +void Scene4100::postInit(SceneObjectList *OwnerList) { + loadScene(4100); + Scene::postInit(); + setZoomPercents(135, 80, 190, 100); + + _stripManager.addSpeaker(&_speakerMText); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerCHFText); + _stripManager.addSpeaker(&_speakerCDRText); + _stripManager.addSpeaker(&_speakerCDR); + _stripManager.addSpeaker(&_speakerML); + _stripManager.addSpeaker(&_speakerQR); + + _globals->_player.postInit(); + _globals->_player.setVisage(4200); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setStrip(4); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setPosition(Common::Point(88, 180)); + _globals->_player._moveDiff = Common::Point(7, 4); + + _hotspot1.postInit(); + _hotspot1.setVisage(4102); + _hotspot1.setPriority2(129); + _hotspot1.setPosition(Common::Point(171, 120)); + + _hotspot3.postInit(); + _hotspot3.setVisage(4130); + _hotspot3.animate(ANIM_MODE_2, NULL); + _hotspot3.setPriority2(200); + _hotspot3.setPosition(Common::Point(272, 110)); + + _hotspot4.postInit(); + _hotspot4.setVisage(4130); + _hotspot4.animate(ANIM_MODE_2, NULL); + _hotspot4.setStrip2(2); + _hotspot4.setPosition(Common::Point(152, 167)); + + if (_globals->getFlag(36)) { + _hotspot1.setVisage(4105); + _hotspot1.setStrip(1); + _hotspot1.setFrame(4); + } else if (!_globals->getFlag(43)) { + _hotspot5.postInit(); + _hotspot5.setVisage(4102); + _hotspot5.setStrip2(3); + _hotspot5.setFrame(2); + _hotspot5.setPosition(Common::Point(65, 188)); + + _globals->_sceneItems.push_back(&_hotspot5); + } + + if (_globals->_inventory._ladder._sceneNumber == 4100) { + _hotspot6.postInit(); + _hotspot6.setVisage(4101); + _hotspot6.setPosition(Common::Point(49, 144)); + + _globals->_sceneItems.push_back(&_hotspot6); + } + + _hotspot14.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + _hotspot7._sceneRegionId = 16; + _hotspot8.setBounds(Rect(90, 0, 211, 113)); + _hotspot9.setBounds(Rect(207, 96, 235, 115)); + _hotspot10.setBounds(Rect(87, 81, 212, 107)); + _hotspot11.setBounds(Rect(61, 148, 243, 168)); + _hotspot12.setBounds(Rect(229, 59, 256, 122)); + _hotspot13.setBounds(Rect(255, 152, 286, 183)); + + _globals->_sceneItems.addItems(&_hotspot3, &_hotspot1, &_hotspot13, &_hotspot12, &_hotspot4, + &_hotspot11, &_hotspot9, &_hotspot7, &_hotspot10, &_hotspot8, &_hotspot14, NULL); + + if (_globals->_sceneManager._previousScene == 4150) { + _globals->_soundHandler.startSound(155); + + if (!_globals->getFlag(42)) { + _hotspot1.setVisage(4104); + _hotspot1.setPosition(Common::Point(152, 118)); + _hotspot1.setStrip2(-1); + _hotspot1.setFrame2(-1); + _hotspot1.setFrame(1); + + _globals->_player.setStrip(2); + _globals->_player.disableControl(); + setAction(&_action4); + + _globals->clearFlag(43); + } + + _globals->_player.setPosition(Common::Point(252, 139)); + _globals->_player.setStrip(2); + } else { + if ((_globals->_inventory._ale._sceneNumber == 4100) && !_globals->getFlag(42)) { + _globals->_player.disableControl(); + setAction(&_action3); + } + if (_globals->getFlag(35)) { + _globals->_player.disableControl(); + _sceneMode = 4101; + setAction(&_sequenceManager, this, 4101, &_globals->_player, NULL); + } + } +} + +void Scene4100::signal() { + switch (_sceneMode) { + case 4101: + _globals->_sceneManager.changeScene(4000); + break; + case 4102: + case 4103: + case 4109: + _globals->_player.enableControl(); + break; + } +} + +void Scene4100::dispatch() { + if (!_action) { + if ((_globals->_player.getRegionIndex() == 15) && !_globals->getFlag(42)) + setAction(&_action6); + + if (_globals->_player.getRegionIndex() == 8) + _globals->_sceneManager.changeScene(4150); + + if (_globals->_player._position.y >= 196) { + _globals->_player.disableControl(); + _sceneMode = 4101; + setAction(&_sequenceManager, this, 4105, &_globals->_player, NULL); + } + } + + Scene::dispatch(); +} + +/*-------------------------------------------------------------------------- + * Scene 4150 - Village - Bedroom + * + *--------------------------------------------------------------------------*/ + +void Scene4150::Action1::signal() { + Scene4150 *scene = (Scene4150 *)_globals->_sceneManager._scene; + byte adjustData[4] = {0, 0, 0, 0}; + + switch (_actionIndex++) { + case 0: + setDelay(60); + break; + case 1: + scene->_stripManager.start(4520, this); + break; + case 2: + setDelay(15); + break; + case 3: + setAction(&scene->_action2, this); + break; + case 4: { + for (int idx = 100; idx >= 0; idx -= 5) { + _globals->_scenePalette.fade(adjustData, false, idx); + g_system->updateScreen(); + g_system->delayMillis(10); + } + + scene->_hotspot4.postInit(); + scene->_hotspot4.setVisage(4150); + scene->_hotspot4.setStrip(2); + scene->_hotspot4.setPosition(Common::Point(166, 157)); + + scene->_hotspot1.postInit(); + scene->_hotspot1.setVisage(4156); + scene->_hotspot1.setStrip(1); + scene->_hotspot1.setFrame(1); + + setDelay(120); + break; + } + case 5: + _globals->_scenePalette.loadPalette(4150); + _globals->_scenePalette.refresh(); + setDelay(60); + break; + case 6: + scene->_stripManager.start(4522, this); + break; + case 7: + for (int idx = 100; idx >= 0; idx -= 5) { + _globals->_scenePalette.fade(adjustData, false, idx); + g_system->updateScreen(); + g_system->delayMillis(10); + } + + scene->_hotspot4.remove(); + scene->_hotspot1.setVisage(4157); + scene->_hotspot1.animate(ANIM_MODE_NONE, NULL); + scene->_hotspot1.setStrip(1); + scene->_hotspot1.setFrame(1); + scene->_hotspot1.show(); + + _globals->_player.setVisage(4200); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setStrip(3); + _globals->_player.setPosition(Common::Point(139, 166)); + _globals->_player._moveDiff = Common::Point(7, 3); + _globals->_player.show(); + + setDelay(120); + break; + case 8: + _globals->_scenePalette.loadPalette(4150); + _globals->_scenePalette.refresh(); + setDelay(30); + break; + case 9: + scene->_stripManager.start(4523, this); + break; + case 10: + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player._moveDiff = Common::Point(7, 4); + _globals->_player.setStrip(3); + _globals->_player.enableControl(); + + remove(); + break; + } +} + +void Scene4150::Action2::signal() { + Scene4150 *scene = (Scene4150 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(3); + break; + case 1: + scene->_hotspot1.setVisage(4152); + scene->_hotspot1.setStrip(1); + scene->_hotspot1.setFrame(1); + scene->_hotspot1.animate(ANIM_MODE_5, this); + + _globals->_player.animate(ANIM_MODE_5, NULL); + break; + case 2: + _globals->_player.hide(); + scene->_hotspot1.setVisage(4153); + scene->_hotspot1.setStrip(1); + scene->_hotspot1.setFrame(1); + scene->_hotspot1.animate(ANIM_MODE_5, this); + break; + case 3: + remove(); + break; + } +} + +void Scene4150::Action3::signal() { + Scene4150 *scene = (Scene4150 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(15); + break; + case 1: + _globals->_player.checkAngle(&scene->_hotspot3); + + if (_globals->_inventory._rope._sceneNumber == 1) { + scene->_hotspot3.postInit(); + scene->_hotspot3.setVisage(4150); + scene->_hotspot3.setPosition(Common::Point(175, 70)); + + _globals->_inventory._rope._sceneNumber = 4150; + _globals->_sceneItems.push_front(&scene->_hotspot3); + } else { + _globals->_inventory._rope._sceneNumber = 1; + scene->_hotspot3.remove(); + } + + _globals->_player.enableControl(); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene4150::HotspotGroup1::doAction(int action) { + Scene4150 *scene = (Scene4150 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4150, 0); + break; + case OBJECT_ROPE: + scene->setAction(&scene->_action3); + break; + } +} + +void Scene4150::HotspotGroup3::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4150, _globals->getFlag(46) ? 9 : 8); + _globals->setFlag(46); + break; + case CURSOR_USE: + SceneItem::display2(4150, 30); + break; + } +} + +void Scene4150::HotspotGroup6::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4150, _globals->getFlag(47) ? 16 : 15); + _globals->setFlag(47); + break; + case CURSOR_USE: + SceneItem::display2(4150, 31); + break; + } +} + +void Scene4150::Hotspot3::doAction(int action) { + Scene4150 *scene = (Scene4150 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4150, 20); + break; + case CURSOR_USE: + scene->setAction(&scene->_action3); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene4150::Scene4150(): + _hotspot1(0, CURSOR_LOOK, 4000, 17, CURSOR_USE, 4150, 21, CURSOR_TALK, 4150, 21, + OBJECT_SCANNER, 4150, 22, OBJECT_STUNNER, 4150, 23, LIST_END), + _hotspot2(0, CURSOR_LOOK, 4150, 4, CURSOR_USE, 4150, 24, LIST_END), + _hotspot7(0, CURSOR_LOOK, 4150, 1, CURSOR_USE, 4150, 25, OBJECT_ROPE, 4150, 26, LIST_END), + _hotspot8(0, CURSOR_LOOK, 4150, 1, CURSOR_USE, 4150, 25, OBJECT_ROPE, 4150, 26, LIST_END), + _hotspot9(0, CURSOR_LOOK, 4150, 2, CURSOR_USE, 4150, 27, OBJECT_SCANNER, 4150, 28, + OBJECT_STUNNER, 4150, 32, LIST_END), + _hotspot10(0, CURSOR_LOOK, 4150, 5, CURSOR_USE, 4150, 29, LIST_END), + _hotspot11(0, CURSOR_LOOK, 4150, 6, CURSOR_USE, 4150, 29, LIST_END), + _hotspot12(0, CURSOR_LOOK, 4150, 7, CURSOR_USE, 4150, 29, LIST_END), + _hotspot17(0, CURSOR_LOOK, 4150, 10, CURSOR_USE, 4150, 27, OBJECT_STUNNER, 4150, 32, LIST_END), + _hotspot18(0, CURSOR_LOOK, 4150, 11, CURSOR_USE, 4150, 32, OBJECT_STUNNER, 4150, 27, LIST_END), + _hotspot19(0, CURSOR_LOOK, 4150, 12, CURSOR_USE, 4150, 29, LIST_END), + _hotspot20(0, CURSOR_LOOK, 4150, 13, CURSOR_USE, 4150, 29, LIST_END), + _hotspot21(0, CURSOR_LOOK, 4150, 13, CURSOR_USE, 4150, 29, LIST_END), + _hotspot22(0, CURSOR_LOOK, 4150, 13, CURSOR_USE, 4150, 29, LIST_END), + _hotspot23(0, CURSOR_LOOK, 4150, 14, CURSOR_USE, 4150, 27, OBJECT_STUNNER, 4150, 32, LIST_END), + _hotspot24(0, CURSOR_LOOK, 4150, 14, CURSOR_USE, 4150, 27, OBJECT_STUNNER, 4150, 32, LIST_END) + { +} + +void Scene4150::postInit(SceneObjectList *OwnerList) { + loadScene(4150); + Scene::postInit(); + setZoomPercents(60, 85, 200, 100); + + _stripManager.addSpeaker(&_speakerQR); + _stripManager.addSpeaker(&_speakerCDL); + _stripManager.addSpeaker(&_speakerQText); + + _hotspot2.postInit(); + _hotspot2.setVisage(4171); + _hotspot2.animate(ANIM_MODE_2, NULL); + _hotspot2.setPriority2(100); + _hotspot2.setPosition(Common::Point(76, 147)); + + _hotspot1.postInit(); + _hotspot1.setPosition(Common::Point(177, 201)); + + if (_globals->getFlag(44)) { + _globals->_player.postInit(); + _globals->_player.setVisage(4200); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setStrip(2); + _globals->_player.setPosition(Common::Point(328, 160)); + _globals->_player._moveDiff = Common::Point(7, 4); + _globals->_player.disableControl(); + + _sceneMode = 4151; + setAction(&_sequenceManager, this, 4151, &_globals->_player, NULL); + + _hotspot1.setVisage(4157); + _hotspot1.setPosition(Common::Point(177, 201)); + } else { + _globals->_player.postInit(); + _globals->_player.setVisage(4154); + _globals->_player._canWalk = false; + _globals->_player.setPosition(Common::Point(198, 202)); + _globals->_player.disableControl(); + + _hotspot1.setVisage(4152); + setAction(&_action1); + _globals->setFlag(44); + } + + if (_globals->_inventory._rope._sceneNumber == 4150) { + _hotspot3.postInit(); + _hotspot3.setVisage(4150); + _hotspot3.setPosition(Common::Point(175, 70)); + + _globals->_sceneItems.push_back(&_hotspot3); + } + + _globals->_sceneItems.push_back(&_hotspot1); + + _hotspot5.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + _hotspot6.setBounds(Rect(28, 121, 80, 148)); + _hotspot7.setBounds(Rect(27, 17, 127, 100)); + _hotspot8.setBounds(Rect(62, 11, 117, 22)); + _hotspot9.setBounds(Rect(48, 78, 104, 94)); + _hotspot10.setBounds(Rect(32, 107, 58, 119)); + _hotspot11.setBounds(Rect(1, 130, 17, 163)); + _hotspot12.setBounds(Rect(1, 158, 78, 197)); + _hotspot13.setBounds(Rect(253, 11, 274, 188)); + _hotspot14.setBounds(Rect(4, 15, 29, 153)); + _hotspot15.setBounds(Rect(127, 22, 146, 133)); + _hotspot16.setBounds(Rect(165, 22, 181, 141)); + _hotspot17.setBounds(Rect(186, 31, 217, 52)); + _hotspot18.setBounds(Rect(200, 31, 251, 86)); + _hotspot19.setBounds(Rect(183, 81, 234, 111)); + _hotspot20.setBounds(Rect(188, 120, 219, 142)); + _hotspot21.setBounds(Rect(235, 122, 249, 145)); + _hotspot22.setBounds(Rect(283, 125, 320, 146)); + _hotspot23.setBounds(Rect(284, 27, 306, 160)); + _hotspot24.setBounds(Rect(257, 72, 284, 99)); + _hotspot25.setBounds(Rect(183, 155, 316, 190)); + _hotspot26.setBounds(Rect(98, 169, 238, 198)); + + _globals->_sceneItems.addItems(&_hotspot24, &_hotspot23, &_hotspot13, &_hotspot25, + &_hotspot26, &_hotspot19, &_hotspot22, &_hotspot20, &_hotspot17, &_hotspot16, + &_hotspot15, &_hotspot11, &_hotspot14, &_hotspot18, &_hotspot21, &_hotspot12, + &_hotspot10, &_hotspot9, &_hotspot8, &_hotspot7, &_hotspot6, &_hotspot2, + &_hotspot5, NULL); + + _globals->_soundHandler.startSound(165); + _soundHandler.startSound(311); +} + +void Scene4150::signal() { + if (_sceneMode == 4151) + _globals->_player.enableControl(); + else if (_sceneMode == 4152) + _globals->_sceneManager.changeScene(4100); +} + +void Scene4150::dispatch() { + Scene::dispatch(); + + if (!_action && (_globals->_player._position.x >= 316)) { + _globals->_soundHandler.proc1(NULL); + _globals->_player.disableControl(); + _sceneMode = 4152; + setAction(&_sequenceManager, this, 4152, &_globals->_player, NULL); + } +} + +/*-------------------------------------------------------------------------- + * Scene 4000 - Village + * + *--------------------------------------------------------------------------*/ + +void Scene4250::Action1::signal() { + Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(3); + break; + case 1: + ADD_MOVER_NULL(_globals->_player, 6, 190); + ADD_MOVER_NULL(scene->_hotspot3, 9, 195); + ADD_MOVER(scene->_hotspot1, 12, 185); + break; + case 2: + setDelay(30); + break; + case 3: + scene->_stripManager.start(4450, this); + break; + case 4: + case 7: + setDelay(15); + break; + case 5: + ADD_PLAYER_MOVER(220, 175); + scene->_hotspot1.setPriority2(105); + ADD_PLAYER_MOVER_NULL(scene->_hotspot1, 197, 173); + break; + case 6: + scene->_stripManager.start(4470, this); + break; + case 8: + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene4250::Action2::signal() { + Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + ADD_PLAYER_MOVER(247, 182); + break; + case 1: + _globals->_player.setVisage(2670); + _globals->_player.changeZoom(50); + _globals->_player.setStrip(3); + _globals->_player.setFrame(1); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 2: + if ((_globals->_stripNum == 9000) || (_globals->_stripNum == 4300)) { + scene->_stripManager.start(4205, this); + } else { + scene->_stripManager.start(4490, this); + } + break; + case 3: + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 4: + _globals->_player.setVisage(2602); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.changeZoom(70); + + if ((_globals->_stripNum == 9000) || (_globals->_stripNum == 4300)) { + _globals->_player.enableControl(); + remove(); + } else { + ADD_PLAYER_MOVER(6, 180); + ADD_PLAYER_MOVER_NULL(scene->_hotspot1, 12, 185); + } + break; + case 5: + ADD_PLAYER_MOVER(-16, 180); + ADD_PLAYER_MOVER_NULL(scene->_hotspot1, -12, 185); + scene->_hotspot3.setStrip2(2); + ADD_MOVER_NULL(scene->_hotspot5, -30, 195); + break; + case 6: + _globals->clearFlag(59); + _globals->clearFlag(70); + _globals->clearFlag(37); + _globals->clearFlag(114); + _globals->clearFlag(36); + _globals->clearFlag(43); + _globals->_sceneManager.changeScene(2100); + break; + } +} + +void Scene4250::Action3::signal() { + Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(3); + break; + case 1: + scene->_stripManager.start(4480, this); + break; + case 2: + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene4250::Action4::signal() { + Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(3); + break; + case 1: + _globals->_player.addMover(NULL); + scene->_stripManager.start((_globals->_inventory._helmet._sceneNumber == 4250) ? 4259 : 4256, this); + break; + case 2: + ADD_PLAYER_MOVER(_globals->_player._position.x + 5, _globals->_player._position.y); + break; + case 3: + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene4250::Action5::signal() { + Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(3); + break; + case 1: + scene->_hotspot4.setPriority2(195); + scene->_hotspot1.setPriority2(105); + ADD_MOVER_NULL(_globals->_player, 6, 185); + ADD_MOVER_NULL(scene->_hotspot4, 9, 190); + ADD_MOVER(scene->_hotspot1, 12, 180); + break; + case 2: + ADD_PLAYER_MOVER(252, 176); + ADD_PLAYER_MOVER_NULL(scene->_hotspot1, 197, 173); + ADD_PLAYER_MOVER_NULL(scene->_hotspot4, 239, 195); + break; + case 3: + scene->_hotspot4.setPriority2(-1); + scene->_hotspot1.setStrip(5); + scene->_hotspot4.setStrip(7); + _globals->_player.enableControl(); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene4250::Hotspot1::doAction(int action) { + Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4250, (_globals->_inventory._helmet._sceneNumber == 4250) ? 19 : 14); + break; + case CURSOR_TALK: + _globals->_player.disableControl(); + if (!_globals->_sceneObjects->contains(&scene->_hotspot4)) { + scene->setAction(&scene->_action3); + } else { + scene->_sceneMode = 4260; + if (_globals->_inventory._helmet._sceneNumber == 4250) { + scene->_sceneMode = 4265; + scene->setAction(&scene->_sequenceManager, scene, 4265, this, NULL); + } else { + scene->setAction(&scene->_sequenceManager, scene, + _globals->_sceneObjects->contains(&scene->_hotspot6) ? 4260 : 4262, this, NULL); + } + } + break; + case OBJECT_SCANNER: + if (_globals->_inventory._helmet._sceneNumber == 4250) + SceneItem::display2(4250, 21); + else + SceneHotspot::doAction(action); + break; + case OBJECT_STUNNER: + if (_globals->_inventory._helmet._sceneNumber == 4250) + SceneItem::display2(4250, 22); + else + SceneHotspot::doAction(action); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4250::Hotspot2::doAction(int action) { + Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + case CURSOR_USE: + SceneItem::display2(4250, 16); + break; + case OBJECT_SCANNER: + if ((_globals->_stripNum == 9000) || (_globals->_stripNum == 4300)) + scene->setAction(&scene->_action2); + else if (_globals->getFlag(55)) + SceneItem::display2(4250, 17); + else { + _globals->setFlag(55); + scene->setAction(&scene->_action2); + } + break; + case OBJECT_STASIS_NEGATOR: + _globals->_player.disableControl(); + scene->_sceneMode = 4252; + scene->setAction(&scene->_sequenceManager, scene, 4252, &_globals->_player, this, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4250::Hotspot4::doAction(int action) { + Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4250, (_globals->_inventory._helmet._sceneNumber == 4250) ? 18 : 5); + break; + case OBJECT_SCANNER: + if (_globals->_inventory._helmet._sceneNumber == 4250) + SceneItem::display2(4250, 21); + else + SceneHotspot::doAction(action); + break; + case OBJECT_STUNNER: + if (_globals->_inventory._helmet._sceneNumber == 4250) + SceneItem::display2(4250, 22); + else + SceneHotspot::doAction(action); + break; + case CURSOR_TALK: + _globals->_player.disableControl(); + if (!_globals->_sceneObjects->contains(&scene->_hotspot6)) { + scene->_sceneMode = 4254; + scene->setAction(&scene->_sequenceManager, scene, 4263, NULL); + } else { + scene->_sceneMode = 4254; + + if (_globals->_inventory._helmet._sceneNumber == 4250) { + scene->_sceneMode = 4266; + scene->setAction(&scene->_sequenceManager, scene, 4266, this, NULL); + } else { + scene->setAction(&scene->_sequenceManager, scene, + (_globals->_inventory._concentrator._sceneNumber == 1) ? 4255 : 4254, NULL); + } + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4250::Hotspot6::doAction(int action) { + Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4250, (_globals->_inventory._helmet._sceneNumber == 4250) ? 7 : 6); + break; + case OBJECT_SCANNER: + SceneItem::display2(4250, (_globals->_inventory._helmet._sceneNumber == 4250) ? 1 : 2); + break; + case OBJECT_STUNNER: + SceneItem::display2(4250, (_globals->_inventory._helmet._sceneNumber == 4250) ? 20 : 3); + break; + case OBJECT_HELMET: + _globals->_soundHandler.startSound(354); + _globals->_player.disableControl(); + _globals->_inventory._helmet._sceneNumber = 4250; + + if (_globals->_inventory._concentrator._sceneNumber == 1) { + if (_globals->getFlag(115)) { + scene->_sceneMode = 4269; + scene->setAction(&scene->_sequenceManager, scene, 4269, this, NULL); + } else { + _globals->setFlag(115); + _globals->_events.setCursor(CURSOR_WALK); + scene->setAction(&scene->_sequenceManager, scene, 4256, this, NULL); + } + } else if (_globals->_inventory._keyDevice._sceneNumber == 1) { + scene->_sceneMode = 4267; + scene->setAction(&scene->_sequenceManager, scene, 4267, this, NULL); + } else if (_globals->_inventory._keyDevice._sceneNumber == 4300) { + scene->_sceneMode = 4268; + scene->setAction(&scene->_sequenceManager, scene, 4268, this, NULL); + } else { + _globals->_events.setCursor(CURSOR_WALK); + ADD_MOVER_NULL(scene->_hotspot1, 241, 169); + scene->_sceneMode = 4261; + scene->setAction(&scene->_sequenceManager, scene, 4261, &_globals->_player, this, NULL); + } + break; + case OBJECT_NULLIFIER: + if (_globals->_inventory._helmet._sceneNumber == 4250) { + _globals->_soundHandler.startSound(353); + _globals->_player.disableControl(); + _globals->_inventory._helmet._sceneNumber = 1; + + scene->_sceneMode = 4257; + scene->setAction(&scene->_sequenceManager, scene, 4257, &_globals->_player, this, NULL); + } else { + SceneItem::display2(4250, 4); + } + break; + case CURSOR_TALK: + if (_globals->_inventory._helmet._sceneNumber == 4250) + doAction(OBJECT_HELMET); + else { + _globals->_player.disableControl(); + scene->_sceneMode = 4264; + scene->setAction(&scene->_sequenceManager, scene, 4264, this, NULL); + } + break; + case CURSOR_USE: + if (_globals->_inventory._helmet._sceneNumber == 4250) + doAction(OBJECT_HELMET); + else { + _globals->_player.disableControl(); + if ((_globals->_inventory._items._sceneNumber != 1) || (_globals->_inventory._concentrator._sceneNumber != 1)) { + scene->_sceneMode = 4258; + scene->setAction(&scene->_sequenceManager, scene, 4258, this, NULL); + } else { + scene->_hotspot2.postInit(); + scene->_hotspot2.setVisage(4251); + scene->_hotspot2.setFrame(scene->_hotspot2.getFrameCount()); + scene->_hotspot2.setPosition(Common::Point(267, 172)); + scene->_hotspot2.hide(); + + scene->_sceneMode = 4259; + scene->setAction(&scene->_sequenceManager, scene, 4259, &_globals->_player, this, &scene->_hotspot2, NULL); + } + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4250::Hotspot8::doAction(int action) { + Scene4250 *scene = (Scene4250 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + case CURSOR_USE: + _globals->_sceneManager.changeScene(4300); + break; + case OBJECT_SCANNER: + SceneItem::display2(4250, 24); + break; + case OBJECT_STUNNER: + SceneItem::display2(4250, 25); + break; + case OBJECT_STASIS_NEGATOR: + _globals->_player.disableControl(); + scene->_sceneMode = 4270; + scene->setAction(&scene->_sequenceManager, scene, + (_globals->_inventory._helmet._sceneNumber == 4250) ? 4270 : 4271, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene4250::Scene4250(): + _hotspot7(0, CURSOR_LOOK, 4250, 0, LIST_END) { +} + +void Scene4250::postInit(tSage::SceneObjectList *OwnerList) { + loadScene(4250); + Scene::postInit(); + setZoomPercents(160, 90, 185, 100); + + _stripManager.addSpeaker(&_speakerSR); + _stripManager.addSpeaker(&_speakerSL); + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerGameText); + _stripManager.addSpeaker(&_speakerQL); + _stripManager.addSpeaker(&_speakerQR); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerPText); + _stripManager.addSpeaker(&_speakerMText); + _stripManager.addSpeaker(&_speakerFLText); + + _speakerSText.setTextPos(Common::Point(40, 40)); + _speakerPText.setTextPos(Common::Point(40, 100)); + _hotspot8._sceneRegionId = 16; + + _globals->_player.postInit(); + _globals->_player.setVisage(2602); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setPosition(Common::Point(-13, 190)); + _globals->_player.changeZoom(-1); + _globals->_player._moveDiff = Common::Point(4, 1); + + _hotspot1.postInit(); + _hotspot1.setVisage(2801); + _hotspot1.animate(ANIM_MODE_1, NULL); + _hotspot1.setObjectWrapper(new SceneObjectWrapper()); + _hotspot1.setPosition(Common::Point(-18, 185)); + _hotspot1.changeZoom(-1); + _hotspot1._moveDiff = Common::Point(4, 1); + _globals->_sceneItems.push_back(&_hotspot1); + + if (_globals->_sceneManager._previousScene == 4300) { + _hotspot5.postInit(); + _hotspot5.setVisage(4250); + _hotspot5.setPosition(Common::Point(268, 168)); + _hotspot5.setPriority2(1); + + _hotspot4.postInit(); + _hotspot4.setVisage(2701); + _hotspot4.animate(ANIM_MODE_1, NULL); + _hotspot4.setObjectWrapper(new SceneObjectWrapper()); + _hotspot4.setPosition(Common::Point(272, 175)); + _hotspot4.setStrip(2); + _hotspot4._moveDiff = Common::Point(4, 1); + _hotspot4.changeZoom(70); + _globals->_sceneItems.push_back(&_hotspot4); + + _hotspot1.setPosition(Common::Point(197, 173)); + _hotspot1.changeZoom(70); + + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setPosition(Common::Point(252, 176)); + _globals->_player.changeZoom(70); + + _hotspot6.postInit(); + _hotspot6.setVisage(4302); + _hotspot6.setStrip(4); + _hotspot6.setFrame(3); + _hotspot6.changeZoom(50); + _hotspot6.setPriority2(70); + _hotspot6.setPosition(Common::Point(261, 175)); + + if (_globals->_inventory._helmet._sceneNumber == 4250) { + _hotspot6.setStrip(6); + _hotspot6.setFrame(_hotspot6.getFrameCount()); + } + + if (_globals->getFlag(98)) { + _globals->_sceneItems.push_front(&_hotspot6); + } else { + _hotspot6.hide(); + if ((_globals->_stripNum == 4300) || (_globals->_stripNum == 4301)) { + _globals->setFlag(98); + _globals->_player.setVisage(4302); + _globals->_player.setStrip(5); + _globals->_player.changeZoom(50); + _globals->_player.disableControl(); + + _hotspot4.setPosition(Common::Point(239, 195)); + _sceneMode = 4253; + _globals->_sceneItems.push_front(&_hotspot6); + + setAction(&_sequenceManager, this, 4253, &_globals->_player, NULL); + } + } + } else if (_globals->_stripNum == 9000) { + _hotspot4.postInit(); + _hotspot4.setVisage(2701); + _hotspot4.animate(ANIM_MODE_1, NULL); + _hotspot4.setObjectWrapper(new SceneObjectWrapper()); + _hotspot4.setPosition(Common::Point(-15, 195)); + _hotspot4._moveDiff = Common::Point(4, 1); + _globals->_sceneItems.push_back(&_hotspot4); + + setAction(&_action5); + } else { + _hotspot3.postInit(); + _hotspot3.setVisage(4006); + _hotspot3.animate(ANIM_MODE_1, NULL); + _hotspot3.setObjectWrapper(new SceneObjectWrapper()); + _hotspot3.setPosition(Common::Point(-15, 195)); + _hotspot3.setStrip2(3); + _hotspot3._moveDiff = Common::Point(4, 1); + + setAction(&_action1); + _globals->clearFlag(43); + _globals->clearFlag(114); + _globals->clearFlag(36); + } + + if (_globals->getFlag(17)) { + _globals->_sceneItems.push_back(&_hotspot8); + } else { + _hotspot2.postInit(); + _hotspot2.setVisage(4251); + _hotspot2.setStrip2(1); + _hotspot2.setPriority2(2); + _hotspot2.setFrame(1); + _hotspot2.setPosition(Common::Point(267, 172)); + + _globals->_sceneItems.push_back(&_hotspot2); + } + + _hotspot7.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + _globals->_sceneItems.push_back(&_hotspot7); + _globals->_soundHandler.startSound(185); +} + +void Scene4250::signal() { + switch (_sceneMode) { + case 4252: + _globals->setFlag(17); + _globals->_sceneManager.changeScene(4301); + break; + case 4253: + if (_globals->_stripNum == 4301) { + ADD_MOVER_NULL(_hotspot1, 241, 169); + setAction(&_sequenceManager, this, 4261, &_globals->_player, &_hotspot6, NULL); + } else { + _globals->_player.enableControl(); + } + break; + case 4254: + case 4256: + case 4257: + case 4258: + case 4260: + case 4264: + case 4265: + case 4266: + case 4267: + case 4268: + case 4269: + case 4270: + _globals->_player.enableControl(); + break; + case 4255: + case 4262: + case 4263: + break; + case 4259: + _globals->_soundHandler.startSound(360); + _globals->_sceneManager.changeScene(9900); + break; + case 4261: + _globals->_inventory._keyDevice._sceneNumber = 1; + _globals->_player.enableControl(); + break; + } +} + +void Scene4250::dispatch() { + if (_globals->_player.getRegionIndex() == 8) + _globals->_player.changeZoom(90 - (_globals->_player._position.y - 153)); + if (_globals->_player.getRegionIndex() == 12) + _globals->_player.changeZoom(70); + if (_globals->_player.getRegionIndex() == 15) { + _globals->_player.changeZoom(-1); + _globals->_player.setPriority2(-1); + } + + if (_hotspot1.getRegionIndex() == 8) + _hotspot1.changeZoom(90 - (_hotspot1._position.y - 153)); + if (_hotspot1.getRegionIndex() == 12) + _hotspot1.changeZoom(70); + if (_hotspot1.getRegionIndex() == 15) { + _hotspot1.changeZoom(-1); + _hotspot1.setPriority2(-1); + } + + if (_hotspot4.getRegionIndex() == 8) + _hotspot4.changeZoom(90 - (_hotspot4._position.y - 153)); + if (_hotspot4.getRegionIndex() == 12) + _hotspot4.changeZoom(70); + if (_hotspot4.getRegionIndex() == 15) { + _hotspot4.changeZoom(-1); + _hotspot4.setPriority2(-1); + } + + Scene::dispatch(); + + if (!_action) { + if (!_globals->getFlag(55) && (_globals->_player.getRegionIndex() == 12)) { + setAction(&_action4); + } + + if (_globals->_sceneObjects->contains(&_hotspot6) && (_globals->_player.getRegionIndex() == 12)) + setAction(&_action4); + } +} + +/*-------------------------------------------------------------------------- + * Scene 4300 - Village - Slaver Ship + * + *--------------------------------------------------------------------------*/ + +void Scene4300::Action1::signal() { + Scene4300 *scene = (Scene4300 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->setFlag(56); + _globals->_scenePalette.addRotation(240, 254, -1); + scene->_hotspot7.animate(ANIM_MODE_6, this); + _globals->_soundHandler.startSound(164); + break; + case 1: + _globals->_soundHandler.startSound(340); + scene->_soundHandler1.startSound(341); + scene->_hotspot1.remove(); + setDelay(3); + break; + case 2: + scene->_soundHandler1.startSound(341); + scene->_hotspot2.remove(); + setDelay(6); + break; + case 3: + scene->_soundHandler1.startSound(341); + scene->_hotspot3.remove(); + setDelay(6); + break; + case 4: + scene->_soundHandler1.startSound(341); + scene->_hotspot4.remove(); + setDelay(12); + break; + case 5: + scene->_soundHandler1.startSound(341); + scene->_hotspot5.remove(); + setDelay(12); + break; + case 6: + scene->_soundHandler1.startSound(341); + scene->_hotspot6.remove(); + setDelay(60); + break; + case 7: + scene->_hotspot10.setPriority2(250); + scene->_hotspot10.animate(ANIM_MODE_5, this); + break; + case 8: + scene->_hotspot13.show(); + scene->_stripManager.start(8015, this, scene); + break; + case 9: + _globals->_soundHandler.startSound(350); + _globals->_sceneManager._fadeMode = FADEMODE_GRADUAL; + _globals->_events.setCursor(CURSOR_USE); + _globals->_player.enableControl(); + + remove(); + break; + } +} + +void Scene4300::Action2::signal() { + Scene4300 *scene = (Scene4300 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(3); + break; + case 1: + scene->_stripManager.start(8016, this, scene); + break; + case 2: + _globals->_player.enableControl(); + remove(); + break; + } +} + + +/*--------------------------------------------------------------------------*/ + +void Scene4300::Hotspot8::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4300, 15); + break; + case CURSOR_USE: + SceneItem::display2(4300, 18); + break; + case OBJECT_SCANNER: + SceneItem::display2(4300, 14); + break; + case OBJECT_STUNNER: + SceneItem::display2(4300, 19); + break; + case OBJECT_KEY_DEVICE: + _globals->_inventory._keyDevice._sceneNumber = 4300; + _globals->_scenePalette.addRotation(240, 254, -1); + animate(ANIM_MODE_5, NULL); + + _globals->setFlag(99); + _globals->_sceneItems.push_back(this); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4300::Hotspot9::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + if ((_globals->_inventory._stasisBox2._sceneNumber == 4300) || + (_globals->_inventory._concentrator._sceneNumber == 1)) + SceneItem::display2(4300, 7); + else + SceneItem::display2(4300, 1); + break; + case CURSOR_USE: + if ((_globals->_inventory._stasisBox2._sceneNumber == 4300) || + (_globals->_inventory._concentrator._sceneNumber == 1)) + SceneItem::display2(4300, 7); + else + SceneItem::display2(4300, 3); + break; + case OBJECT_STUNNER: + SceneItem::display2(4300, 24); + break; + case OBJECT_SCANNER: + if ((_globals->_inventory._stasisBox2._sceneNumber == 4300) || + (_globals->_inventory._concentrator._sceneNumber != 1)) + SceneItem::display2(4300, 22); + else + SceneItem::display2(4300, 23); + break; + default: + NamedHotspot::doAction(action); + break; + } +} + +void Scene4300::Hotspot10::doAction(int action) { + Scene4300 *scene = (Scene4300 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4300, 2); + break; + case CURSOR_TALK: + _globals->_player.disableControl(); + scene->setAction(&scene->_action2); + break; + case OBJECT_SCANNER: + SceneItem::display2(4300, 20); + break; + case OBJECT_STUNNER: + SceneItem::display2(4300, 21); + break; + case CURSOR_USE: + case OBJECT_HELMET: + _globals->_stripNum = (action == CURSOR_USE) ? 4300 : 4301; + _globals->_events.setCursor(CURSOR_NONE); + _globals->_sceneManager.changeScene(4250); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4300::Hotspot15::signal() { + Scene4300 *scene = (Scene4300 *)_globals->_sceneManager._scene; + + scene->_soundHandler2.startSound(345); + + _strip = (_globals->_randomSource.getRandomNumber(6) < 2) ? 2 : 1; + if ((_globals->_inventory._stasisBox2._sceneNumber == 4300) || + (_globals->_inventory._concentrator._sceneNumber == 1)) { + setStrip(1); + setFrame(1); + animate(ANIM_MODE_NONE, NULL); + } else { + animate(ANIM_MODE_5, this); + } +} + +void Scene4300::Hotspot16::doAction(int action) { + Scene4300 *scene = (Scene4300 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4300, 8); + break; + case CURSOR_USE: + if ((_globals->_inventory._stasisBox2._sceneNumber != 4300) && + (_globals->_inventory._concentrator._sceneNumber != 4300)) { + SceneItem::display2(4300, 16); + } else { + scene->_sceneMode = 4302; + scene->setAction(&scene->_sequenceManager, scene, 4302, this, NULL); + } + break; + case OBJECT_SCANNER: + SceneItem::display2(4300, 27); + break; + case OBJECT_STUNNER: + SceneItem::display2(4300, 24); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene4300::Hotspot17::doAction(int action) { + Scene4300 *scene = (Scene4300 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4300, (_globals->_inventory._stasisBox2._sceneNumber == 4300) ? 17 : 11); + break; + case CURSOR_USE: + if (_globals->_inventory._stasisBox2._sceneNumber != 4300) + SceneItem::display2(4300, 13); + else { + _globals->_scenePalette.clearListeners(); + remove(); + + SceneItem::display2(4300, 12); + _globals->_inventory._concentrator._sceneNumber = 1; + } + break; + case OBJECT_SCANNER: + SceneItem::display2(4300, 25); + break; + case OBJECT_STUNNER: + SceneItem::display2(4300, 26); + break; + case OBJECT_STASIS_BOX2: + scene->_soundHandler1.startSound(352); + _globals->_events.setCursor(CURSOR_USE); + scene->_sceneMode = 4303; + + scene->setAction(&scene->_sequenceManager, scene, 4303, this, NULL); + break; + } +} + +void Scene4300::Hotspot19::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4300, 9); + break; + case OBJECT_SCANNER: + SceneItem::display2(4300, 28); + break; + case OBJECT_STUNNER: + SceneItem::display2(4300, 24); + break; + case CURSOR_USE: + if ((_globals->_inventory._stasisBox2._sceneNumber != 4300) && + (_globals->_inventory._concentrator._sceneNumber != 4300)) + SceneItem::display2(4300, 10); + else + SceneItem::display2(4300, 29); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene4300::Scene4300(): + _hotspot18(0, CURSOR_LOOK, 4300, 0, LIST_END) { +} + +void Scene4300::postInit(SceneObjectList *OwnerList) { + loadScene(4300); + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerMText); + _stripManager.addSpeaker(&_speakerFLText); + + _hotspot11.setup(76, 97, 102, 127, 4300, 5, 6); + + _hotspot7.postInit(); + _hotspot7.setPosition(Common::Point(90, 128)); + _hotspot7.setVisage(4303); + _hotspot7.setPriority2(250); + _globals->_sceneItems.push_back(&_hotspot7); + + _hotspot9.setup(120, 49, 174, 91, 4300, -1, -1); + + _hotspot15.postInit(); + _hotspot15.setVisage(4300); + _hotspot15.setPosition(Common::Point(149, 79)); + _hotspot15.signal(); + + if (!_globals->getFlag(99)) { + _hotspot8.postInit(); + _hotspot8.setVisage(4300); + _hotspot8.setStrip(3); + _hotspot8.setPosition(Common::Point(196, 47)); + _globals->_sceneItems.push_back(&_hotspot8); + } + + if (_globals->_inventory._concentrator._sceneNumber == 4300) { + _hotspot17.postInit(); + _hotspot17.setVisage(4300); + _hotspot17.setStrip(6); + _hotspot17.setPriority2(1); + _hotspot17.setPosition(Common::Point(200, 69)); + + if (_globals->_inventory._stasisBox2._sceneNumber == 4300) + _hotspot17.setFrame(_hotspot17.getFrameCount()); + + _globals->_sceneItems.push_back(&_hotspot17); + } + + if (!_globals->getFlag(98)) { + _hotspot10.postInit(); + _hotspot10.setVisage(4302); + _hotspot10.setPosition(Common::Point(244, 179)); + _hotspot10.setPriority2(100); + _globals->_sceneItems.push_back(&_hotspot10); + + _hotspot12.postInit(); + _hotspot12.setVisage(4302); + _hotspot12.setStrip2(3); + _hotspot12.setPosition(Common::Point(231, 185)); + _hotspot12.setPriority2(251); + _hotspot12.hide(); + + _hotspot13.postInit(); + _hotspot13.hide(); + _hotspot13.setVisage(4302); + _hotspot13.setStrip2(2); + _hotspot13.setPosition(Common::Point(256, 168)); + _hotspot13.setPriority2(251); + _hotspot13._numFrames = 1; + _hotspot13.animate(ANIM_MODE_8, 0, NULL); + } + + if (_globals->_inventory._items._sceneNumber == 4300) { + _hotspot16.postInit(); + _hotspot16.setVisage(4300); + _hotspot16.setPosition(Common::Point(169, 141)); + _hotspot16.setPriority2(1); + _hotspot16.setStrip(4); + _globals->_sceneItems.push_back(&_hotspot16); + } + + if (_globals->_sceneManager._previousScene == 4301) { + _globals->_player.disableControl(); + _hotspot7.setFrame(_hotspot7.getFrameCount()); + + _hotspot1.postInit(); + _hotspot1.setVisage(4301); + _hotspot1.setPriority2(145); + _hotspot1.setPosition(Common::Point(160, 64)); + + _hotspot2.postInit(); + _hotspot2.setVisage(4301); + _hotspot2.setStrip2(2); + _hotspot2.setPriority2(140); + _hotspot2.setPosition(Common::Point(166, 90)); + + _hotspot3.postInit(); + _hotspot3.setVisage(4301); + _hotspot3.setStrip2(3); + _hotspot3.setPriority2(135); + _hotspot3.setPosition(Common::Point(173, 114)); + + _hotspot4.postInit(); + _hotspot4.setVisage(4301); + _hotspot4.setStrip2(4); + _hotspot4.setPriority2(130); + _hotspot4.setPosition(Common::Point(187, 141)); + + _hotspot5.postInit(); + _hotspot5.setVisage(4301); + _hotspot5.setStrip2(5); + _hotspot5.setPriority2(125); + _hotspot5.setPosition(Common::Point(201, 164)); + + _hotspot6.postInit(); + _hotspot6.setVisage(4301); + _hotspot6.setStrip2(6); + _hotspot6.setPriority2(120); + _hotspot6.setPosition(Common::Point(219, 186)); + + setAction(&_action1); + } else { + _globals->_player.disableControl(); + _sceneMode = 4304; + setAction(&_sequenceManager, this, 4304, NULL); + } + + _hotspot10.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + _hotspot19._sceneRegionId = 0; + _globals->_sceneItems.push_back(&_hotspot19); + _globals->_sceneItems.push_back(&_hotspot18); +} + +void Scene4300::stripCallback(int v) { + switch (v) { + case 1: + _hotspot12.show(); + _hotspot12.animate(ANIM_MODE_7, 0, NULL); + break; + case 2: + _hotspot12.hide(); + break; + } +} + +void Scene4300::remove() { + _globals->_scenePalette.clearListeners(); + Scene::remove(); +} + +void Scene4300::signal() { + switch (_sceneMode) { + case 4302: + _globals->_inventory._items._sceneNumber = 1; + _hotspot16.remove(); + _globals->_player.enableControl(); + break; + case 4303: + _globals->_inventory._stasisBox2._sceneNumber = 4300; + _hotspot15.setStrip(1); + _hotspot15.setFrame(1); + _hotspot15.animate(ANIM_MODE_NONE, NULL); + break; + case 4304: + _hotspot14.postInit(); + _hotspot14.setVisage(4300); + _hotspot14.setStrip(7); + _hotspot14.setPosition(Common::Point(60, 199)); + + _gfxButton.setText(EXIT_MSG); + _gfxButton._bounds.centre(60, 193); + _gfxButton.draw(); + _gfxButton._bounds.expandPanes(); + + _globals->_player.enableControl(); + _globals->_scenePalette.addRotation(240, 254, -1); + break; + } +} + +void Scene4300::dispatch() { + if (_action) + _action->dispatch(); +} + +void Scene4300::process(Event &event) { + Scene::process(event); + if (_gfxButton.process(event)) + _globals->_sceneManager.changeScene(4250); +} + +/*-------------------------------------------------------------------------- + * Scene 4301 - Village - Slaver Ship Keypad + * + *--------------------------------------------------------------------------*/ + +void Scene4301::Action1::synchronise(Serialiser &s) { + Action::synchronise(s); + s.syncAsSint16LE(_field34E); + for (int idx = 0; idx < 6; ++idx) + s.syncAsSint16LE(_indexList[idx]); +} + +void Scene4301::Action1::remove() { + Scene4301 *scene = (Scene4301 *)_globals->_sceneManager._scene; + _globals->_player.enableControl(); + + for (_state = 0; _state < 6; ++_state) + _buttonList[_state].remove(); + + scene->_hotspot3.remove(); + scene->_hotspot2.remove(); + + scene->_hotspot1.animate(ANIM_MODE_6, NULL); + Action::remove(); +} + +void Scene4301::Action1::signal() { + Scene4301 *scene = (Scene4301 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + scene->_soundHandler.startSound(164); + scene->_hotspot1.animate(ANIM_MODE_5, this); + break; + case 1: + _globals->_soundHandler.startSound(335); + _globals->_events.setCursor(CURSOR_USE); + + scene->_hotspot2.postInit(); + scene->_hotspot2.setVisage(4303); + scene->_hotspot2.setStrip(2); + scene->_hotspot2.setFrame(1); + scene->_hotspot2.setPosition(Common::Point(30, 15)); + scene->_hotspot2.setPriority2(255); + + scene->_hotspot3.postInit(); + scene->_hotspot3.setVisage(4303); + scene->_hotspot3.setStrip(2); + scene->_hotspot3.setFrame(2); + scene->_hotspot3.setPosition(Common::Point(48, 29)); + scene->_hotspot3.setPriority2(255); + scene->_hotspot3.hide(); + + _field34E = 0; + _state = 0; + _actionIndex = 2; + break; + case 10: + _globals->_events.setCursor(CURSOR_NONE); + scene->_soundHandler.startSound(337); + if (scene->_hotspot3._flags & OBJFLAG_HIDE) + scene->_hotspot3.show(); + else + scene->_hotspot3.hide(); + setDelay(20); + + if (_state <= 8) + _actionIndex = 10; + ++_state; + break; + case 11: + for (_state = 0; _state < 6; ++_state) + _buttonList[_state].remove(); + + scene->_soundHandler.startSound(338); + scene->_hotspot3.hide(); + + _actionIndex = 2; + _state = 0; + _globals->_events.setCursor(CURSOR_USE); + break; + case 20: + _globals->_player.disableControl(); + scene->_soundHandler.startSound(339); + scene->_hotspot3._frame = 3; + if (scene->_hotspot3._flags & OBJFLAG_HIDE) + scene->_hotspot3.show(); + else + scene->_hotspot3.hide(); + + if (_state <= 8) + _actionIndex = 20; + ++_state; + + setDelay(20); + break; + case 21: + scene->_field68E = true; + remove(); + break; + } +} + +void Scene4301::Action1::process(Event &event) { + Scene4301 *scene = (Scene4301 *)_globals->_sceneManager._scene; + Rect buttonsRect; + + Action::process(event); + if (event.handled || (_actionIndex != 2)) + return; + + buttonsRect = Rect(14, 35, 112, 100); + buttonsRect.translate(30, 15); + + if ((event.eventType == EVENT_BUTTON_DOWN) && buttonsRect.contains(event.mousePos)) { + event.handled = true; + scene->_soundHandler.startSound(336); + + int buttonIndex = ((event.mousePos.y - buttonsRect.top) / 33) * 3 + + ((event.mousePos.x - buttonsRect.left) / 33); + + _buttonList[_state].postInit(); + _buttonList[_state].setVisage(4303); + _buttonList[_state].setStrip(buttonIndex + 3); + _buttonList[_state].setFrame(1); + _buttonList[_state].setPosition(Common::Point((_state % 3) * 25 + 55, (_state / 3) * 25 + 121)); + _buttonList[_state].setPriority2(255); + _buttonList[_state]._numFrames = 25; + _buttonList[_state].animate(ANIM_MODE_5, NULL); + + _indexList[_state++] = buttonIndex; + + if (_state == 6) { + // Six buttons pressed + if ((_indexList[0] == 2) && (_indexList[1] == 3) && (_indexList[2] == 0) && + (_indexList[3] == 4) && (_indexList[4] == 1) && (_indexList[5] == 5)) { + // Entered the correct full combination + _state = 0; + _actionIndex = 20; + } else { + // Incorrect combination entered + _state = 0; + _actionIndex = 10; + } + + signal(); + } + } + + if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) { + event.handled = true; + remove(); + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene4301::Hotspot4::doAction(int action) { + Scene4301 *scene = (Scene4301 *)_globals->_sceneManager._scene; + + if (action == CURSOR_USE) { + _globals->_player.disableControl(); + scene->setAction(&scene->_action1); + } else { + NamedHotspot::doAction(action); + } +} + +void Scene4301::Hotspot5::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(4300, 0); + break; + case CURSOR_USE: + SceneItem::display(4300, 30); + break; + case OBJECT_SCANNER: + SceneItem::display2(4300, 31); + break; + case OBJECT_STUNNER: + SceneItem::display2(4300, 32); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene4301::postInit(SceneObjectList *OwnerList) { + _globals->setFlag(50); + loadScene(4301); + Scene::postInit(); + setZoomPercents(0, 100, 200, 100); + + _field68E = false; + _globals->_inventory._stasisBox2._sceneNumber = 1; + _hotspot4.setup(76, 97, 102, 127, 4300, 5, 6); + + _hotspot1.postInit(); + _hotspot1.setPosition(Common::Point(90, 128)); + _hotspot1.setVisage(4303); + _hotspot1._strip = 1; + _hotspot1._frame = 1; + _hotspot1.setPriority2(250); + + _hotspot5.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + _globals->_sceneItems.push_back(&_hotspot5); + + _globals->_player.enableControl(); +} + +void Scene4301::dispatch() { + if (_action) { + _action->dispatch(); + } else if (_field68E) { + _field68E = 0; + _globals->clearFlag(50); + _globals->_sceneManager._fadeMode = FADEMODE_NONE; + _globals->_sceneManager.setNewScene(4300); + } +} + +} // End of namespace tSage diff --git a/engines/tsage/ringworld_scenes5.h b/engines/tsage/ringworld_scenes5.h new file mode 100644 index 0000000000..e9ad5b62cb --- /dev/null +++ b/engines/tsage/ringworld_scenes5.h @@ -0,0 +1,695 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#ifndef TSAGE_RINGWORLD_SCENES5_H +#define TSAGE_RINGWORLD_SCENES5_H + +#include "common/scummsys.h" +#include "tsage/core.h" +#include "tsage/converse.h" +#include "tsage/ringworld_logic.h" + +namespace tSage { + +class Scene4000: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + class Action5: public Action { + public: + virtual void signal(); + }; + class Action6: public Action { + public: + virtual void signal(); + }; + class Action7: public Action { + public: + virtual void signal(); + }; + class Action8: public Action { + public: + virtual void signal(); + }; + class Action9: public Action { + public: + virtual void signal(); + }; + class Action10: public Action { + public: + virtual void signal(); + }; + class Action11: public Action { + public: + virtual void signal(); + }; + class Action12: public Action { + public: + virtual void signal(); + }; + class Action13: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot7: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot8: public SceneObject { + private: + int _ctr; + public: + virtual void synchronise(Serialiser &s) { + SceneObject::synchronise(s); + s.syncAsUint16LE(_ctr); + } + virtual void doAction(int action); + }; + class Hotspot9: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot10: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot12: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot13: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot17: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot18: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot23: public SceneObject { + public: + virtual void doAction(int action); + }; +public: + SequenceManager _sequenceManager1, _sequenceManager2, _sequenceManager3; + SoundHandler _soundHandler1, _soundHandler2; + SpeakerQR _speakerQR; + SpeakerML _speakerML; + SpeakerMR _speakerMR; + SpeakerSR _speakerSR; + SpeakerCHFL _speakerCHFL; + SpeakerPL _speakerPL; + SpeakerPText _speakerPText; + SpeakerQText _speakerQText; + SpeakerSText _speakerSText; + SpeakerMText _speakerMText; + SpeakerCHFR _speakerCHFR; + SpeakerQL _speakerQL; + SpeakerCHFText _speakerCHFText; + SceneObject _hotspot1, _hotspot2, _hotspot3, _hotspot4, _hotspot5, _hotspot6; + Hotspot7 _hotspot7; + Hotspot8 _hotspot8; + Hotspot9 _hotspot9; + Hotspot10 _hotspot10; + DisplayHotspot _hotspot11; + Hotspot12 _hotspot12; + Hotspot13 _hotspot13; + Hotspot _hotspot14, _hotspot15, _hotspot16; + Hotspot17 _hotspot17; + Hotspot18 _hotspot18; + DisplayHotspot _hotspot19, _hotspot20, _hotspot21, _hotspot22; + Hotspot23 _hotspot23; + DisplayHotspot _hotspot24, _hotspot25, _hotspot26; + SceneObject _hotspot27; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Action5 _action5; + Action6 _action6; + Action7 _action7; + Action8 _action8; + Action9 _action9; + Action10 _action10; + Action11 _action11; + Action12 _action12; + Action13 _action13; + + Scene4000(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene4010: public Scene { +public: + SequenceManager _sequenceManager; + SpeakerQText _speakerQText; + SpeakerSText _speakerSText; + SpeakerMText _speakerMText; + SceneObject _hotspot1, _hotspot2; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); +}; + +class Scene4025: public Scene { + /* Custom classes */ + class Peg; + + class Hole: public SceneObject { + public: + Peg *_pegPtr; + int _armStrip; + Common::Point _newPosition; + + virtual void synchronise(Serialiser &s); + virtual void doAction(int action); + }; + class Peg: public SceneObject { + public: + int _field88; + int _armStrip; + + Peg(): SceneObject() { _field88 = 0; _armStrip = 3; } + virtual void synchronise(Serialiser &s); + virtual void doAction(int action); + }; + + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; +public: + SequenceManager _sequenceManager; + GfxButton _gfxButton; + SceneObject _armHotspot; + Hole _hole1, _hole2, _hole3, _hole4, _hole5; + Peg _peg1, _peg2, _peg3, _peg4, _peg5; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Peg *_pegPtr, *_pegPtr2; + Hole *_holePtr; + + Scene4025(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void synchronise(Serialiser &s); + virtual void remove(); + virtual void signal(); + virtual void process(Event &event); + virtual void dispatch(); +}; + +class Scene4045: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot1: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot2: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot6: public SceneObject { + public: + virtual void doAction(int action); + }; + +public: + SequenceManager _sequenceManager; + SpeakerQR _speakerQR; + SpeakerML _speakerML; + SpeakerPR _speakerPR; + SpeakerPText _speakerPText; + SpeakerQText _speakerQText; + SpeakerQL _speakerQL; + Hotspot1 _hotspot1; + Hotspot2 _hotspot2; + DisplayHotspot _hotspot3; + SceneObject _hotspot4, _hotspot5; + Hotspot6 _hotspot6; + DisplayHotspot _hotspot7, _hotspot8, _hotspot9, _hotspot10; + DisplayHotspot _hotspot11, _hotspot12, _hotspot13, _hotspot14; + Action1 _action1; + Action _action2; + Action _action3; + + Scene4045(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void stripCallback(int v); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene4050: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot14: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot17: public SceneObject { + public: + virtual void doAction(int action); + }; +public: + SpeakerPText _speakerPText; + SpeakerQText _speakerQText; + SpeakerGameText _speakerGameText; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + DisplayHotspot _hotspot1, _hotspot2, _hotspot3, _hotspot4, _hotspot5; + DisplayHotspot _hotspot6, _hotspot7, _hotspot8, _hotspot9, _hotspot10; + DisplayHotspot _hotspot11, _hotspot12, _hotspot13; + Hotspot14 _hotspot14; + SceneObject _hotspot15, _hotspot16; + Hotspot17 _hotspot17; + + Scene4050(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene4100: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + class Action5: public Action { + public: + virtual void signal(); + }; + class Action6: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot1: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot2: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot5: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot6: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot14: public SceneObject { + public: + virtual void doAction(int action); + }; +public: + SequenceManager _sequenceManager; + SpeakerMText _speakerMText; + SpeakerML _speakerML; + SpeakerQText _speakerQText; + SpeakerQR _speakerQR; + SpeakerCHFText _speakerCHFText; + SpeakerCDRText _speakerCDRText; + SpeakerCDR _speakerCDR; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Action5 _action5; + Action6 _action6; + Hotspot1 _hotspot1; + Hotspot2 _hotspot2; + DisplayHotspot _hotspot3, _hotspot4; + Hotspot5 _hotspot5; + Hotspot6 _hotspot6; + DisplayHotspot _hotspot7, _hotspot8, _hotspot9, _hotspot10; + DisplayHotspot _hotspot11, _hotspot12, _hotspot13; + Hotspot14 _hotspot14; + + Scene4100(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene4150: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class HotspotGroup1: public SceneObject { + public: + virtual void doAction(int action); + }; + class HotspotGroup3: public SceneObject { + public: + virtual void doAction(int action); + }; + class HotspotGroup6: public SceneObject { + public: + virtual void doAction(int action); + }; + + class Hotspot3: public SceneObject { + public: + virtual void doAction(int action); + }; + +public: + SequenceManager _sequenceManager; + SoundHandler _soundHandler; + SpeakerQText _speakerQText; + SpeakerQR _speakerQR; + SpeakerCDL _speakerCDL; + Action1 _action1; + Action2 _action2; + Action3 _action3; + DisplayHotspot _hotspot1, _hotspot2; + Hotspot3 _hotspot3; + SceneObject _hotspot4; + HotspotGroup1 _hotspot5, _hotspot6; + DisplayHotspot _hotspot7, _hotspot8, _hotspot9, _hotspot10, _hotspot11, _hotspot12; + HotspotGroup3 _hotspot13, _hotspot14, _hotspot15, _hotspot16; + DisplayHotspot _hotspot17, _hotspot18, _hotspot19, _hotspot20, _hotspot21; + DisplayHotspot _hotspot22, _hotspot23, _hotspot24; + HotspotGroup6 _hotspot25, _hotspot26; + + Scene4150(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene4250: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + class Action5: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot1: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot2: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot4: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot6: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot8: public SceneObject { + public: + virtual void doAction(int action); + }; + +public: + SequenceManager _sequenceManager; + SoundHandler _soundHandler; + SpeakerSR _speakerSR; + SpeakerSL _speakerSL; + SpeakerSText _speakerSText; + SpeakerGameText _speakerGameText; + SpeakerQL _speakerQL; + SpeakerQR _speakerQR; + SpeakerQText _speakerQText; + SpeakerPText _speakerPText; + SpeakerMText _speakerMText; + SpeakerFLText _speakerFLText; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Action5 _action5; + Hotspot1 _hotspot1; + Hotspot2 _hotspot2; + SceneObject _hotspot3; + Hotspot4 _hotspot4; + SceneObject _hotspot5; + Hotspot6 _hotspot6; + DisplayHotspot _hotspot7; + Hotspot8 _hotspot8; + + Scene4250(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene4300: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot8: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot9: public NamedHotspot { + public: + virtual void doAction(int action); + }; + class Hotspot10: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot15: public SceneObject { + public: + virtual void signal(); + }; + class Hotspot16: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot17: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot19: public SceneObject { + public: + virtual void doAction(int action); + }; +public: + SoundHandler _soundHandler1, _soundHandler2; + SequenceManager _sequenceManager; + GfxButton _gfxButton; + SpeakerQText _speakerQText; + SpeakerSText _speakerSText; + SpeakerMText _speakerMText; + SpeakerFLText _speakerFLText; + + SceneObject _hotspot1, _hotspot2, _hotspot3, _hotspot4; + SceneObject _hotspot5, _hotspot6, _hotspot7; + Hotspot8 _hotspot8; + Hotspot9 _hotspot9; + Hotspot10 _hotspot10; + NamedHotspot _hotspot11; + SceneObject _hotspot12, _hotspot13, _hotspot14; + Hotspot15 _hotspot15; + Hotspot16 _hotspot16; + Hotspot17 _hotspot17; + DisplayHotspot _hotspot18; + Hotspot19 _hotspot19; + Action1 _action1; + Action2 _action2; + + Scene4300(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void stripCallback(int v); + virtual void remove(); + virtual void signal(); + virtual void dispatch(); + virtual void process(Event &event); +}; + +class Scene4301: public Scene { + /* Actions */ + class Action1: public ActionExt { + public: + SceneObject _buttonList[6]; + int _field34E; + int _indexList[6]; + + virtual void synchronise(Serialiser &s); + virtual void remove(); + virtual void signal(); + virtual void process(Event &event); + }; + + /* Hotspots */ + class Hotspot4: public NamedHotspot { + public: + virtual void doAction(int action); + }; + class Hotspot5: public NamedHotspot { + public: + virtual void doAction(int action); + }; + +public: + Common::List<int> _list1; + SequenceManager _sequenceManager; + SoundHandler _soundHandler; + Action1 _action1; + SceneObject _hotspot1, _hotspot2, _hotspot3; + Hotspot4 _hotspot4; + Hotspot5 _hotspot5; + bool _field68E; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void dispatch(); + virtual void synchronise(Serialiser &s) { + Scene::synchronise(s); + s.syncAsSint16LE(_field68E); + } +}; + + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/ringworld_scenes6.cpp b/engines/tsage/ringworld_scenes6.cpp new file mode 100644 index 0000000000..ccd857b5f9 --- /dev/null +++ b/engines/tsage/ringworld_scenes6.cpp @@ -0,0 +1,2173 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#include "tsage/ringworld_scenes6.h" +#include "tsage/scenes.h" +#include "tsage/tsage.h" +#include "tsage/staticres.h" + +namespace tSage { + +/*-------------------------------------------------------------------------- + * Scene 5000 - Caverns - Entrance + * + *--------------------------------------------------------------------------*/ + +void Scene5000::Action1::signal() { + Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(10); + break; + case 1: + scene->_soundHandler.startSound(190); + scene->_soundHandler.proc5(true); + ADD_MOVER(scene->_hotspot1, 283, 12); + break; + case 2: + break; + case 3: + scene->_hotspot1._moveDiff.y = 1; + scene->_hotspot4.setPosition(Common::Point(scene->_hotspot1._position.x, + scene->_hotspot1._position.y + 15)); + scene->_hotspot4.show(); + setDelay(15); + break; + case 4: + scene->_soundHandler.proc4(); + ADD_MOVER(scene->_hotspot1, 233, 80); + break; + case 5: + scene->_hotspot3.animate(ANIM_MODE_8, 0, NULL); + scene->_hotspot3.show(); + ADD_MOVER(scene->_hotspot1, 233, 90); + break; + case 6: + scene->_hotspot3.remove(); + scene->_hotspot2.setPosition(Common::Point(233, 76)); + scene->_hotspot2.show(); + scene->_hotspot2.animate(ANIM_MODE_5, this); + + scene->_hotspot4.remove(); + break; + case 7: + setDelay(60); + scene->_hotspot2.remove(); + break; + case 8: + scene->_hotspot5.show(); + scene->_hotspot5.animate(ANIM_MODE_5, this); + break; + case 9: + scene->setAction(&scene->_action2); + break; + } +} + +void Scene5000::Action1::dispatch() { + Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene; + Action::dispatch(); + + if (_actionIndex == 3) { + if (scene->_hotspot1._percent % 2 == 0) { + ++scene->_hotspot1._position.y; + if (scene->_hotspot1._position.x > 233) + --scene->_hotspot1._position.x; + } + + scene->_hotspot1.changeZoom(++scene->_hotspot1._percent); + scene->_hotspot1._flags |= OBJFLAG_PANES; + + if (scene->_hotspot1._percent >= 100) + signal(); + } + + if ((_actionIndex == 5) || (_actionIndex == 6)) { + scene->_hotspot4.setPosition(Common::Point(scene->_hotspot1._position.x, + scene->_hotspot1._position.y + 15)); + } +} + +void Scene5000::Action2::signal() { + Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.setPosition(Common::Point(217, 76)); + setDelay(10); + break; + case 1: + _globals->_player.setStrip2(3); + _globals->_player.animate(ANIM_MODE_1, NULL); + ADD_MOVER(_globals->_player, 214, 89); + break; + case 2: + if (!_globals->getFlag(59)) + setAction(&scene->_action3, this); + _globals->_player.setPriority2(15); + ADD_MOVER(_globals->_player, 208, 100); + break; + case 3: + ADD_MOVER(_globals->_player, 213, 98); + break; + case 4: + ADD_MOVER(_globals->_player, 215, 115); + break; + case 5: + _globals->_player.changeZoom(47); + ADD_MOVER(_globals->_player, 220, 125); + break; + case 6: + ADD_MOVER(_globals->_player, 229, 115); + break; + case 7: + _globals->_player.changeZoom(-1); + _globals->_player.setPriority2(35); + ADD_MOVER(_globals->_player, 201, 166); + break; + case 8: + _globals->_player.updateZoom(); + ADD_MOVER(_globals->_player, 205, 146); + break; + case 9: + _globals->_player.changeZoom(-1); + _globals->_player.setPriority2(50); + ADD_MOVER(_globals->_player, 220, 182); + break; + case 10: + _globals->_player.updateZoom(); + ADD_MOVER(_globals->_player, 208, 163); + break; + case 11: + _globals->_player.changeZoom(-1); + _globals->_player.setStrip2(-1); + _globals->_player.setPriority2(-1); + ADD_MOVER(_globals->_player, 208, 175); + break; + case 12: + _globals->_player.setStrip(8); + _globals->_player.setFrame(1); + setDelay(10); + break; + case 13: + if (!_globals->_sceneObjects->contains(&scene->_hotspot7)) + setDelay(10); + break; + case 14: + setDelay(30); + break; + case 15: + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene5000::Action3::signal() { + Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(10); + break; + case 1: + scene->_hotspot7.postInit(); + scene->_hotspot7.setVisage(2809); + scene->_hotspot7.setObjectWrapper(new SceneObjectWrapper()); + scene->_hotspot7.setPosition(Common::Point(217, 76)); + scene->_hotspot7.changeZoom(10); + scene->_hotspot7.setStrip2(3); + scene->_hotspot7.setPriority2(200); + scene->_hotspot7._moveDiff.y = 2; + scene->_hotspot7.animate(ANIM_MODE_1, NULL); + ADD_MOVER(scene->_hotspot7, 214, 89); + + _globals->_sceneItems.push_front(&scene->_hotspot7); + break; + case 2: + scene->_hotspot7.changeZoom(-1); + scene->_hotspot7.setPriority2(14); + ADD_MOVER(scene->_hotspot7, 208, 100); + break; + case 3: + ADD_MOVER(scene->_hotspot7, 213, 98); + break; + case 4: + scene->_hotspot7.setPriority2(19); + ADD_MOVER(scene->_hotspot7, 213, 98); + break; + case 5: + scene->_hotspot7.changeZoom(46); + ADD_MOVER(scene->_hotspot7, 220, 125); + break; + case 6: + ADD_MOVER(scene->_hotspot7, 229, 115); + break; + case 7: + scene->_hotspot7.changeZoom(-1); + scene->_hotspot7.setPriority2(34); + ADD_MOVER(scene->_hotspot7, 201, 166); + break; + case 8: + scene->_hotspot7.updateZoom(); + ADD_MOVER(scene->_hotspot7, 205, 146); + break; + case 9: + scene->_hotspot7.changeZoom(-1); + scene->_hotspot7.setPriority2(49); + ADD_MOVER(scene->_hotspot7, 210, 182); + break; + case 10: + scene->_hotspot7.updateZoom(); + ADD_MOVER(scene->_hotspot7, 208, 163); + break; + case 11: + scene->_hotspot7.changeZoom(-1); + scene->_hotspot7.setStrip2(-1); + scene->_hotspot7.setPriority2(-1); + ADD_MOVER(scene->_hotspot7, 175, 166); + break; + case 12: + ADD_MOVER(scene->_hotspot7, 126, 146); + break; + case 13: + scene->_hotspot7.setStrip(2); + remove(); + break; + } +} + +void Scene5000::Action4::signal() { + Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(1); + break; + case 1: + _globals->_player.setPriority2(50); + _globals->_player.setStrip2(4); + ADD_MOVER(_globals->_player, 210, 182); + break; + case 2: + ADD_MOVER(_globals->_player, 205, 146); + break; + case 3: + _globals->_player.setPriority2(35); + ADD_MOVER(_globals->_player, 201, 166); + break; + case 4: + ADD_MOVER(_globals->_player, 229, 115); + break; + case 5: + _globals->_player.setPriority2(20); + _globals->_player.changeZoom(47); + ADD_MOVER(_globals->_player, 220, 125); + break; + case 6: + ADD_MOVER(_globals->_player, 215, 115); + break; + case 7: + _globals->_player.changeZoom(-1); + ADD_MOVER(_globals->_player, 213, 98); + break; + case 8: + _globals->_player.setPriority2(15); + ADD_MOVER(_globals->_player, 208, 100); + break; + case 9: + ADD_MOVER(_globals->_player, 214, 89); + break; + case 10: + ADD_MOVER(_globals->_player, 217, 76); + break; + case 11: + _globals->_player.hide(); + setDelay(60); + break; + case 12: + if (!_globals->_sceneObjects->contains(&scene->_hotspot7)) + _globals->_sceneManager.changeScene(2320); + remove(); + break; + } +} + +void Scene5000::Action5::signal() { + Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + ADD_MOVER(_globals->_player, 91, 155); + break; + case 1: + _globals->_player.setVisage(2670); + _globals->_player._strip = 4; + _globals->_player._frame = 1; + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 2: + SceneItem::display2(5000, _globals->_sceneObjects->contains(&scene->_hotspot7) ? 17 : 13); + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 3: + _globals->_player.setVisage(0); + _globals->_player._strip = 8; + _globals->_player.animate(ANIM_MODE_1, NULL); + + _globals->_player.enableControl(); + remove(); + } +} + +void Scene5000::Action6::signal() { + Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(3); + break; + case 1: + _globals->_events.setCursor(CURSOR_WALK); + scene->_stripManager.start(2150, this); + break; + case 2: + _globals->_events.setCursor(CURSOR_NONE); + scene->setAction(&scene->_sequenceManager, this, 5001, &scene->_hotspot7, NULL); + break; + case 3: + ADD_PLAYER_MOVER(208, 163); + break; + case 4: + _globals->_player.setPriority2(50); + _globals->_player.setStrip2(4); + ADD_MOVER(_globals->_player, 210, 182); + break; + case 5: + _globals->_sceneManager.changeScene(2100); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene5000::Hotspot7::doAction(int action) { + Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(5000, 12); + break; + case CURSOR_TALK: + setAction(&scene->_action6); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene5000::Hotspot8::doAction(int action) { + Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(5000, 10); + break; + case OBJECT_STUNNER: + SceneItem::display2(5000, 14); + break; + case OBJECT_SCANNER: + setAction(&scene->_action5); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene5000::HotspotGroup1::doAction(int action) { + Scene5000 *scene = (Scene5000 *)_globals->_sceneManager._scene; + + if (_globals->_sceneObjects->contains(&scene->_hotspot7)) + scene->setAction(&scene->_action6); + else + SceneItem::display2(5000, 11); +} +/*--------------------------------------------------------------------------*/ + +Scene5000::Scene5000(): + _hotspot1(0, CURSOR_LOOK, 5000, 3, LIST_END), + _hotspot12(0, CURSOR_LOOK, 5000, 6, CURSOR_USE, 5000, 7, OBJECT_STUNNER, 5000, 14, + OBJECT_SCANNER, 5000, 16, LIST_END), + _hotspot13(0, CURSOR_LOOK, 5000, 8, CURSOR_USE, 5000, 9, OBJECT_STUNNER, 5000, 0, + OBJECT_SCANNER, 5000, 16, LIST_END), + _hotspot14(0, CURSOR_LOOK, 5000, 8, CURSOR_USE, 5000, 9, OBJECT_STUNNER, 5000, 0, + OBJECT_SCANNER, 5000, 16, LIST_END), + _hotspot15(0, CURSOR_LOOK, 5000, 2, OBJECT_STUNNER, 5000, 15, LIST_END), + _hotspot16(0, CURSOR_LOOK, 5000, 4, CURSOR_USE, 5000, 5, LIST_END), + _hotspot17(0, CURSOR_LOOK, 5000, 1, LIST_END), + _hotspot18(0, CURSOR_LOOK, 5000, 0, LIST_END) { +} + + +void Scene5000::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + loadScene(5000); + + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerQText); + + _globals->_player.postInit(); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player._moveDiff = Common::Point(4, 2); + _globals->_player.changeZoom(-1); + _globals->_player.disableControl(); + + _hotspot1.postInit(); + _hotspot1.setVisage(5001); + _hotspot1.setFrame2(1); + _hotspot1._moveDiff = Common::Point(5, 5); + _hotspot1.setPriority2(10); + _hotspot1.changeZoom(10); + + _hotspot4.postInit(); + _hotspot4.setVisage(5001); + _hotspot4.setStrip2(2); + _hotspot4._moveDiff = Common::Point(5, 1); + _hotspot4.setPriority2(10); + _hotspot4.changeZoom(100); + _hotspot4.animate(ANIM_MODE_8, 0, NULL); + _hotspot4.hide(); + + _hotspot2.postInit(); + _hotspot2.setVisage(5001); + _hotspot2.setStrip2(3); + _hotspot2._numFrames = 5; + _hotspot2.hide(); + + _hotspot3.postInit(); + _hotspot3.setVisage(5001); + _hotspot3.setStrip2(5); + _hotspot3._numFrames = 5; + _hotspot3.setPosition(Common::Point(233, 76)); + _hotspot3.hide(); + + _hotspot5.postInit(); + _hotspot5.setVisage(5001); + _hotspot5.setStrip2(4); + _hotspot5._numFrames = 5; + _hotspot5.setPriority2(15); + _hotspot5.setPosition(Common::Point(218, 76)); + _hotspot5.hide(); + + _hotspot9.postInit(); + _hotspot9.setVisage(5002); + _hotspot9.setPriority2(80); + _hotspot9.setPosition(Common::Point(71, 174)); + + _hotspot10.postInit(); + _hotspot10.setVisage(5002); + _hotspot10.setStrip2(2); + _hotspot10.setPosition(Common::Point(87, 120)); + + _hotspot11.postInit(); + _hotspot11.setVisage(5002); + _hotspot11.setStrip2(2); + _hotspot11.setFrame(3); + _hotspot10.setPosition(Common::Point(93, 118)); + + setZoomPercents(95, 10, 145, 100); + + _hotspot8.setBounds(Rect(0, 73, 87, 144)); + _hotspot18.setBounds(Rect(54, 0, 319, 85)); + _hotspot17.setBounds(Rect(184, 0, 199, 79)); + _hotspot13.setBounds(Rect(0, 164, 135, 200)); + _hotspot14.setBounds(Rect(0, 0, 105, 140)); + _hotspot15.setBounds(Rect(266, 70, 291, 85)); + _hotspot16.setBounds(Rect(0, 86, 3219, 200)); + _hotspot12.setBounds(Rect(230, 143, 244, 150)); + + _globals->_sceneItems.addItems(&_hotspot9, &_hotspot10, &_hotspot11, &_hotspot8, &_hotspot13, + &_hotspot14, &_hotspot12, &_hotspot15, &_hotspot17, &_hotspot18, &_hotspot16, NULL); + + switch (_globals->_sceneManager._previousScene) { + case 1000: + case 2100: + case 2320: + if (_globals->getFlag(59)) { + _hotspot1.setPosition(Common::Point(233, 90)); + _hotspot1.changeZoom(100); + _hotspot1.show(); + + _hotspot5.setFrame(1); + _hotspot5.animate(ANIM_MODE_5, NULL); + _hotspot5.setPosition(Common::Point(218, 76)); + _hotspot5.show(); + + _globals->_player.setPosition(Common::Point(217, -10)); + _globals->_player.disableControl(); + + setAction(&_action2); + } else { + _globals->_player.setPosition(Common::Point(217, -10)); + _hotspot1.setPosition(Common::Point(320, -10)); + _globals->_player.disableControl(); + + setAction(&_action1); + } + break; + default: + _globals->_player.disableControl(); + _globals->_player.setPosition(Common::Point(0, 146)); + + _hotspot1.changeZoom(100); + _hotspot1.setPosition(Common::Point(233, 90)); + _hotspot1.show(); + + _hotspot5.setFrame(_hotspot5.getFrameCount()); + _hotspot5.show(); + + _sceneMode = 5004; + setAction(&_sequenceManager, this, 5004, &_globals->_player, NULL); + break; + } + + _globals->_soundHandler.startSound(190); +} + +void Scene5000::signal() { + switch (_sceneMode) { + case 5002: + case 5003: + case 5004: + _globals->_player.enableControl(); + break; + case 5005: + _globals->_sceneManager.changeScene(5100); + break; + } +} + +void Scene5000::dispatch() { + Scene::dispatch(); + + if (!_action) { + if (!_globals->_sceneObjects->contains(&_hotspot7) && (_globals->_player.getRegionIndex() == 10)) { + _globals->_player.disableControl(); + _sceneMode = 5005; + setAction(&_sequenceManager, this, 5005, &_globals->_player, NULL); + } + + if (_globals->_player.getRegionIndex() == 8) { + _globals->_player.disableControl(); + + if (_globals->_sceneObjects->contains(&_hotspot7)) { + _sceneMode = 5003; + _globals->_player.addMover(NULL); + setAction(&_sequenceManager, this, 5003, &_globals->_player, NULL); + } else { + setAction(&_action4); + } + } + + if (_globals->_sceneObjects->contains(&_hotspot7) && (_globals->_player.getRegionIndex() == 15)) { + _sceneMode = 5002; + _globals->_player.disableControl(); + _globals->_player.addMover(NULL); + setAction(&_sequenceManager, this, 5002, &_globals->_player, NULL); + } + } +} + +/*-------------------------------------------------------------------------- + * Scene 5100 - Caverns + * + *--------------------------------------------------------------------------*/ + +void Scene5100::Action1::signal() { + Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(5); + break; + case 1: + ADD_MOVER(_globals->_player, 1111, 165); + break; + case 2: + _globals->_player.setStrip(6); + _globals->_player.setFrame(1); + setDelay(60); + break; + case 3: + if (_globals->getFlag(10)) { + _globals->_player.enableControl(); + remove(); + } else { + _globals->setFlag(10); + scene->_stripManager.start(5102, this); + } + break; + case 4: + scene->_soundHandler.startSound(206); + + scene->_hotspot5.postInit(); + scene->_hotspot5.setVisage(5362); + scene->_hotspot5.setPosition(Common::Point(1160, 34)); + scene->_hotspot5.setStrip2(2); + scene->_hotspot5.animate(ANIM_MODE_1, NULL); + scene->_hotspot5.setPriority2(10); + + _globals->_sceneItems.push_front(&scene->_hotspot5); + ADD_MOVER(scene->_hotspot5, 999, 14); + break; + case 5: + scene->_hotspot5.setStrip2(4); + scene->_hotspot5._frame = 1; + scene->_hotspot5.animate(ANIM_MODE_5, this); + break; + case 6: + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene5100::Action2::signal() { + Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(5); + break; + case 1: + if (scene->_hotspot8._visage == 2806) + setDelay(1); + else + scene->_hotspot8.animate(ANIM_MODE_5, this); + break; + case 2: + if (scene->_hotspot8._visage != 2806) { + scene->_hotspot8.setVisage(2806); + scene->_hotspot8.setPosition(Common::Point(548, 193)); + scene->_hotspot8.animate(ANIM_MODE_1, NULL); + scene->_hotspot8._angle = 325; + scene->_hotspot8.setObjectWrapper(new SceneObjectWrapper()); + scene->_hotspot8.setStrip(8); + } + + scene->_stripManager.start(5129, this); + break; + case 3: + if (_globals->_player._position.x >= 966) { + ADD_PLAYER_MOVER(1215, 155); + } else { + ADD_PLAYER_MOVER_THIS(scene->_hotspot8, 966, 185); + } + + if (_globals->_player._position.x >= 966) { + setDelay(1); + } else { + ADD_PLAYER_MOVER(966, 190); + } + break; + case 4: + ADD_PLAYER_MOVER_THIS(scene->_hotspot8, 1215, 155); + ADD_PLAYER_MOVER(1215, 155); + break; + case 5: + _globals->_sceneManager.changeScene(2100); + break; + } +} + +void Scene5100::Action3::signal() { + Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->setFlag(62); + _globals->_player.disableControl(); + _globals->_player.addMover(NULL); + + scene->_hotspot2.addMover(NULL); + scene->_hotspot3.addMover(NULL); + _globals->_player.setVisage(2672); + + if (static_cast<SceneObject *>(_owner)->_position.x >= _globals->_player._position.x) + _globals->_player._strip = 4; + else + _globals->_player._strip = 3; + _globals->_player._frame = 1; + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 1: + _globals->_player.setVisage(2674); + _globals->_player.setFrame(1); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 2: + scene->_soundHandler.startSound(28); + if (static_cast<SceneObject *>(_owner)->_position.x < _globals->_player._position.x) { + scene->_hotspot2.setVisage(5130); + scene->_hotspot2._strip = 1; + scene->_hotspot2._frame = 1; + scene->_hotspot2.animate(ANIM_MODE_5, this); + scene->_hotspot2.setAction(NULL); + + scene->_hotspot3.setStrip2(1); + ADD_PLAYER_MOVER_THIS(scene->_hotspot3, 1200, 100); + } else { + scene->_hotspot3.setVisage(5130); + scene->_hotspot3._strip = 1; + scene->_hotspot3._frame = 1; + scene->_hotspot3.animate(ANIM_MODE_5, this); + scene->_hotspot3.setAction(NULL); + + scene->_hotspot2.setStrip2(2); + ADD_PLAYER_MOVER_NULL(scene->_hotspot2, 10, 140); + + } + + _globals->_player.setVisage(2672); + _globals->_player._frame = _globals->_player.getFrameCount(); + _globals->_player.animate(ANIM_MODE_6, this); + break; + case 3: + break; + case 4: + SceneItem::display2(5100, 38); + _globals->_player.enableControl(); + + _globals->_player.setVisage(0); + _globals->_player._strip = 8; + _globals->_player.animate(ANIM_MODE_1, NULL); + remove(); + break; + } +} + +void Scene5100::Action4::signal() { + Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + _globals->_player.disableControl(); + scene->_soundHandler.startSound(208); + SceneItem::display2(5100, 15); + + ObjectMover3 *mover = new ObjectMover3(); + scene->_hotspot2.addMover(mover, &_globals->_player, 20, this); + break; + } + case 1: + scene->_hotspot1.postInit(); + scene->_hotspot1.setVisage(5120); + scene->_hotspot1.setPosition(Common::Point(795, 161)); + scene->_hotspot1._strip = 4; + scene->_hotspot1.animate(ANIM_MODE_5, this); + break; + case 2: + setDelay(15); + break; + case 3: + _globals->_sceneManager.changeScene(5200); + break; + } +} + +void Scene5100::Action5::signal() { + Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(60); + break; + case 1: + scene->_stripManager.start(5128, this); + break; + case 2: + setDelay(15); + break; + case 3: + scene->_sceneMode = 5106; + scene->setAction(&scene->_sequenceManager, scene, 5106, &_globals->_player, NULL); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene5100::HotspotGroup1::doAction(int action) { + Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(5100, _globals->getFlag(62) ? 41 : 26); + break; + case CURSOR_USE: + SceneItem::display2(5100, 11); + break; + case OBJECT_SCANNER: + SceneItem::display2(5100, 17); + break; + case OBJECT_STUNNER: + if (_globals->getFlag(62)) + SceneItem::display2(5100, 42); + else + setAction(&scene->_action3); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene5100::Hotspot4::doAction(int action) { + Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(5100, 31); + break; + case CURSOR_USE: + _globals->_player.disableControl(); + scene->_sceneMode = 5110; + scene->setAction(&scene->_sequenceManager, scene, 5110, &_globals->_player, this, &scene->_hotspot7, NULL); + break; + case CURSOR_TALK: + SceneItem::display2(5100, 34); + break; + case OBJECT_STUNNER: + SceneItem::display2(5100, 36); + break; + case OBJECT_SCANNER: + SceneItem::display2(5100, 37); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene5100::HotspotGroup2::doAction(int action) { + Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(5100, _globals->getFlag(62) ? 47 : 23); + break; + case CURSOR_USE: + SceneItem::display2(5100, 29); + break; + case CURSOR_TALK: + if (_position.x >= 600) + SceneItem::display2(5100, 28); + else { + _globals->_player.disableControl(); + scene->_sceneMode = 5114; + scene->setAction(&scene->_sequenceManager, scene, 5114, NULL); + } + break; + case OBJECT_SCANNER: + SceneItem::display2(5100, 43); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene5100::Hotspot9::doAction(int action) { + Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(5100, 32); + break; + case CURSOR_USE: + _globals->_player.disableControl(); + scene->_sceneMode = 5117; + scene->setAction(&scene->_sequenceManager, scene, 5117, &_globals->_player, NULL); + break; + case OBJECT_STUNNER: + SceneItem::display2(5100, 35); + break; + case OBJECT_SCANNER: + SceneItem::display2(5100, 44); + break; + case OBJECT_BONE: + _globals->_player.disableControl(); + scene->_sceneMode = 5116; + scene->setAction(&scene->_sequenceManager, scene, 5116, &_globals->_player, &scene->_hotspot10, + &scene->_hotspot4, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene5100::Hotspot17::doAction(int action) { + Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(5100, 18); + break; + case CURSOR_USE: + if (_globals->getFlag(67)) + SceneItem::display2(5100, 19); + else { + _globals->_player.disableControl(); + scene->_sceneMode = 5101; + scene->setAction(&scene->_sequenceManager, scene, 5101, &_globals->_player, this, NULL); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene5100::Hotspot18::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + if (_globals->_sceneManager._previousScene != 5000) { + SceneItem::display2(5100, 3); + } else { + switch (_index1) { + case 0: + SceneItem::display2(5100, 0); + ++_index1; + break; + case 1: + SceneItem::display2(5100, 1); + ++_index1; + break; + default: + SceneItem::display2(5100, 2); + break; + } + } + break; + case CURSOR_USE: + switch (_index2) { + case 0: + SceneItem::display2(5100, 8); + ++_index2; + break; + case 1: + SceneItem::display2(5100, 9); + ++_index2; + break; + default: + SceneItem::display2(5100, 10); + break; + } + break; + + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene5100::Hotspot19::doAction(int action) { + Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(5100, _globals->_sceneObjects->contains(&scene->_hotspot14) ? 27 : 20); + break; + case CURSOR_USE: + _globals->_player.disableControl(); + scene->_sceneMode = 5106; + + if (_globals->getFlag(66)) + scene->setAction(&scene->_sequenceManager, scene, 5113, &_globals->_player, NULL); + else { + _globals->setFlag(66); + scene->setAction(&scene->_sequenceManager, scene, 5106, &_globals->_player, &scene->_hotspot14, NULL); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene5100::Hotspot20::doAction(int action) { + Scene5100 *scene = (Scene5100 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(5100, 21); + break; + case CURSOR_USE: + _globals->_player.disableControl(); + + if (_globals->getFlag(67)) { + scene->_sceneMode = 5112; + scene->setAction(&scene->_sequenceManager, scene, 5112, &_globals->_player, NULL); + } else { + scene->_sceneMode = 5101; + scene->setAction(&scene->_sequenceManager, scene, 5106, &_globals->_player, &scene->_hotspot17, NULL); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene5100::Scene5100(): + _hotspot16(0, CURSOR_LOOK, 5100, 48, LIST_END), + _hotspot21(0, CURSOR_LOOK, 5100, 4, CURSOR_USE, 5100, 5, LIST_END) { +} + +void Scene5100::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(50, 10, 200, 100); + _sceneMode = 0; + + _stripManager.addSpeaker(&_speakerMText); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerGameText); + _stripManager.addSpeaker(&_speakerBatText); + _speakerQText._npc = &_globals->_player; + _speakerMText._npc = &_globals->_player; + _speakerSText._npc = &_hotspot8; + + _globals->_player.postInit(); + _globals->_player.setVisage(0); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.disableControl(); + + if (!_globals->getFlag(66)) { + _hotspot14.postInit(); + _hotspot14.setVisage(5101); + _hotspot14.setPosition(Common::Point(498, 147)); + _hotspot14.setPriority2(200); + _hotspot14._moveDiff.y = 10; + } + + _hotspot17.postInit(); + _hotspot17.setVisage(5101); + _hotspot17._strip = 2; + _hotspot17.setPriority2(200); + + if (_globals->getFlag(67)) + _hotspot17.setPosition(Common::Point(554, 192)); + else + _hotspot17.setPosition(Common::Point(539, 179)); + + _hotspot19.setBounds(Rect(488, 115, 508, 148)); + _hotspot21.setBounds(Rect(1150, 85, 1173, 112)); + _hotspot20.setBounds(Rect(517, 193, 562, 200)); + _globals->_sceneItems.addItems(&_hotspot19, &_hotspot21, NULL); + + if (_globals->getFlag(67)) { + _globals->_sceneItems.addItems(&_hotspot20, &_hotspot17, NULL); + } else { + _globals->_sceneItems.addItems(&_hotspot17, &_hotspot20, NULL); + } + + if (!_globals->getFlag(105)) { + _hotspot4.postInit(); + _hotspot4.setVisage(5363); + _hotspot4.setPosition(Common::Point(1025, 65)); + _hotspot4.setStrip(4); + _hotspot4.animate(ANIM_MODE_7, 0, NULL);; + _globals->_sceneItems.push_back(&_hotspot4); + + _hotspot9.postInit(); + _hotspot9.setVisage(5363); + _hotspot9.setPosition(Common::Point(966, 120)); + _globals->_sceneItems.push_back(&_hotspot9); + + _hotspot10.postInit(); + _hotspot10.setVisage(5363); + _hotspot10.setPosition(Common::Point(999, 68)); + _hotspot10.setStrip(2); + + _hotspot6.postInit(); + _hotspot6.setVisage(5362); + _hotspot6.setPosition(Common::Point(1017, 34)); + _hotspot6._strip = 4; + _hotspot6._frame = _hotspot6.getFrameCount(); + _globals->_sceneItems.push_back(&_hotspot6); + } + + _hotspot16._sceneRegionId = 15; + _globals->_sceneItems.push_back(&_hotspot16); + + if (!_globals->getFlag(62)) { + _hotspot2.postInit(); + _hotspot2.setVisage(5110); + _hotspot2.animate(ANIM_MODE_1, NULL); + _hotspot2._moveDiff.x = 4; + _globals->_sceneItems.push_back(&_hotspot2); + + _hotspot3.postInit(); + _hotspot3.setVisage(5110); + _hotspot3.animate(ANIM_MODE_1, NULL); + _hotspot3._moveDiff.x = 4; + _globals->_sceneItems.push_back(&_hotspot3); + + if (_globals->getFlag(61)) { + _hotspot2.setPosition(Common::Point(483, 189)); + _hotspot3.setPosition(Common::Point(811, 182)); + } else { + _hotspot2.setPosition(Common::Point(610, 170)); + _hotspot3.setPosition(Common::Point(600, 180)); + } + } + + if (_globals->getFlag(60) && (_globals->_inventory._stasisBox._sceneNumber == 1) && + _globals->getFlag(107) && _globals->getFlag(67)) { + _hotspot8.postInit(); + _hotspot8.setVisage(2806); + _hotspot8.setPosition(Common::Point(557, 178)); + _hotspot8.animate(ANIM_MODE_1, NULL); + _hotspot8.setObjectWrapper(new SceneObjectWrapper()); + + _globals->clearFlag(59); + } + + switch (_globals->_sceneManager._previousScene) { + case 5000: + default: + _globals->_player.setPosition(Common::Point(1184, 160)); + setAction(&_action1); + break; + case 5200: + if (_globals->_stripNum == 5200) { + _globals->_player.setVisage(5101); + _globals->_player.setPriority2(200); + _globals->_player.setStrip(5); + _globals->_player.setFrame(1); + _globals->_player.setPosition(Common::Point(513, 199)); + + _sceneMode = 5108; + setAction(&_sequenceManager, this, 5108, &_globals->_player, NULL); + } else { + _globals->_player.setPosition(Common::Point(20, 175)); + + _hotspot13.postInit(); + _hotspot13.setVisage(5110); + _hotspot13.setPosition(Common::Point(578, 192)); + _hotspot13._strip = 2; + + _hotspot11.postInit(); + _hotspot11.setVisage(5110); + _hotspot11.setPosition(Common::Point(5, 162)); + _hotspot11.setStrip2(1); + _hotspot11._moveDiff = Common::Point(4, 2); + _hotspot11.animate(ANIM_MODE_1, NULL); + + ObjectMover2 *mover = new ObjectMover2(); + _hotspot11.addMover(mover, 15, 20, &_globals->_player); + + _hotspot12.postInit(); + _hotspot12.setVisage(5110); + _hotspot12.setPosition(Common::Point(15, 164)); + _hotspot12.setStrip2(1); + _hotspot12._moveDiff = Common::Point(4, 2); + _hotspot12.animate(ANIM_MODE_1, NULL); + + ObjectMover2 *mover2 = new ObjectMover2(); + _hotspot12.addMover(mover2, 25, 50, &_globals->_player); + + _hotspot17.setPosition(Common::Point(554, 182)); + _globals->_player.disableControl(); + + _sceneMode = 5105; + setAction(&_sequenceManager, this, 5105, &_globals->_player, NULL); + } + break; + case 5300: + switch (_globals->_stripNum) { + case 5300: + _sceneMode = 5111; + + _globals->_player.setVisage(5101); + _globals->_player.setStrip(6); + _globals->_player.setPriority2(170); + _globals->_player.setPosition(Common::Point(1168, 110)); + + setAction(&_sequenceManager, this, 5111, &_globals->_player, NULL); + _hotspot8.setPosition(Common::Point(1107, 178)); + break; + case 5302: + _globals->_player.setPosition(Common::Point(512, 190)); + + if (_globals->_sceneObjects->contains(&_hotspot8)) + setAction(&_action2); + else + _globals->_player.enableControl(); + break; + case 5303: + _hotspot8.setVisage(5102); + _hotspot8.setPosition(Common::Point(533, 172)); + _globals->_player.setPosition(Common::Point(512, 190)); + setAction(&_action2); + break; + } + + if (_globals->getFlag(108)) { + _hotspot6.postInit(); + _hotspot6.setVisage(5362); + _hotspot6.setPosition(Common::Point(542, 19)); + _hotspot6.setStrip(6); + _hotspot6.setFrame(1); + _globals->_sceneItems.push_back(&_hotspot6); + } else if (_globals->_inventory._vial._sceneNumber != 5100) { + _hotspot6.postInit(); + _hotspot6.setVisage(5362); + _hotspot6.setPosition(Common::Point(1152, 70)); + _hotspot6.setPriority2(170); + _hotspot6.setStrip(6); + _hotspot6.setFrame(1); + _globals->_sceneItems.push_back(&_hotspot6); + } + break; + } + + _hotspot18.setBounds(Rect(0, 0, 1280, 200)); + _globals->_sceneItems.push_back(&_hotspot18); + + _hotspot15.postInit(); + _hotspot15.setVisage(5140); + _hotspot15.setStrip(3); + _hotspot15.setPosition(Common::Point(977, 173)); + _hotspot15.setPriority2(1); + + _globals->_sceneManager._scene->_sceneBounds.centre(_globals->_player._position); + loadScene(5100); + _globals->_soundHandler.startSound(205); +} + +void Scene5100::signal() { + switch (_sceneMode) { + case 5101: + case 5112: + _globals->setFlag(67); + _globals->_sceneManager.changeScene(5300); + break; + case 5102: + case 5114: + _globals->_player.enableControl(); + break; + case 5103: + if (_globals->getFlag(61)) { + SceneItem::display2(5100, 46); + _globals->_sceneManager.changeScene(5300); + } else { + SceneItem::display2(5100, 45); + _globals->_sceneManager.changeScene(5200); + } + break; + case 5105: + _globals->_sceneManager.changeScene(5300); + break; + case 5106: + _globals->_stripNum = 5111; + _globals->_sceneManager.changeScene(5200); + break; + case 5108: + if (!_globals->getFlag(60)) + _globals->_player.enableControl(); + else if (_globals->_inventory._stasisBox._sceneNumber == 1) + setAction(&_action2); + else + setAction(&_action5); + break; + case 5110: + SceneItem::display2(5100, 30); + _globals->_player._angle = 325; + _globals->_player.enableControl(); + break; + case 5111: + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setVisage(6); + _globals->_player.setStrip(6); + _globals->_player.setPriority2(-1); + _globals->_player.animate(ANIM_MODE_1, NULL); + + if ((_globals->_inventory._vial._sceneNumber != 5100) && !_globals->getFlag(108)) { + _globals->setFlag(108); + _sceneMode = 5130; + _globals->_player.disableControl(); + + _speakerBatText.setTextPos(Common::Point(_globals->_sceneManager._scene->_sceneBounds.left + 20, 30)); + setAction(&_sequenceManager, this, 5130, &_globals->_player, &_hotspot6, NULL); + } else if (_globals->_sceneObjects->contains(&_hotspot8)) { + setAction(&_action2); + } else { + _globals->_player.enableControl(); + } + break; + case 5116: + _globals->setFlag(105); + _globals->_inventory._bone._sceneNumber = 0; + + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setVisage(0); + _globals->_player.setStrip(6); + _globals->_player.setPriority2(-1); + _globals->_player.animate(ANIM_MODE_1, NULL); + break; + case 5117: + _globals->_player.enableControl(); + break; + case 5130: + _hotspot6.setVisage(5362); + _hotspot6.setPosition(Common::Point(542, 25)); + _hotspot6.setStrip(6); + _hotspot6.setFrame(1); + _globals->_player.enableControl(); + break; + case 5150: + _globals->clearFlag(60); + _globals->_sceneManager.changeScene(5300); + break; + } +} + +void Scene5100::dispatch() { + if (_hotspot15._bounds.contains(_globals->_player._position) && !_globals->_player._visage) { + _globals->_player.disableControl(); + _globals->_player.addMover(NULL); + + _soundHandler.startSound(207); + _sceneMode = 5103; + setAction(&_sequenceManager, this, (_globals->_player._position.x >= 966) ? 5104 : 5103, + &_globals->_player, &_hotspot15, NULL); + } + + if (_globals->getFlag(61) && !_globals->getFlag(62) && + ((_globals->_player._position.x - _hotspot2._position.x) < 160) && + (_globals->_sceneManager._previousScene != 5200) && + (_globals->_sceneManager._previousScene != 5150)) { + setAction(NULL); + _sceneMode = 5150; + _soundHandler.startSound(208); + + if (_globals->_inventory._vial._sceneNumber == 5100) { + _globals->_player.addMover(NULL); + _globals->_player.disableControl(); + SceneItem::display2(5100, 39); + } + + _hotspot2.setStrip2(1); + _hotspot3.setStrip2(2); + + ObjectMover3 *mover1 = new ObjectMover3(); + _hotspot2.addMover(mover1, 20, this); + ObjectMover3 *mover2 = new ObjectMover3(); + _hotspot3.addMover(mover2, 20, this); + } + + if (!_action) { + if (((_globals->_player._position.x - _hotspot2._position.x) < 130) && !_globals->getFlag(61)) { + _globals->_player._canWalk = false; + _globals->_player.addMover(NULL); + + PlayerMover2 *mover = new PlayerMover2(); + _hotspot3.addMover(mover, 20, 25, &_globals->_player); + setAction(&_action4); + } + + if ((_globals->_sceneManager._scene->_backgroundBounds.right - 85) <= _globals->_player._position.x) + _globals->_sceneManager.changeScene(5000); + + if (_globals->_player.getRegionIndex() == 8) { + _sceneMode = 5114; + setAction(&_sequenceManager, this, 5115, &_globals->_player, NULL); + } + } + + Scene::dispatch(); +} + +/*-------------------------------------------------------------------------- + * Scene 5200 - Caverns - Throne Room + * + *--------------------------------------------------------------------------*/ + +void Scene5200::Action1::signal() { + Scene5200 *scene = (Scene5200 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(_globals->_randomSource.getRandomNumber(59) + 120); + break; + case 1: + scene->_hotspot3.animate(ANIM_MODE_8, 1, this); + _actionIndex = 0; + break; + } +} + +void Scene5200::Action2::signal() { + Scene5200 *scene = (Scene5200 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + ADD_PLAYER_MOVER(92, 52); + break; + case 1: + _globals->_player.setVisage(5202); + _globals->_player._strip = 4; + _globals->_player._frame = 1; + _globals->_player.animate(ANIM_MODE_4, 3, 1, this); + break; + case 2: + scene->_soundHandler.proc3(); + scene->_hotspot14.remove(); + + _globals->_inventory._stasisBox._sceneNumber = 1; + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 3: + _globals->_player.setVisage(0); + _globals->_player._strip = 3; + _globals->_player.animate(ANIM_MODE_1, NULL); + + scene->_hotspot8.animate(ANIM_MODE_2, NULL); + ADD_MOVER(scene->_hotspot8, 141, 77); + break; + case 4: + scene->_soundHandler.startSound(303); + + scene->_hotspot8._strip = 2; + scene->_hotspot8._frame = 1; + scene->_hotspot8.animate(ANIM_MODE_5, this); + break; + case 5: + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene5200::Action3::signal() { + switch (_actionIndex++) { + _globals->_player.disableControl(); + setDelay(5); + break; + case 1: + ADD_PLAYER_MOVER(285, 62); + break; + case 2: + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene5200::Action4::signal() { + Scene5200 *scene = (Scene5200 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(120); + break; + case 1: + _globals->_soundHandler.startSound(209); + scene->_stripManager.start(5202, this, scene); + break; + case 2: + scene->_hotspot6.animate(ANIM_MODE_5, this); + break; + case 3: + setDelay(10); + break; + case 4: + scene->_stripManager.start(5204, this, scene); + break; + case 5: + setDelay(60); + break; + case 6: + _globals->_sceneManager.changeScene(5100); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene5200::Hotspot9::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + if (!_state) { + ++_state; + SceneItem::display2(5200, 5); + } else { + SceneItem::display2(5200, 6); + } + break; + case CURSOR_USE: + SceneItem::display2(5200, 14); + break; + default: + SceneItem::doAction(action); + break; + } +} + +void Scene5200::Hotspot10::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + if (!_state) { + ++_state; + SceneItem::display2(5200, 7); + } else { + SceneItem::display2(5200, 8); + } + break; + default: + SceneItem::doAction(action); + break; + } +} + +void Scene5200::Hotspot14::doAction(int action) { + Scene5200 *scene = (Scene5200 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(5200, 4); + break; + case CURSOR_USE: + scene->setAction(&scene->_action2); + break; + default: + SceneItem::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene5200::Scene5200(): + _hotspot11(0, CURSOR_LOOK, 5200, 0, CURSOR_USE, 5200, 13, LIST_END), + _hotspot12(10, CURSOR_LOOK, 5200, 9, LIST_END), + _hotspot13(8, CURSOR_LOOK, 5200, 0, CURSOR_USE, 5200, 13, LIST_END) { +} + + +void Scene5200::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(0, 150, 199, 150); + _fieldA = 5600; + _fieldE = 5100; + + _hotspot9._state = 0; + _hotspot10._state = 0; + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerGameText); + _stripManager.addSpeaker(&_speakerFLText); + _stripManager.addSpeaker(&_speakerFLL); + _stripManager.addSpeaker(&_speakerQL); + _stripManager.setCallback(this); + + _speakerFLText._textPos.x = 160; + _speakerQText._textPos.x = 20; + + if (_globals->_inventory._stasisBox._sceneNumber == 5200) { + _soundHandler.startSound(216); + _soundHandler.proc5(true); + + _hotspot14.postInit(); + _hotspot14.setVisage(5202); + _hotspot14._strip = 3; + _hotspot14.setPosition(Common::Point(105, 52)); + _hotspot14.setPriority2(90); + + _hotspot8.postInit(); + _hotspot8.setVisage(5202); + _hotspot8._strip = 1; + _hotspot8.setPosition(Common::Point(96, 53)); + _hotspot8.setPriority2(90); + _globals->_sceneItems.push_back(&_hotspot14); + } + + if (_globals->_stripNum == 1111) { + _globals->_soundHandler.startSound(205); + _globals->_player.disableControl(); + + _globals->_player.postInit(); + _globals->_player.setVisage(0); + _globals->_player.changeZoom(75); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setStrip(1); + _globals->_player.setFrame(3); + _globals->_player.setPosition(Common::Point(307, 62)); + + setAction(&_action3); + } else { + _globals->_player.postInit(); + _globals->_player.setVisage(2640); + _globals->_player._strip = 1; + _globals->_player._frame = 4; + _globals->_player.setPosition(Common::Point(105, 199)); + + _hotspot5.postInit(); + _hotspot5.setVisage(5210); + _hotspot5._frame = 2; + _hotspot5.setPosition(Common::Point(189, 167)); + + _hotspot6.postInit(); + _hotspot6.setVisage(5210); + _hotspot6._frame = 1; + _hotspot6._strip = 2; + _hotspot6.setPosition(Common::Point(159, 137)); + + _hotspot7.postInit(); + _hotspot7.setVisage(5210); + _hotspot7._frame = 1; + _hotspot7._strip = 4; + _hotspot7.setPriority2(168); + _hotspot7.setPosition(Common::Point(186, 106)); + + _hotspot1.postInit(); + _hotspot1.setVisage(5212); + _hotspot1._frame = 1; + _hotspot1.setPosition(Common::Point(62, 132)); + + _hotspot2.postInit(); + _hotspot2.setVisage(5212); + _hotspot2._strip = 3; + _hotspot2.setPosition(Common::Point(148, 141)); + _hotspot2.setPriority2(90); + + _hotspot3.postInit(); + _hotspot3.setVisage(5212); + _hotspot3._strip = 2; + _hotspot3.setPosition(Common::Point(62, 109)); + _hotspot3.setPriority2(138); + _hotspot3.setAction(&_action1); + + _hotspot4.postInit(); + _hotspot4.setVisage(5212); + _hotspot4._strip = 4; + _hotspot4.setPosition(Common::Point(146, 110)); + _hotspot4.setPriority2(90); + + _globals->_player.disableControl(); + _globals->setFlag(61); + + setAction(&_action4); + } + + _hotspot11.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + _hotspot9._sceneRegionId = 11; + _hotspot10._sceneRegionId = 9; + + _globals->_sceneItems.addItems(&_hotspot12, &_hotspot13, &_hotspot9, &_hotspot10, &_hotspot11, NULL); + _globals->_sceneManager._scene->_sceneBounds.centre(_globals->_player._position); + loadScene(5200); +} + +void Scene5200::stripCallback(int v) { + switch (v) { + case 1: + _hotspot7.animate(ANIM_MODE_2, NULL); + break; + case 2: + _hotspot7.animate(ANIM_MODE_NONE, NULL); + break; + } +} + +void Scene5200::dispatch() { + Scene::dispatch(); + + if (!_action && (_globals->_player.getRegionIndex() == 12)) { + _globals->_stripNum = 5200; + _globals->_sceneManager.changeScene(5100); + } +} + +/*-------------------------------------------------------------------------- + * Scene 5300 - Caverns - Pit + * + *--------------------------------------------------------------------------*/ + +void Scene5300::Action1::signal() { + Scene5300 *scene = (Scene5300 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(3); + break; + case 1: + scene->_hotspot2._numFrames = 4; + scene->_hotspot2.animate(ANIM_MODE_8, 1, NULL); + setDelay(120); + break; + case 2: + scene->_hotspot2.animate(ANIM_MODE_NONE, NULL); + + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.setStrip2(-1); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + ADD_MOVER(_globals->_player, 85, 170); + break; + case 3: + scene->_hotspot2.setPriority2(-1); + _globals->_player.checkAngle(&scene->_hotspot2); + setAction(&scene->_sequenceManager, this, 5305, &scene->_hotspot2, NULL); + break; + case 4: + scene->_stripManager.start(5316, this); + break; + case 5: + if (!_globals->getFlag(106) || !_globals->getFlag(107) || (_globals->_inventory._stasisBox._sceneNumber != 1)) { + _globals->_player.enableControl(); + remove(); + } else { + _globals->getFlag(60); + + if (_globals->getFlag(67)) { + scene->_sceneMode = 5310; + scene->setAction(&scene->_sequenceManager, scene, 5310, &_globals->_player, &scene->_hotspot2, NULL); + } else { + scene->_sceneMode = 5347; + scene->setAction(&scene->_sequenceManager, scene, 5347, NULL); + } + } + break; + } +} + +void Scene5300::Action2::signal() { + Scene5300 *scene = (Scene5300 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(60); + break; + case 1: + _globals->setFlag(60); + scene->_stripManager.start(5328, this); + break; + case 2: + if (_globals->_inventory._stasisBox._sceneNumber == 1) { + _globals->_stripNum = 5303; + setDelay(5); + } else { + _globals->_stripNum = 5302; + scene->_stripManager.start(5329, this); + } + break; + case 3: + _globals->_sceneManager.changeScene(5100); + remove(); + break; + } +} + +void Scene5300::Action3::signal() { + Scene5300 *scene = (Scene5300 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(30); + break; + case 1: + scene->_stripManager.start(_globals->_stripNum, this); + break; + case 2: + _globals->_player.enableControl(); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene5300::Hotspot1::doAction(int action) { + Scene5300 *scene = (Scene5300 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(5300, 24); + break; + case CURSOR_TALK: + _globals->_stripNum = 5312; + scene->setAction(&scene->_action3); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene5300::Hotspot2::doAction(int action) { + Scene5300 *scene = (Scene5300 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(5300, 23); + break; + case CURSOR_USE: + if (!_globals->getFlag(106)) { + _globals->_player.disableControl(); + scene->_sceneMode = 5302; + scene->setAction(&scene->_sequenceManager, scene, 5302, &_globals->_player, NULL); + } else { + SceneItem::display2(5300, _globals->getFlag(107) ? 25 : 20); + } + break; + case CURSOR_TALK: + if (!_globals->getFlag(106)) { + _globals->_player.disableControl(); + scene->_sceneMode = 5302; + scene->setAction(&scene->_sequenceManager, scene, 5302, &_globals->_player, NULL); + } else if (!_globals->getFlag(107)) { + SceneItem::display2(5300, 11); + } else { + _globals->_player.disableControl(); + + if (_globals->_inventory._stasisBox._sceneNumber != 1) { + scene->setAction(&scene->_sequenceManager, scene, 5316, NULL); + } else { + _globals->setFlag(60); + scene->_sceneMode = _globals->getFlag(67) ? 5315 : 5347; + scene->setAction(&scene->_sequenceManager, scene, 5315, this); + } + } + break; + case OBJECT_SCANNER: + SceneItem::display2(5300, _globals->getFlag(107) ? 10 : 9); + break; + case OBJECT_MEDKIT: + if (_globals->getFlag(106)) + SceneItem::display2(5300, 7); + else { + _globals->setFlag(106); + _globals->_player.disableControl(); + + scene->_sceneMode = 5303; + scene->setAction(&scene->_sequenceManager, scene, 5303, &_globals->_player, NULL); + } + break; + case OBJECT_VIAL: + if (_globals->getFlag(107)) { + SceneItem::display2(5300, 8); + } else { + _globals->_inventory._vial._sceneNumber = 5300; + _globals->setFlag(107); + _globals->_player.disableControl(); + scene->_sceneMode = 5304; + + scene->setAction(&scene->_sequenceManager, scene, 5304, &_globals->_player, NULL); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene5300::Hotspot5::doAction(int action) { + Scene5300 *scene = (Scene5300 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(5300, 27); + break; + case CURSOR_USE: + _globals->_inventory._bone._sceneNumber = 1; + _globals->_player.disableControl(); + + scene->_sceneMode = 5309; + scene->setAction(&scene->_sequenceManager, scene, 5309, &_globals->_player, this, NULL); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene5300::Hotspot6::doAction(int action) { + Scene5300 *scene = (Scene5300 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + if (!_globals->getFlag(105) || (_globals->_inventory._vial._sceneNumber == 1)) + SceneItem::display2(5300, 4); + else + SceneItem::display2(5300, 26); + break; + case CURSOR_USE: + if (!_globals->getFlag(105) || (_globals->_inventory._vial._sceneNumber != 5100)) { + _globals->_player.disableControl(); + scene->_sceneMode = 5301; + scene->setAction(&scene->_sequenceManager, scene, 5301, &_globals->_player, NULL); + } else { + _globals->_player.disableControl(); + scene->_sceneMode = 5307; + _globals->_inventory._vial._sceneNumber = 1; + + scene->setAction(&scene->_sequenceManager, scene, 5307, &scene->_hotspot1, &_globals->_player, + &scene->_hotspot4, NULL); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene5300::Hotspot7::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(63)) + SceneItem::display2(5300, 2); + else { + _globals->setFlag(63); + SceneItem::display2(5300, 0); + SceneItem::display2(5300, 1); + } + break; + case CURSOR_USE: + if (_globals->getFlag(64)) + SceneItem::display2(5300, 15); + else { + _globals->setFlag(64); + SceneItem::display2(5300, 14); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene5300::Hotspot8::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + SceneItem::display2(5300, _globals->getFlag(65) ? 6 : 5); + break; + case CURSOR_USE: + SceneItem::display2(5300, 18); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +Scene5300::Scene5300(): + _hotspot3(0, CURSOR_LOOK, 5300, 3, CURSOR_USE, 5300, 16, LIST_END) { +} + +void Scene5300::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + loadScene(5300); + setZoomPercents(0, 100, 199, 100); + + _stripManager.addSpeaker(&_speakerQR); + _stripManager.addSpeaker(&_speakerQL); + _stripManager.addSpeaker(&_speakerBatR); + _stripManager.addSpeaker(&_speakerSR); + _stripManager.addSpeaker(&_speakerSL); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerBatText); + _stripManager.addSpeaker(&_speakerSText); + _stripManager.addSpeaker(&_speakerGameText); + + if (_globals->getFlag(106) && _globals->getFlag(107)) { + _hotspot2.postInit(); + _hotspot2.setVisage(2806); + _hotspot2.setObjectWrapper(new SceneObjectWrapper()); + _hotspot2.setPosition(Common::Point(63, 170)); + _hotspot2.animate(ANIM_MODE_1, NULL); + } else { + _hotspot2.postInit(); + _hotspot2.setVisage(5310); + _hotspot2.setPosition(Common::Point(63, 170)); + _hotspot2.animate(ANIM_MODE_1, NULL); + _hotspot2.setPriority2(98); + } + + _hotspot1.postInit(); + _hotspot1.setVisage(5362); + _hotspot1.setStrip2(3); + _hotspot1.setFrame2(5); + _hotspot1.setPosition(Common::Point(76, 48)); + + _hotspot4.postInit(); + _hotspot4.setVisage(5316); + _hotspot4.setStrip(2); + _hotspot4.setPosition(Common::Point(89, 65)); + _hotspot4.animate(ANIM_MODE_2, NULL); + _hotspot4.hide(); + + if (_globals->getFlag(67)) { + _globals->_player.postInit(); + _globals->_player.setVisage(5316); + _globals->_player.setPosition(Common::Point(191, 27)); + _globals->_player.disableControl(); + + if (_globals->getFlag(107) && _globals->getFlag(106)) { + _hotspot2.postInit(); + _hotspot2.setObjectWrapper(new SceneObjectWrapper()); + _hotspot2.animate(ANIM_MODE_1, NULL); + + setAction(&_action2); + } else { + _globals->_player.setVisage(5315); + _globals->_player.setPosition(Common::Point(204, 86)); + _globals->_player.animate(ANIM_MODE_2, NULL); + _globals->_player.setStrip2(1); + _globals->_player._moveDiff.y = 12; + + _sceneMode = 5308; + setAction(&_sequenceManager, this, 5308, &_globals->_player, NULL); + } + } else { + _hotspot3.postInit(); + _hotspot3.setVisage(5301); + _hotspot3.setPosition(Common::Point(172, 32)); + _hotspot3.setPriority2(1); + _hotspot3.animate(ANIM_MODE_NONE, NULL); + + _globals->_player.postInit(); + _globals->_player.setVisage(5315); + _globals->_player.setPosition(Common::Point(204, 86)); + _globals->_player.animate(ANIM_MODE_2, NULL); + _globals->_player.setStrip2(1); + _globals->_player._moveDiff.y = 12; + _globals->_player.disableControl(); + + _sceneMode = 5306; + setAction(&_sequenceManager, this, 5306, &_globals->_player, &_hotspot3, NULL); + } + + _field1B0A = 1; + if (_globals->_inventory._bone._sceneNumber == 5300) { + _hotspot5.postInit(); + _hotspot5.setVisage(5301); + _hotspot5.setStrip(2); + _hotspot5.setPosition(Common::Point(190, 147)); + _globals->_sceneItems.push_back(&_hotspot5); + } + + _hotspot6.setBounds(Rect(74, 51, 114, 69)); + _hotspot7.setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + _hotspot8._sceneRegionId = 8; + + _globals->_sceneItems.addItems(&_hotspot8, &_hotspot2, &_hotspot6, &_hotspot3, &_hotspot7, NULL); + _globals->_soundHandler.startSound(212); +} + +void Scene5300::signal() { + switch (_sceneMode) { + case 5301: + _globals->_stripNum = 5300; + _globals->_sceneManager.changeScene(5100); + break; + case 5302: + case 5308: + case 5316: + case 5347: + _globals->_player.setStrip2(-1); + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.enableControl(); + break; + case 5303: + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.enableControl(); + + if (_globals->getFlag(107)) + setAction(&_action1); + else + SceneItem::display2(5300, 28); + break; + case 5304: + _globals->_player.animate(ANIM_MODE_1, NULL); + _globals->_player.enableControl(); + + if (_globals->getFlag(106)) + setAction(&_action1); + else + SceneItem::display2(5300, 28); + break; + case 5306: + _globals->clearFlag(67); + _globals->_player.setStrip2(-1); + + if ((_globals->_inventory._vial._sceneNumber == 1) || (_globals->_inventory._vial._sceneNumber == 5300)) + _stripManager.start(5303, this); + else + _stripManager.start(5302, this); + _sceneMode = 5302; + break; + case 5307: + _soundHandler.proc1(NULL); + break; + case 5309: + _hotspot5.remove(); + _globals->_player.enableControl(); + break; + case 5310: + _hotspot2.setPriority2(41); + _sceneMode = 5315; + + setAction(&_sequenceManager, this, 5315, &_hotspot2, NULL); + break; + case 5315: + _globals->_stripNum = 5315; + _globals->_sceneManager.changeScene(5100); + break; + } +} + + +} // End of namespace tSage diff --git a/engines/tsage/ringworld_scenes6.h b/engines/tsage/ringworld_scenes6.h new file mode 100644 index 0000000000..9ab446f712 --- /dev/null +++ b/engines/tsage/ringworld_scenes6.h @@ -0,0 +1,333 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#ifndef TSAGE_RINGWORLD_SCENES6_H +#define TSAGE_RINGWORLD_SCENES6_H + +#include "common/scummsys.h" +#include "tsage/ringworld_logic.h" +#include "tsage/events.h" +#include "tsage/core.h" +#include "tsage/scenes.h" +#include "tsage/globals.h" + +namespace tSage { + +class Scene5000: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + virtual void dispatch(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + class Action5: public Action { + public: + virtual void signal(); + }; + class Action6: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot7: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot8: public SceneObject { + public: + virtual void doAction(int action); + }; + class HotspotGroup1: public SceneObject { + public: + virtual void doAction(int action); + }; +public: + SequenceManager _sequenceManager; + SoundHandler _soundHandler; + SpeakerSText _speakerSText; + SpeakerQText _speakerQText; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Action5 _action5; + Action6 _action6; + DisplayHotspot _hotspot1; + SceneObject _hotspot2, _hotspot3, _hotspot4, _hotspot5, _hotspot6; + Hotspot7 _hotspot7; + Hotspot8 _hotspot8; + HotspotGroup1 _hotspot9, _hotspot10, _hotspot11; + DisplayHotspot _hotspot12, _hotspot13, _hotspot14, _hotspot15; + DisplayHotspot _hotspot16, _hotspot17, _hotspot18; + + Scene5000(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene5100: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + class Action5: public Action { + public: + virtual void signal(); + }; + class Action6: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class HotspotGroup1: public SceneObject { + public: + virtual void doAction(int action); + }; + class HotspotGroup2: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot4: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot9: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot17: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot18: public SceneHotspot { + public: + int _index1; + int _index2; + + virtual void doAction(int action); + }; + class Hotspot19: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot20: public SceneObject { + public: + virtual void doAction(int action); + }; +public: + SequenceManager _sequenceManager; + SoundHandler _soundHandler; + SpeakerMText _speakerMText; + SpeakerQText _speakerQText; + SpeakerSText _speakerSText; + SpeakerBatText _speakerBatText; + SpeakerGameText _speakerGameText; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Action5 _action5; + HotspotGroup1 _hotspot1, _hotspot2, _hotspot3; + Hotspot4 _hotspot4; + HotspotGroup2 _hotspot5, _hotspot6, _hotspot7; + SceneObject _hotspot8; + Hotspot9 _hotspot9; + SceneObject _hotspot10, _hotspot11, _hotspot12, _hotspot13, _hotspot14, _hotspot15; + DisplayHotspot _hotspot16; + Hotspot17 _hotspot17; + Hotspot18 _hotspot18; + Hotspot19 _hotspot19; + Hotspot20 _hotspot20; + DisplayHotspot _hotspot21; + + Scene5100(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene5200: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot9: public SceneItemExt { + public: + virtual void doAction(int action); + }; + class Hotspot10: public SceneItemExt { + public: + virtual void doAction(int action); + }; + class Hotspot14: public SceneObject { + public: + virtual void doAction(int action); + }; +public: + SoundHandler _soundHandler; + SpeakerFLL _speakerFLL; + SpeakerFLText _speakerFLText; + SpeakerQL _speakerQL; + SpeakerQText _speakerQText; + SpeakerGameText _speakerGameText; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + + SceneObject _hotspot1, _hotspot2, _hotspot3, _hotspot4, _hotspot5, _hotspot6, _hotspot7; + SceneObject _hotspot8; + Hotspot9 _hotspot9; + Hotspot10 _hotspot10; + DisplayHotspot _hotspot11, _hotspot12, _hotspot13; + Hotspot14 _hotspot14; + + Scene5200(); + virtual void stripCallback(int v); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void dispatch(); +}; + +class Scene5300: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + + /* Hotspots */ + class Hotspot1: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot2: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot5: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot6: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot7: public SceneObject { + public: + virtual void doAction(int action); + }; + class Hotspot8: public SceneObject { + public: + virtual void doAction(int action); + }; +public: + SoundHandler _soundHandler; + SequenceManager _sequenceManager; + SpeakerQR _speakerQR; + SpeakerQL _speakerQL; + SpeakerQText _speakerQText; + SpeakerBatR _speakerBatR; + SpeakerBatText _speakerBatText; + SpeakerSR _speakerSR; + SpeakerSL _speakerSL; + SpeakerSText _speakerSText; + SpeakerGameText _speakerGameText; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Hotspot1 _hotspot1; + Hotspot2 _hotspot2; + DisplayHotspot _hotspot3; + SceneObject _hotspot4; + Hotspot5 _hotspot5; + Hotspot6 _hotspot6; + Hotspot7 _hotspot7; + Hotspot8 _hotspot8; + int _field1B0A; + + Scene5300(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void synchronise(Serialiser &s) { + Scene::synchronise(s); + s.syncAsSint16LE(_field1B0A); + } +}; + + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/ringworld_scenes8.cpp b/engines/tsage/ringworld_scenes8.cpp new file mode 100644 index 0000000000..e9277fbe00 --- /dev/null +++ b/engines/tsage/ringworld_scenes8.cpp @@ -0,0 +1,2508 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/scene_logic.cpp $ + * $Id: scene_logic.cpp 232 2011-02-12 11:56:38Z dreammaster $ + * + */ + +#include "graphics/cursorman.h" +#include "tsage/ringworld_scenes8.h" +#include "tsage/scenes.h" +#include "tsage/tsage.h" +#include "tsage/staticres.h" + +namespace tSage { + +/*-------------------------------------------------------------------------- + * Scene 7000 + * + *--------------------------------------------------------------------------*/ + +void Scene7000::Action1::signal() { + Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(3); + break; + case 1: + setAction(&scene->_action6, this); + break; + case 2: + scene->_soundHandler.startSound(252, 0, 127); + scene->_object8.remove(); + scene->_object1.postInit(); + scene->_object1.setVisage(7003); + scene->_object1.animate(ANIM_MODE_5, this); + scene->_object1.setPosition(Common::Point(151, 182), 0); + scene->_object1.setPriority2(205); + _globals->_sceneItems.push_front(&scene->_object1); + break; + case 3: + scene->_object1.setStrip(4); + scene->_object1.animate(ANIM_MODE_8, 0, 0); + scene->_stripManager.start(7005, this); + break; + case 4: + scene->_object1.animate(ANIM_MODE_2, 0); + setDelay(3); + break; + case 5: + _globals->_player.enableControl(); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7000::Action2::signal() { + Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(3); + break; + case 1: + _globals->_player.addMover(0, 0); + _globals->_player.setVisage(7006); + _globals->_player.setStrip(1); + _globals->_player.setFrame(1); + _globals->_player.setPosition(Common::Point(_globals->_player._position.x, _globals->_player._position.y + 13)); + _globals->_player.changeZoom(68); + _globals->_player.animate(ANIM_MODE_5, this); + scene->_object1.remove(); + break; + case 2: + _globals->_sceneManager.changeScene(7100); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7000::Action3::dispatch() { + Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene; + + Action::dispatch(); + if (_actionIndex == 4) + scene->_object4.setPosition(Common::Point(scene->_object3._position.x, scene->_object3._position.y)); +} + +/*--------------------------------------------------------------------------*/ + +void Scene7000::Action3::signal() { + Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(30); + scene->setZoomPercents(10, 10, 62, 100); + scene->_object4.postInit(); + scene->_object4.setVisage(5001); + scene->_object4.setStrip2(2); + scene->_object4.animate(ANIM_MODE_8, 0, 0); + scene->_object4.setPosition(Common::Point(10, 18), 0); + scene->_object4.setPriority2(10); + scene->_object4.changeZoom(100); + scene->_object4.hide(); + break; + case 1: { + NpcMover *mover = new NpcMover(); + Common::Point pt(107, 65); + scene->_object3.addMover(mover, &pt, this); + break; + } + case 2: + scene->_object3.setPriority2(10); + scene->_object4.setPosition(Common::Point(scene->_object3._position.x, scene->_object3._position.y + 15), 0); + scene->_object4.show(); + setDelay(30); + break; + case 3: { + NpcMover *mover = new NpcMover(); + Common::Point pt(107, 92); + scene->_object3.addMover(mover, &pt, this); + break; + } + case 4: + scene->_object4.remove(); + _globals->_sceneManager.changeScene(2100); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7000::Action4::signal() { + Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + scene->_object1.animate(ANIM_MODE_6, this); + break; + case 1: + scene->_object1.hide(); + setDelay(300); + break; + case 2: + _globals->_soundHandler.startSound(252, 0, 127); + scene->_object1.show(); + scene->_object1.setStrip(3); + scene->_object1.setFrame(1); + scene->_object1.animate(ANIM_MODE_5, this); + break; + case 3: + scene->_object1.setStrip(1); + scene->_object1.animate(ANIM_MODE_8, 0, 0); + _globals->setFlag(81); + _globals->_player.enableControl(); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7000::Action5::signal() { + Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: { + NpcMover *playerMover = new NpcMover(); + Common::Point pt(88, 121); + _globals->_player.addMover(playerMover, &pt, this); + break; + } + case 1: + _globals->_player.checkAngle(&scene->_object1); + _globals->_soundHandler.startSound(252, 0, 127); + scene->_object1.setStrip(2); + scene->_stripManager.start(7015, this); + break; + case 2: + scene->_object1.setStrip(1); + scene->_object1.setFrame(4); + scene->_object1.animate(ANIM_MODE_6, this); + break; + case 3: { + scene->_object1.remove(); + NpcMover *mover = new NpcMover(); + Common::Point pt(31, 94); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 4: { + NpcMover *mover = new NpcMover(); + Common::Point pt(11, 94); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 5: { + _globals->_player.setPriority2(10); + NpcMover *mover = new NpcMover(); + Common::Point pt(11, 89); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 6: { + NpcMover *mover = new NpcMover(); + Common::Point pt(41, 89); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 7: + _globals->clearFlag(36); + _globals->clearFlag(37); + _globals->clearFlag(72); + _globals->clearFlag(13); + _globals->_sceneManager.changeScene(2100); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7000::Action6::signal() { + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(3); + break; + case 1: { + NpcMover *mover = new NpcMover(); + Common::Point pt(12, 91); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 2: { + NpcMover *mover = new NpcMover(); + Common::Point pt(8, 91); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 3: { + NpcMover *mover = new NpcMover(); + Common::Point pt(31, 96); + _globals->_player.addMover(mover, &pt, this); + _globals->_player.setPriority2(-1); + break; + } + case 4: { + NpcMover *mover = new NpcMover(); + Common::Point pt(83, 117); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 5: { + NpcMover *mover = new NpcMover(); + Common::Point pt(95, 121); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 6: + _globals->_player.setStrip(3); + _globals->_player.setFrame(1); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7000::Action7::signal() { + switch (_actionIndex++) { + case 0: + _globals->_player.disableControl(); + setDelay(3); + break; + case 1: + setDelay(3); + break; + case 2: { + NpcMover *mover = new NpcMover(); + Common::Point pt(31, 94); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 3: { + NpcMover *mover = new NpcMover(); + Common::Point pt(11, 94); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 4: { + _globals->_player.setPriority2(10); + NpcMover *mover = new NpcMover(); + Common::Point pt(11, 89); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 5: { + NpcMover *mover = new NpcMover(); + Common::Point pt(41, 89); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 6: + if (_globals->getFlag(13)) + _globals->_sceneManager.changeScene(2280); + else + _globals->_sceneManager.changeScene(2320); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7000::SceneItem1::doAction(int action) { + if (action == CURSOR_LOOK) + SceneItem::display(7000, 2, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + + SceneItem::doAction(action); +} + +/*--------------------------------------------------------------------------*/ + +void Scene7000::Object1::doAction(int action) { + Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_TRANSLATOR: + _globals->_player.disableControl(); + _globals->_inventory._translator._sceneNumber = 7000; + if (_globals->_inventory._waldos._sceneNumber == 7000) { + if (_globals->_inventory._jar._sceneNumber == 7000) { + scene->_sceneMode = 7012; + scene->setAction(&scene->_sequenceManager, scene, 7010, &_globals->_player, &scene->_object1, 0, 0); + } else { + scene->_sceneMode = 7015; + scene->setAction(&scene->_sequenceManager, scene, 7017, &_globals->_player, 0, 0); + } + } else { + if (_globals->_inventory._jar._sceneNumber == 7000) { + scene->_sceneMode = 7011; + scene->setAction(&scene->_sequenceManager, scene, 7010, &_globals->_player, &scene->_object1, 0, 0); + } else { + scene->_sceneMode = 7004; + scene->setAction(&scene->_sequenceManager, scene, 7004, &_globals->_player, this, 0, 0); + } + } + break; + case OBJECT_WALDOS: + _globals->_player.disableControl(); + _globals->_inventory._waldos._sceneNumber = 7000; + if (_globals->_inventory._translator._sceneNumber == 7000) { + if (_globals->_inventory._jar._sceneNumber == 7000) { + scene->_sceneMode = 7015; + scene->setAction(&scene->_sequenceManager, scene, 7015, &_globals->_player, 0, 0); + } else { + scene->_sceneMode = 7006; + scene->setAction(&scene->_sequenceManager, scene, 7006, &_globals->_player, 0, 0); + } + } else { + scene->_sceneMode = 7009; + scene->setAction(&scene->_sequenceManager, scene, 7009, &_globals->_player, 0, 0); + } + break; + case OBJECT_JAR: + _globals->_player.disableControl(); + _globals->_inventory._jar._sceneNumber = 7000; + if (_globals->_inventory._translator._sceneNumber == 7000) { + if (_globals->_inventory._waldos._sceneNumber == 7000) { + scene->_sceneMode = 7007; + scene->setAction(&scene->_sequenceManager, scene, 7007, &_globals->_player, &scene->_object1, 0, 0); + } else { + scene->_sceneMode = 7015; + scene->setAction(&scene->_sequenceManager, scene, 7016, &_globals->_player, 0, 0); + } + } else { + scene->_sceneMode = 7008; + scene->setAction(&scene->_sequenceManager, scene, 7008, &_globals->_player, 0, 0); + } + break; + case CURSOR_LOOK: + if (_globals->getFlag(81)) + SceneItem::display(7000, 1, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + else + SceneItem::display(7000, 0, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_USE: + if (_globals->getFlag(81)) { + _globals->_inventory._stasisBox._sceneNumber = 1; + _globals->_player.disableControl(); + scene->setAction(&scene->_action5); + } else { + SceneItem::display(7000, 5, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } + break; + case CURSOR_TALK: + if (_globals->getFlag(81)) { + _globals->_inventory._stasisBox._sceneNumber = 1; + _globals->_player.disableControl(); + scene->setAction(&scene->_action5); + } else if (_globals->getFlag(52)) { + scene->_sceneMode = 7005; + scene->setAction(&scene->_sequenceManager, scene, 7013, 0, 0); + } else if (_globals->getFlag(13)) { + _globals->_sceneManager._sceneNumber = 7002; + scene->setAction(&scene->_sequenceManager, scene, 7014, 0, 0); + } else { + _globals->_sceneManager._sceneNumber = 7002; + scene->setAction(&scene->_sequenceManager, scene, 7002, 0, 0); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7000::dispatch() { + Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene; + + if (!_action) { + if (_globals->_sceneRegions.indexOf(_globals->_player._position) == 8) { + if (!_globals->getFlag(13)) { + _globals->_player.disableControl(); + _globals->_player.addMover(0); + SceneItem::display(7000, 3, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + _sceneMode = 7001; + setAction(&scene->_sequenceManager, this, 7001, &_globals->_player, NULL); + } else if (!_globals->getFlag(52)) { + setAction(&_action2); + } else { + _globals->_player.disableControl(); + _sceneMode = 7003; + setAction(&scene->_sequenceManager, this, 7003, &_globals->_player, 0); + } + } + if (_globals->_sceneRegions.indexOf(_globals->_player._position) == 9) + scene->setAction(&scene->_action7); + } + Scene::dispatch(); +} + +/*--------------------------------------------------------------------------*/ + +void Scene7000::postInit(SceneObjectList *OwnerList) { + loadScene(7000); + Scene::postInit(); + setZoomPercents(93, 25, 119, 55); + _stripManager.addSpeaker(&_speakerSKText); + _stripManager.addSpeaker(&_speakerSKL); + _stripManager.addSpeaker(&_speakerQText); + _stripManager.addSpeaker(&_speakerQL); + _stripManager.addSpeaker(&_speakerQR); + + _speakerSKText._npc = &_object1; + _speakerQText._npc = &_globals->_player; + + _object5.postInit(); + _object5.setVisage(7001); + _object5.setStrip2(1); + _object5.animate(ANIM_MODE_2, 0); + _object5.setPosition(Common::Point(49, 147), 0); + _object5.setPriority2(1); + + _object6.postInit(); + _object6.setVisage(7001); + _object6.setStrip2(2); + _object6.animate(ANIM_MODE_2, 0); + _object6.setPosition(Common::Point(160, 139), 0); + _object6.setPriority2(1); + + _object7.postInit(); + _object7.setVisage(7001); + _object7.setStrip2(3); + _object7.animate(ANIM_MODE_2, 0); + _object7.setPosition(Common::Point(272, 129), 0); + _object7.setPriority2(1); + + _object8.postInit(); + _object8.setVisage(7001); + _object8.setStrip2(4); + _object8.animate(ANIM_MODE_2, 0); + _object8.setPosition(Common::Point(176, 175), 0); + _object8.setPriority2(1); + + if (_globals->getFlag(72)) { + _object3.postInit(); + _object3.setVisage(5001); + _object3.setStrip2(1); + _object3.animate(ANIM_MODE_2, 0); + _object3.setPosition(Common::Point(107, 92), 0); + _object3.changeZoom(100); + _object3.setPriority2(10); + + _object1.postInit(); + _object1.setVisage(7003); + if (_globals->getFlag(81)) + _object1.setStrip(4); + else + _object1.setStrip(2); + _object1.setPosition(Common::Point(87, 129), 0); + _object1._numFrames = 4; + _object1.changeZoom(45); + _object1.animate(ANIM_MODE_8, 0, 0); + _globals->_sceneItems.addItems(&_object1, 0); + } + _soundHandler.startSound(251, 0, 127); + if (_globals->_sceneManager._previousScene == 2100) { + if (_globals->getFlag(72)) { + _globals->_player.postInit(); + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, 0); + SceneObjectWrapper *wrapper = new SceneObjectWrapper(); + _globals->_player.setObjectWrapper(wrapper); + _globals->_player.setPosition(Common::Point(57, 94), 0); + _globals->_player.changeZoom(-1); + _globals->_player.setPriority2(10); + if (_globals->getFlag(81)) { + setAction(&_action4); + } else { + _object1.setPosition(Common::Point(151, 182), 0); + setAction(&_action1); + } + } else { + _globals->_soundHandler.startSound(250, 0, 127); + _globals->setFlag(72); + + _object3.postInit(); + _object3.setVisage(5001); + _object3.setStrip2(1); + _object3.animate(ANIM_MODE_1, 0); + _object3.setPosition(Common::Point(307, 0), 0); + _object3.changeZoom(-1); + setAction(&_action3); + } + } else if (_globals->_sceneManager._previousScene == 2280) { + _globals->_player.postInit(); + _globals->_player.setVisage(2170); + _globals->_player.animate(ANIM_MODE_1, 0); + SceneObjectWrapper *wrapper = new SceneObjectWrapper(); + _globals->_player.setObjectWrapper(wrapper); + _globals->_player.setPosition(Common::Point(57, 94), 0); + _globals->_player.changeZoom(-1); + _globals->_player.setPriority2(10); + _globals->_player.disableControl(); + _sceneMode = 7001; + setAction(&_action6, this); + if (!_globals->getFlag(81)) { + _object1.setPosition(Common::Point(151, 182), 0); + _object1.changeZoom(100); + } + _object8.remove(); + _object9.remove(); + } else if (_globals->_sceneManager._previousScene == 2320) { + _globals->_player.postInit(); + _globals->_player.setVisage(0); + _globals->_player.animate(ANIM_MODE_1, 0); + SceneObjectWrapper *wrapper = new SceneObjectWrapper(); + _globals->_player.setObjectWrapper(wrapper); + _globals->_player.setPosition(Common::Point(57, 94), 0); + _globals->_player.changeZoom(-1); + _globals->_player.setPriority2(10); + _sceneMode = 7001; + setAction(&_action6, this); + } else { + _globals->setFlag(72); + + _object3.postInit(); + _object3.setVisage(5001); + _object3.setStrip2(1); + _object3.setPosition(Common::Point(307, 0), 0); + _soundHandler.startSound(151, 0, 127); + _soundHandler.proc5(1); + _globals->_soundHandler.startSound(250, 0, 127); + setAction(&_action3); + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7000::signal() { + Scene7000 *scene = (Scene7000 *)_globals->_sceneManager._scene; + switch (_sceneMode) { + case 7001: + case 7002: + case 7004: + case 7009: + _globals->_player.enableControl(); + break; + case 7003: + _sceneMode = 7001; + setAction(&scene->_sequenceManager, this, 7001, &_globals->_player, NULL); + break; + case 7011: + _sceneMode = 7005; + setAction(&scene->_sequenceManager, this, 7005, &_globals->_player, NULL); + break; + case 7012: + _sceneMode = 7005; + setAction(&scene->_sequenceManager, this, 7012, &_globals->_player, NULL); + break; + case 7015: + setAction(&_action4); + break; + } +} + + +/*-------------------------------------------------------------------------- + * Scene 7100 + * + *--------------------------------------------------------------------------*/ + +void Scene7100::Action3::signal() { + Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(1); + break; + case 1: { + Common::Point pt(433, 308); + NpcMover *mover = new NpcMover(); + scene->_object4.addMover(mover, &pt, this); + break; + } + case 2: + scene->_object4.remove(); + remove(); + break; + } +} + +void Scene7100::Action4::signal() { + Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(_globals->_randomSource.getRandomNumber(1) + 1); + break; + case 1: { + scene->_object5.setStrip(3); + Common::Point pt(85, 52); + NpcMover *mover = new NpcMover(); + scene->_object5.addMover(mover, &pt, this); + break; + } + case 2: { + scene->_object5.setStrip(4); + Common::Point pt(20, 52); + NpcMover *mover = new NpcMover(); + scene->_object5.addMover(mover, &pt, this); + break; + } + case 3: + _actionIndex = 0; + setDelay(1); + break; + } +} + +void Scene7100::Action5::signal() { + Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(1); + break; + case 1: { + Common::Point pt(59, 151); + NpcMover *mover = new NpcMover(); + scene->_object9.addMover(mover, &pt, this); + break; + } + case 2: { + scene->_object9.setStrip2(1); + Common::Point pt(127, 144); + NpcMover *mover = new NpcMover(); + scene->_object9.addMover(mover, &pt, this); + break; + } + case 3: { + scene->_object9.setStrip2(2); + scene->_object9.setPriority2(180); + Common::Point pt(8, 181); + NpcMover *mover = new NpcMover(); + scene->_object9.addMover(mover, &pt, this); + break; + } + case 4: { + scene->_object9.remove(); + remove(); + } + } +} + +void Scene7100::Action6::signal() { + Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(1); + scene->_object10.setPriority2(8); + scene->_object10.setPosition(Common::Point(155, 187), 0); + + scene->_object11.setPriority2(8); + scene->_object11.setPosition(Common::Point(155, 190), 0); + + scene->_object12.setPriority2(8); + scene->_object12.setPosition(Common::Point(151, 193), 0); + break; + case 1: { + Common::Point pt1(167, 187); + NpcMover *mover1 = new NpcMover(); + scene->_object10.addMover(mover1, &pt1, this); + + Common::Point pt2(165, 185); + NpcMover *mover2 = new NpcMover(); + scene->_object11.addMover(mover2, &pt2, 0); + + Common::Point pt3(163, 183); + NpcMover *mover3 = new NpcMover(); + scene->_object12.addMover(mover3, &pt3, 0); + break; + } + case 2: { + scene->_object10.setStrip2(6); + Common::Point pt1(91, 187); + NpcMover *mover1 = new NpcMover(); + scene->_object10.addMover(mover1, &pt1, this); + + scene->_object11.setStrip2(6); + scene->_object11.setPriority2(50); + Common::Point pt2(89, 185); + NpcMover *mover2 = new NpcMover(); + scene->_object11.addMover(mover2, &pt2, 0); + + scene->_object12.setStrip2(6); + scene->_object12.setPriority2(50); + Common::Point pt3(87, 183); + NpcMover *mover3 = new NpcMover(); + scene->_object12.addMover(mover3, &pt3, 0); + break; + } + case 3: + _actionIndex = 0; + setDelay(1); + break; + } +} + +void Scene7100::Action7::signal() { + Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(1); + break; + case 1: { + scene->_object13.setStrip2(8); + Common::Point pt(324, 87); + NpcMover *mover = new NpcMover(); + scene->_object13.addMover(mover, &pt, this); + break; + } + case 2: { + scene->_object13.setStrip2(2); + Common::Point pt(524, 104); + NpcMover *mover = new NpcMover(); + scene->_object13.addMover(mover, &pt, 0); + break; + } + case 3: + _actionIndex = 0; + setDelay(1); + break; + } +} + +void Scene7100::Action8::signal() { + Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(1); + break; + case 1: { + scene->_object17.setStrip2(4); + scene->_object18.setStrip2(4); + scene->_object19.setStrip2(4); + + Common::Point pt1(482, 153); + NpcMover *mover1 = new NpcMover(); + scene->_object17.addMover(mover1, &pt1, this); + + Common::Point pt2(480, 146); + NpcMover *mover2 = new NpcMover(); + scene->_object18.addMover(mover2, &pt2, 0); + + Common::Point pt3(470, 153); + NpcMover *mover3 = new NpcMover(); + scene->_object19.addMover(mover3, &pt3, 0); + break; + } + case 2: { + scene->_object17.setStrip2(3); + scene->_object18.setStrip2(3); + scene->_object19.setStrip2(3); + + Common::Point pt1(506, 186); + NpcMover *mover1 = new NpcMover(); + scene->_object17.addMover(mover1, &pt1, this); + + Common::Point pt2(502, 179); + NpcMover *mover2 = new NpcMover(); + scene->_object18.addMover(mover2, &pt2, 0); + + Common::Point pt3(495, 184); + NpcMover *mover3 = new NpcMover(); + scene->_object19.addMover(mover3, &pt3, 0); + break; + } + case 3: { + scene->_object17.setStrip2(4); + scene->_object18.setStrip2(4); + scene->_object19.setStrip2(4); + + Common::Point pt1(386, 167); + NpcMover *mover1 = new NpcMover(); + scene->_object17.addMover(mover1, &pt1, this); + + Common::Point pt2(379, 161); + NpcMover *mover2 = new NpcMover(); + scene->_object18.addMover(mover2, &pt2, 0); + + Common::Point pt3(373, 167); + NpcMover *mover3 = new NpcMover(); + scene->_object19.addMover(mover3, &pt3, 0); + break; + } + case 4: { + scene->_object17.setStrip2(3); + scene->_object18.setStrip2(3); + scene->_object19.setStrip2(3); + + Common::Point pt1(479, 193); + NpcMover *mover1 = new NpcMover(); + scene->_object17.addMover(mover1, &pt1, this); + + Common::Point pt2(473, 187); + NpcMover *mover2 = new NpcMover(); + scene->_object18.addMover(mover2, &pt2, 0); + + Common::Point pt3(466, 192); + NpcMover *mover3 = new NpcMover(); + scene->_object19.addMover(mover3, &pt3, 0); + break; + } + case 5: { + Common::Point pt1(552, 183); + NpcMover *mover1 = new NpcMover(); + scene->_object17.addMover(mover1, &pt1, this); + + Common::Point pt2(552, 178); + NpcMover *mover2 = new NpcMover(); + scene->_object18.addMover(mover2, &pt2, 0); + + Common::Point pt3(541, 183); + NpcMover *mover3 = new NpcMover(); + scene->_object19.addMover(mover3, &pt3, 0); + + _actionIndex = 0; + break; + } + } +} + +void Scene7100::Action9::signal() { + Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(1); + break; + case 1: { + scene->_object24.setStrip2(1); + Common::Point pt(64, 159); + NpcMover *mover = new NpcMover(); + scene->_object24.addMover(mover, &pt, this); + break; + } + case 2: { + scene->_object24.setStrip2(2); + scene->_object24.setPriority2(160); + Common::Point pt(34, 159); + NpcMover *mover = new NpcMover(); + scene->_object24.addMover(mover, &pt, this); + break; + } + case 3: { + scene->_object24.setStrip2(1); + Common::Point pt(64, 159); + NpcMover *mover = new NpcMover(); + scene->_object24.addMover(mover, &pt, this); + break; + } + case 4: { + scene->_object24.setStrip2(2); + scene->_object24.setPriority2(180); + Common::Point pt(-12, 182); + NpcMover *mover = new NpcMover(); + scene->_object24.addMover(mover, &pt, this); + break; + } + case 5: { + _actionIndex = 0; + setDelay(1); + break; + } + } +} + +void Scene7100::Action10::signal() { + Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(1000); + break; + case 1: { + Common::Point pt(610, -60); + NpcMover *mover = new NpcMover(); + scene->_object25.addMover(mover, &pt, this); + break; + } + case 2: + scene->_object25.remove(); + remove(); + break; + } +} + +void Scene7100::Action11::signal() { + Scene7100 *scene = (Scene7100 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(30); + break; + case 1: { + Common::Point pt(154, 175); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + ObjectMover2 *mover2 = new ObjectMover2(); + scene->_object1.addMover(mover2, 25, 35, &_globals->_player); + break; + } + case 2: { + Common::Point pt(700, 155); + NpcMover *mover = new NpcMover(); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 3: + _globals->_sceneManager.changeScene(7200); + remove(); + break; + } +} + +void Scene7100::postInit(SceneObjectList *OwnerList) { + loadScene(7100); + Scene::postInit(); + setZoomPercents(60, 85, 200, 100); + + _object2.postInit(); + _object2.setVisage(7161); + _object2.animate(ANIM_MODE_2, 0); + _object2.setPosition(Common::Point(10, 140), 0); + _object2._numFrames = 1; + _object2.setPriority2(180); + _object2.setAction(&_action1, 0); + + _object3.postInit(); + _object3.setVisage(7161); + _object3.animate(ANIM_MODE_2, 0); + _object3.setPosition(Common::Point(34, 115), 0); + _object3._numFrames = 1; + _object3.setPriority2(180); + _object3.setAction(&_action2, 0); + + _object4.postInit(); + _object4.setVisage(7164); + _object4.animate(ANIM_MODE_2, 0); + _object4.setPosition(Common::Point(-10, 159), 0); + _object4._numFrames = 2; + _object4.setPriority2(250); + _object4.setAction(&_action3, 0); + + _object5.postInit(); + _object5.setVisage(7162); + _object5.setStrip(3); + _object5.animate(ANIM_MODE_2, 0); + _object5.setPosition(Common::Point(20, 52), 0); + _object5.setAction(&_action4, 0); + + _object9.postInit(); + _object9.setVisage(7160); + _object5.setStrip(2); + _object9.animate(ANIM_MODE_2, 0); + _object9.setPosition(Common::Point(110, 168), 0); + _object9._numFrames = 2; + _object9.setPriority2(16); + _object9.setAction(&_action5, 0); + + _object13.postInit(); + _object13.setVisage(7161); + _object13.setStrip(8); + _object13.animate(ANIM_MODE_2, 0); + _object13.setPosition(Common::Point(524, 104), 0); + _object13._numFrames = 5; + _object13.setPriority2(250); + _object13.setAction(&_action7, 0); + + _object17.postInit(); + _object17.setVisage(7160); + _object17.setStrip(3); + _object17.animate(ANIM_MODE_2, 0); + _object17.setPosition(Common::Point(552, 183), 0); + _object17._numFrames = 4; + _object17._moveDiff.x = 12; + _object17._moveDiff.y = 12; + _object17.setAction(&_action8, 0); + + _object18.postInit(); + _object18.setVisage(7160); + _object18.setStrip(3); + _object18.animate(ANIM_MODE_2, 0); + _object18.setPosition(Common::Point(552, 178), 0); + _object18._numFrames = 4; + _object18._moveDiff.x = 12; + _object18._moveDiff.y = 12; + + _object19.postInit(); + _object19.setVisage(7160); + _object19.setStrip(3); + _object19.animate(ANIM_MODE_2, 0); + _object19.setPosition(Common::Point(541, 183), 0); + _object19._numFrames = 4; + _object19._moveDiff.x = 12; + _object19._moveDiff.y = 12; + + _object24.postInit(); + _object24.setVisage(7162); + _object24.setStrip(1); + _object24.animate(ANIM_MODE_2, 0); + _object24.setPosition(Common::Point(-12, 182), 0); + _object24._numFrames = 4; + _object24.setPriority2(180); + _object24.setAction(&_action9, 0); + + _object25.postInit(); + _object25.setVisage(7163); + _object25.animate(ANIM_MODE_2, 0); + _object25.setPosition(Common::Point(551, 145), 0); + _object25._numFrames = 5; + _object25.setPriority2(160); + _object25.setAction(&_action10, 0); + + // Swimmer 1 + _globals->_player.postInit(); + _globals->_player.setVisage(7101); + _globals->_player.animate(ANIM_MODE_2, 0); + _globals->_player._moveDiff.x = 4; + _globals->_player._moveDiff.y = 2; + _globals->_player.setPosition(Common::Point(135, 135), 0); + _globals->_player.setPriority2(200); + _globals->_player.disableControl(); + + // Swimmer 2 + _object1.postInit(); + _object1.setVisage(7110); + _object1.animate(ANIM_MODE_1, 0); + _object1._moveDiff.x = 4; + _object1._moveDiff.y = 2; + _object1.setPosition(Common::Point(100, 100), 0); + + setAction(&_action11); + _soundHandler1.startSound(270, 0, 127); + _soundHandler2.startSound(275, 0, 127); + _globals->_soundHandler.startSound(270, 0, 127); +} +/*-------------------------------------------------------------------------- + * Scene 7200 + * + *--------------------------------------------------------------------------*/ + +void Scene7200::Action1::signal() { + Scene7200 *scene = (Scene7200 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(15); + break; + case 1: { + PlayerMover *mover1 = new PlayerMover(); + Common::Point pt1(165, 147); + scene->_swimmer.addMover(mover1, &pt1, this); + Common::Point pt2(207, 138); + PlayerMover *mover2 = new PlayerMover(); + _globals->_player.addMover(mover2, &pt2, this); + break; + } + case 2: + break; + case 3: + _globals->_sceneManager.changeScene(7300); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7200::Action2::signal() { + Scene7200 *scene = (Scene7200 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(3); + break; + case 1: { + scene->_object2.setPriority2(25); + scene->_object3.setPriority2(25); + scene->_object4.setPriority2(25); + scene->_object2.setStrip(1); + scene->_object3.setStrip(1); + scene->_object4.setStrip(1); + NpcMover *mover1 = new NpcMover(); + Common::Point pt1(54, 90); + scene->_object2.addMover(mover1, &pt1, this); + NpcMover *mover2 = new NpcMover(); + Common::Point pt2(56, 85); + scene->_object3.addMover(mover2, &pt2, 0); + NpcMover *mover3 = new NpcMover(); + Common::Point pt3(54, 80); + scene->_object4.addMover(mover3, &pt3, 0); + break; + } + case 2: { + scene->_object2.setPriority2(160); + scene->_object3.setPriority2(160); + scene->_object4.setPriority2(160); + scene->_object2.setStrip(2); + scene->_object3.setStrip(2); + scene->_object4.setStrip(2); + NpcMover *mover1 = new NpcMover(); + Common::Point pt1(10, 89); + scene->_object2.addMover(mover1, &pt1, this); + NpcMover *mover2 = new NpcMover(); + Common::Point pt2(12, 84); + scene->_object3.addMover(mover2, &pt2, 0); + NpcMover *mover3 = new NpcMover(); + Common::Point pt3(10, 79); + scene->_object4.addMover(mover3, &pt3, 0); + break; + } + case 3: + _actionIndex = 0; + setDelay(1); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7200::postInit(SceneObjectList *OwnerList) { + loadScene(7200); + Scene::postInit(); + _object2.postInit(); + _object2.setVisage(7160); + _object2.animate(ANIM_MODE_2, 0); + _object2.setZoom(10); + _object2.setPosition(Common::Point(53, 88), 0); + _object2.setAction(&_action2); + + _object3.postInit(); + _object3.setVisage(7160); + _object3.animate(ANIM_MODE_2, 0); + _object3.setZoom(10); + _object3.setPosition(Common::Point(55, 83), 0); + + _object4.postInit(); + _object4.setVisage(7160); + _object4.animate(ANIM_MODE_2, 0); + _object4.setZoom(10); + _object4.setPosition(Common::Point(57, 78), 0); + + _object5.postInit(); + _object5.setVisage(7201); + _object5.setPosition(Common::Point(300, 172), 0); + _object5.setPriority(172); + _object5.animate(ANIM_MODE_2, 0); + _object5._numFrames = 3; + + _object6.postInit(); + _object6.setVisage(7201); + _object6.setStrip2(3); + _object6.setPosition(Common::Point(144, 97), 0); + _object6.setPriority(199); + _object6.animate(ANIM_MODE_2, 0); + _object6._numFrames = 3; + + _object7.postInit(); + _object7.setVisage(7201); + _object7.setStrip2(4); + _object7.setPosition(Common::Point(115, 123), 0); + _object7.setPriority(199); + _object7.animate(ANIM_MODE_2, 0); + _object7._numFrames = 3; + + _object8.postInit(); + _object8.setVisage(7201); + _object8.setStrip2(6); + _object8.setPosition(Common::Point(140, 173), 0); + _object8.setPriority(199); + _object8.animate(ANIM_MODE_2, 0); + _object8._numFrames = 3; + + _object9.postInit(); + _object9.setVisage(7201); + _object9.setStrip2(7); + _object9.setPosition(Common::Point(215, 196), 0); + _object9.setPriority(199); + _object9.animate(ANIM_MODE_2, 0); + _object9._numFrames = 3; + + // Orange swimmer + _globals->_player.postInit(); + _globals->_player.setVisage(7110); + _globals->_player.animate(ANIM_MODE_1, 0); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setZoom(50); + _globals->_player.setPosition(Common::Point(-18, 16), 0); + _globals->_player.disableControl(); + + _swimmer.postInit(); + _swimmer.setVisage(7101); + _swimmer.animate(ANIM_MODE_1, 0); + _swimmer.setObjectWrapper(new SceneObjectWrapper()); + _swimmer.setZoom(50); + _swimmer.setPosition(Common::Point(-8, 16), 0); + + setAction(&_action1); + _soundHandler.startSound(271, 0, 127); +} + +/*-------------------------------------------------------------------------- + * Scene 7300 + * + *--------------------------------------------------------------------------*/ + +void Scene7300::Action1::signal() { + Scene7300 *scene = (Scene7300 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + case 1: + case 3: + setDelay(30); + break; + case 2: + scene->_stripManager.start(7300, this); + break; + case 4: { + NpcMover *mover = new NpcMover(); + Common::Point pt(102, 122); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 5: + _globals->_player.setStrip(2); + _globals->_player.setFrame(1); + _globals->_player.animate(ANIM_MODE_5, this); + break; + case 6: + _globals->_player.setStrip(3); + _globals->_player._numFrames = 5; + _globals->_player.animate(ANIM_MODE_2, this); + if (_globals->_inventory._translator._sceneNumber == 1) + scene->_stripManager.start(7310, this); + else + scene->_stripManager.start(7305, this); + break; + case 7: + setDelay(3); + _globals->_soundHandler.proc1(0); + break; + case 8: + _globals->_sceneManager.changeScene(2280); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7300::Action2::signal() { + Scene7300 *scene = (Scene7300 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(5); + break; + case 1: + NpcMover *mover1 = new NpcMover(); + Common::Point pt(_globals->_randomSource.getRandomNumber(203), _globals->_randomSource.getRandomNumber(96)); + scene->_object3.addMover(mover1, &pt, this); + _actionIndex = 0; + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7300::Action3::signal() { + Scene7300 *scene = (Scene7300 *)_globals->_sceneManager._scene; + + switch (_actionIndex++) { + case 0: + setDelay(5); + break; + case 1: + NpcMover *mover1 = new NpcMover(); + Common::Point pt(_globals->_randomSource.getRandomNumber(76), _globals->_randomSource.getRandomNumber(78)); + scene->_object1.addMover(mover1, &pt, this); + _actionIndex = 0; + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7300::Action4::signal() { + switch (_actionIndex++) { + case 0: + setDelay(5); + break; + case 1: + _actionIndex = 0; + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7300::dispatch() { + Scene7300 *scene = (Scene7300 *)_globals->_sceneManager._scene; + scene->_object4.setPosition(Common::Point(scene->_object3._position.x + 15, scene->_object3._position.y + 61)); + scene->_object2.setPosition(Common::Point(scene->_object1._position.x + 1, scene->_object1._position.y - 31)); + + Scene::dispatch(); +} + +/*--------------------------------------------------------------------------*/ + +void Scene7300::postInit(SceneObjectList *OwnerList) { + loadScene(7300); + + Scene::postInit(); + setZoomPercents(60, 85, 200, 100); + + _globals->setFlag(52); + _globals->setFlag(24); + _globals->setFlag(109); + + _stripManager.addSpeaker(&_speakerPOR); + _stripManager.addSpeaker(&_speakerPOText); + _stripManager.addSpeaker(&_speakerSKText); + _stripManager.addSpeaker(&_speakerQU); + + _speakerSKText.setTextPos(Common::Point(100, 20)); + _speakerPOText.setTextPos(Common::Point(100, 160)); + + _object4.postInit(); + _object4.setVisage(7311); + _object4.setStrip(1); + _object4.setFrame(1); + _object4.setPosition(Common::Point(218, 157), 0); + + _object3.postInit(); + _object3.setVisage(7311); + _object3.setStrip(2); + _object3.setFrame(1); + _object3.setPosition(Common::Point(203, 96), 0); + _object3._numFrames = 2; + _object3._moveDiff = Common::Point(1, 1); + _object3.animate(ANIM_MODE_8, 0, 0); + _object3._field7A = 2; + _object3.setAction(&_action2); + + _globals->_player.postInit(); + _globals->_player.setVisage(7305); + _globals->_player.animate(ANIM_MODE_1, 0); + _globals->_player.setPosition(Common::Point(-100, 100), 0); + _globals->_player.disableControl(); + + _object1.postInit(); + _object1.setVisage(7312); + _object1.animate(ANIM_MODE_1, 0); + _object1._moveDiff = Common::Point(1, 1); + _object1.setPosition(Common::Point(76, 78), 0); + _object1._field7A = 1; + _object1.setAction(&_action3); + + _object2.postInit(); + _object2.setVisage(7312); + _object2.setStrip(2); + _object2.animate(ANIM_MODE_2, 0); + _object2.setPosition(Common::Point(77, 47), 0); + _object2.setPriority2(190); + + _object5.postInit(); + _object5.setVisage(7300); + _object5.setPosition(Common::Point(106, 45), 0); + _object5.animate(ANIM_MODE_2, 0); + _object5._numFrames = 5; + + _object6.postInit(); + _object6.setVisage(7300); + _object6.setStrip2(2); + _object6.setPosition(Common::Point(283, 193), 0); + _object6.animate(ANIM_MODE_2, 0); + _object6._numFrames = 3; + + _object7.postInit(); + _object7.setVisage(7300); + _object7.setStrip(4); + _object7.setPosition(Common::Point(295, 77), 0); + _object7.animate(ANIM_MODE_2, 0); + _object7._numFrames = 3; + + _object8.postInit(); + _object8.setVisage(7300); + _object8.setStrip(5); + _object8.setPosition(Common::Point(1, 147), 0); + _object8.animate(ANIM_MODE_2, 0); + _object8._numFrames = 2; + + setAction(&_action1); + _globals->_soundHandler.startSound(272, 0, 127); +} + +/*-------------------------------------------------------------------------- + * Scene 7600 + * + *--------------------------------------------------------------------------*/ + +void Scene7600::Action1::signal() { + switch (_actionIndex++) { + case 0: + setDelay(120); + break; + case 1: { + PlayerMover *mover = new PlayerMover(); + Common::Point pt(389, 57); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 2: + _globals->_sceneManager.changeScene(7700); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7600::Action2::signal() { + switch (_actionIndex++) { + case 0: + setDelay(30); + break; + case 1: { + NpcMover *mover = new NpcMover(); + Common::Point pt(-30, 195); + _globals->_player.addMover(mover, &pt, this); + break; + } + case 2: + _globals->_sceneManager.changeScene(2320); + remove(); + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void Scene7600::postInit(SceneObjectList *OwnerList) { + Scene::postInit(); + setZoomPercents(100, 0, 200, 100); + + _object2.postInit(); + _object2.setVisage(7601); + _object2.setStrip(1); + _object2.animate(ANIM_MODE_2, 0); + _object2.setPosition(Common::Point(48, 135)); + _object2.setPriority2(1); + + _object3.postInit(); + _object3.setVisage(7601); + _object3.setStrip(2); + _object3.animate(ANIM_MODE_2, 0); + _object3.setPosition(Common::Point(158, 136)); + _object3.setPriority2(1); + + _object4.postInit(); + _object4.setVisage(7601); + _object4.setStrip(3); + _object4.animate(ANIM_MODE_2, 0); + _object4.setPosition(Common::Point(293, 141)); + _object4.setPriority2(1); + + _object5.postInit(); + _object5.setVisage(7601); + _object5.setStrip(4); + _object5.animate(ANIM_MODE_2, 0); + _object5.setPosition(Common::Point(405, 143)); + _object5.setPriority2(1); + + _object6.postInit(); + _object6.setVisage(7601); + _object6.setStrip(5); + _object6.animate(ANIM_MODE_2, 0); + _object6.setPosition(Common::Point(379, 191)); + _object6.setPriority2(1); + + _globals->_player.postInit(); + _globals->_player.setVisage(2333); + _globals->_player.animate(ANIM_MODE_1, 0); + _globals->_player.setObjectWrapper(new SceneObjectWrapper()); + _globals->_player.setStrip(1); + _globals->_player._moveDiff = Common::Point(16, 16); + _globals->_player.changeZoom(-1); + _globals->_player.disableControl(); + + if (_globals->_sceneManager._previousScene == 7700) { + _globals->_player.setPosition(Common::Point(389, 57)); + setAction(&_action2); + } else { + _globals->_player.setPosition(Common::Point(-50, 195)); + setAction(&_action1); + } + _sceneBounds.centre(_globals->_player._position.x, _globals->_player._position.y); + loadScene(7600); + _soundHandler2.startSound(255); + _soundHandler1.startSound(251); +} + +/*-------------------------------------------------------------------------- + * Scene 7700 + * + *--------------------------------------------------------------------------*/ + +void Scene7700::Action1::signal() { + SceneObject *fmtObj = (SceneObject *) _fmt; + switch (_actionIndex++) { + case 0: { + PlayerMover *mover1 = new PlayerMover(); + Common::Point pt = Common::Point(fmtObj->_position.x, fmtObj->_position.y + 30); + _globals->_player.addMover(mover1, &pt, this); + break; + } + case 1: + _globals->_player.checkAngle(fmtObj); + if (_globals->_player._field8C == 0) + fmtObj->animate(ANIM_MODE_5, this); + else + fmtObj->animate(ANIM_MODE_6, this); + break; + case 2: + remove(); + break; + } +} + +void Scene7700::Action2::signal() { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + switch (_actionIndex++) { + case 0: + case 2: + setDelay(_globals->_randomSource.getRandomNumber(60) + 60); + break; + case 1: + scene->_prof.animate(ANIM_MODE_7, 0, 0); + setDelay(20); + break; + case 3: + scene->_prof.animate(ANIM_MODE_6, this); + _actionIndex = 0; + break; + } +} + +void Scene7700::Action3::signal() { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + switch (_actionIndex++) { + case 0: + scene->_object15.animate(ANIM_MODE_5, this); + break; + case 1: + scene->_sceneItem10.remove(); + scene->_object15.remove(); + scene->_sceneHotspot8.remove(); + scene->_sceneHotspot9.remove(); + scene->_object19.remove(); + setDelay(60); + // No break on purpose! + case 2: + scene->_soundHandler.startSound(260, 0, 127); + scene->_object8.setVisage(7703); + scene->_object8.setPosition(Common::Point(177, 97), 0); + scene->_object8.setStrip2(3); + scene->_object8.animate(ANIM_MODE_5, this); + scene->_object8._numFrames = 3; + break; + case 3: + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene7700::Action4::signal() { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + switch (_actionIndex++) { + case 2: + scene->_object13.remove(); + // No break on purpose! + case 0: + setDelay(3); + break; + case 1: + CursorMan.showMouse(false); + scene->_object13.postInit(); + scene->_object13.setVisage(7700); + scene->_object13.setStrip2(7); + scene->_object13.setPosition(Common::Point(151, 33), 0); + scene->_object13.animate(ANIM_MODE_5, this); + break; + case 3: + CursorMan.showMouse(true); + SceneItem::display(7700, 11, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + _globals->_player.enableControl(); + remove(); + break; + } +} + +void Scene7700::Action5::signal() { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + switch (_actionIndex++) { + case 0: + setDelay(_globals->_randomSource.getRandomNumber(240)); + break; + case 1: { + scene->_cloud.setFrame(_globals->_randomSource.getRandomNumber(1) + 1); + scene->_cloud.setPosition(Common::Point(133, 145 + _globals->_randomSource.getRandomNumber(54)), 0); + + Common::Point pt(360, scene->_cloud._position.y); + NpcMover *mover = new NpcMover(); + scene->_cloud.addMover(mover, &pt, this); + _actionIndex = 0; + break; + } + } +} + +void Scene7700::Action6::signal() { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + switch (_actionIndex++) { + case 0: + setDelay(5); + break; + case 1: { + Common::Point pt(2, 66); + NpcMover *mover = new NpcMover(); + scene->_easterEgg1.addMover(mover, &pt, this); + break; + } + case 2: + scene->_easterEgg1.setStrip(2); + scene->_easterEgg1.setPosition(Common::Point(43, 65), 0); + + scene->_easterEgg2.postInit(); + scene->_easterEgg2.setVisage(7708); + scene->_easterEgg2.setStrip(3); + scene->_easterEgg2.setPosition(Common::Point(116, 54), 0); + scene->_easterEgg2.animate(ANIM_MODE_2, 0); + + setDelay(120); + break; + case 3: + scene->_easterEgg1.remove(); + scene->_easterEgg2.remove(); + remove(); + break; + } +} + +void Scene7700::SceneHotspot1::doAction(int action) { + if (action == CURSOR_LOOK) + SceneItem::display(7700, 4, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + else + SceneHotspot::doAction(action); +} + +void Scene7700::SceneHotspot2::doAction(int action) { + if (action == CURSOR_LOOK) + SceneItem::display(7700, 6, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + else + SceneHotspot::doAction(action); +} + +void Scene7700::SceneHotspot3::doAction(int action) { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_KEY: + SceneItem::display(7702, 3, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + _globals->_inventory._key._sceneNumber = 7700; + break; + case CURSOR_LOOK: + if (_globals->_inventory._key._sceneNumber == 7700) + scene->setAction(&scene->_action4, 0); + else + SceneItem::display(7700, 53, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_USE: + if (!_globals->getFlag(78)) { + scene->_sceneMode = 7712; + scene->setAction(&scene->_sequenceManager, scene, 7715, 0); + } else if (_globals->_inventory._key._sceneNumber == 7700) { + _globals->_player.disableControl(); + scene->_sceneMode = 7705; + scene->setAction(&scene->_sequenceManager, scene, 7705, &_globals->_player, 0); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene7700::SceneHotspot4::doAction(int action) { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display(7700, 12, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_USE: + if (!_globals->getFlag(78)) { + scene->_sceneMode = 7712; + scene->setAction(&scene->_sequenceManager, scene, 7715, 0); + } else { + SceneItem::display(7700, 12, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene7700::SceneHotspot5::doAction(int action) { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display(7700, 28, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_USE: + if (_globals->getFlag(78)) { + if (_globals->_inventory._paper._sceneNumber == 7700) { + _globals->_player.disableControl(); + scene->_sceneMode = 7708; + scene->setAction(&scene->_sequenceManager, scene, 7708, &_globals->_player, 0); + } + } else { + scene->_sceneMode = 7712; + scene->setAction(&scene->_sequenceManager, scene, 7715, 0); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene7700::SceneHotspot6::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + SceneItem::display(7700, 43, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_USE: + SceneItem::display(7700, 56, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene7700::SceneItem7::doAction(int action) { + if (action == CURSOR_LOOK) + SceneItem::display(7700, 51, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); +} + +void Scene7700::SceneHotspot8::doAction(int action) { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display(7700, 48, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_USE: + scene->_sceneMode = 7709; + scene->_soundHandler.startSound(259, 0, 127); + scene->_object15.setFrame(scene->_object15.getFrameCount()); + scene->_object15.animate(ANIM_MODE_6, scene); + if ((scene->_field977 == 2) && (scene->_field97B == 0)) { + scene->_field979++; + } else { + scene->_field97B = 0; + scene->_field979 = 0; + scene->_field977 = 0; + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene7700::SceneHotspot9::doAction(int action) { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display(7700, 48, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_USE: + scene->_sceneMode = 7709; + scene->_soundHandler.startSound(259, 0, 127); + scene->_object15.setFrame(1); + scene->_object15.animate(ANIM_MODE_5, scene); + if (scene->_field977 > 2) { + scene->_field97B = 0; + scene->_field979 = 0; + scene->_field977 = 0; + } + + if (scene->_field979 != 0) { + if (scene->_field979 != 4) { + scene->_field97B = 0; + scene->_field979 = 0; + scene->_field977 = 0; + } else { + scene->_field97B++; + if (scene->_field97B == 3) { + _globals->_player.disableControl(); + scene->setAction(&scene->_action3); + } + } + } else { + scene->_field977++; + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene7700::SceneItem10::doAction(int action) { +} + +void Scene7700::Object1::doAction(int action) { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + + if (action == CURSOR_LOOK) { + SceneItem::display(7700, _lookLineNum, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } else if (action == CURSOR_USE) { + if (_globals->getFlag(78)) { + _globals->_player.disableControl(); + scene->setAction(&scene->_action1, this); + } else { + scene->_sceneMode = 7712; + scene->setAction(&scene->_sequenceManager, scene, 7715, 0); + } + } else { + SceneHotspot::doAction(action); + } +} + +void Scene7700::SceneHotspot11::doAction(int action) { + switch (action) { + case CURSOR_LOOK: + SceneItem::display(7700, _lookLineNum, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_USE: + SceneItem::display(7701, _useLineNum, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene7700::Object1::signal() { + if (_state == 0) { + _state = 1; + SceneItem::display(7701, _defltLineNum, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } else { + _state = 0; + } + _globals->_player.enableControl(); +} + +void Scene7700::Object3::doAction(int action) { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + + if (action == CURSOR_LOOK) { + SceneItem::display(7700, 34, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } else if (action == CURSOR_USE) { + if (_globals->getFlag(78)) { + if (scene->_object3._frame == 1) { + _globals->_player.disableControl(); + scene->_sceneMode = 7707; + scene->setAction(&scene->_sequenceManager, scene, 7707, &_globals->_player, this, 0); + } else { + SceneItem::display(7700, 60, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } + } else { + scene->_sceneMode = 7712; + scene->setAction(&scene->_sequenceManager, scene, 7715, 0); + } + } else { + SceneHotspot::doAction(action); + } +} + +void Scene7700::Object7::doAction(int action) { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + if (_globals->getFlag(78)) + SceneItem::display(7700, 45, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + else + SceneItem::display(7700, 44, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_USE: + if (_globals->getFlag(78)) { + SceneItem::display(7701, 41, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } else { + scene->_sceneMode = 7712; + scene->setAction(&scene->_sequenceManager, scene, 7714, 0); + } + break; + case CURSOR_TALK: + if (_globals->getFlag(78)) { + SceneItem::display(7702, 1, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } else { + _globals->_player.disableControl(); + if (_state == 0) { + _state = 1; + scene->_sceneMode = 7703; + scene->setAction(&scene->_sequenceManager, scene, 7703, 0); + } else { + scene->_sceneMode = 7712; + scene->setAction(&scene->_sequenceManager, scene, 7712, 0); + } + } + break; + case OBJECT_STUNNER: + if (!_globals->getFlag(78)) { + _globals->_soundHandler.proc3(); + _globals->setFlag(78); + setAction(0); + _globals->_player.disableControl(); + scene->_sceneMode = 7704; + scene->setAction(&scene->_sequenceManager, scene, 7704, &_globals->_player, this, 0); + } + break; + default: + SceneHotspot::doAction(action); + break; + } +} + +void Scene7700::Object8::doAction(int action) { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + + if ((action == CURSOR_LOOK) || (action == CURSOR_USE)) { + if (_strip == 3) { + scene->_object9.postInit(); + scene->_object9.setVisage(7701); + scene->_object9.setStrip2(3); + scene->_object9.setPosition(Common::Point(91, 166), 0); + scene->_object9.setPriority2(200); + + scene->_object14.postInit(); + scene->_object14.setVisage(7701); + scene->_object14.setStrip(2); + scene->_object14.setPriority2(250); + scene->_object14.setPosition(Common::Point(139, 151), 0); + + scene->_gfxButton.setText(EXIT_MSG); + scene->_gfxButton._bounds.centre(140, 189); + scene->_gfxButton.draw(); + scene->_gfxButton._bounds.expandPanes(); + + _globals->_sceneItems.push_front(&scene->_object10); + _globals->_sceneItems.push_front(&scene->_object9); + _globals->_player._canWalk = false; + } else { + scene->_object15.postInit(); + scene->_object15.setVisage(7701); + scene->_object15.setPosition(Common::Point(140, 165), 0); + scene->_object15.setPriority2(200); + + scene->_gfxButton.setText(EXIT_MSG); + scene->_gfxButton._bounds.centre(140, 186); + scene->_gfxButton.draw(); + scene->_gfxButton._bounds.expandPanes(); + + scene->_object19.postInit(); + scene->_object19.setVisage(7700); + scene->_object19.setStrip(6); + scene->_object19.setPosition(Common::Point(140, 192), 0); + + _globals->_sceneItems.push_front(&scene->_object10); + _globals->_sceneItems.push_front(&scene->_object8); + _globals->_sceneItems.push_front(&scene->_object9); + _globals->_events.setCursor(CURSOR_WALK); + _globals->_player._canWalk = false; + } + } else { + SceneHotspot::doAction(action); + } +} + +void Scene7700::Object9::doAction(int action) { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + + switch (action) { + case CURSOR_LOOK: + SceneItem::display(7700, 49, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_USE: + SceneItem::display(7701, 42, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_TALK: + SceneItem::display(7702, 4, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case OBJECT_KEY: + if (_frame == 1) { + if (!_globals->getFlag(80)) { + scene->_object10.postInit(); + scene->_object10.setVisage(7701); + scene->_object10.setStrip(4); + scene->_object10.setPosition(Common::Point(159, 136)); + _globals->_sceneItems.push_front(&scene->_object10); + scene->_object10.setPriority2(240); + } + scene->_soundHandler.startSound(262, 0, 127); + scene->_object14.animate(ANIM_MODE_5, 0); + } + _globals->_events.setCursor(CURSOR_WALK); + break; + default: + SceneHotspot::doAction(action); + } +} + +void Scene7700::Object10::doAction(int action) { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + + if (action == CURSOR_LOOK) { + SceneItem::display(7700, 50, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } else if (action == CURSOR_USE) { + _globals->setFlag(80); + scene->_sceneItem10.remove(); + scene->_gfxButton._bounds.expandPanes(); + scene->_object14.remove(); + scene->_object9.remove(); + remove(); + } else { + SceneHotspot::doAction(action); + } +} + +void Scene7700::Object11::doAction(int action) { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + + switch (action) { + case OBJECT_SCANNER: + if (_frame != 1) + SceneItem::display(7701, 44, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + else + SceneItem::doAction(action); + break; + case CURSOR_LOOK: + if (_frame != 1) + SceneItem::display(7700, 9, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + else + SceneItem::display(7700, 52, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case CURSOR_USE: + if (_frame != 1) { + SceneItem::display(7701, 8, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } else { + _globals->setFlag(49); + _globals->_player.disableControl(); + scene->_sceneMode = 7706; + scene->setAction(&scene->_sequenceManager, scene, 7706, &_globals->_player, this, NULL); + } + break; + case OBJECT_EMPTY_JAR: + _globals->_inventory._emptyJar._sceneNumber = 0; + _globals->_inventory._jar._sceneNumber = 1; + _globals->_player.disableControl(); + scene->_sceneMode = 7710; + scene->setAction(&scene->_sequenceManager, scene, 7710, &_globals->_player, NULL); + break; + default: + SceneHotspot::doAction(action); + } +} + +void Scene7700::Object12::doAction(int action) { + Scene7700 *scene = (Scene7700 *)_globals->_sceneManager._scene; + + if (action == CURSOR_LOOK) { + SceneItem::display(7700, 15, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + } else if (action == CURSOR_USE) { + if (_globals->getFlag(78)) { + scene->_sceneMode = 7713; + scene->setAction(&scene->_sequenceManager, scene, 7713, &_globals->_player, NULL); + } else { + scene->_sceneMode = 7712; + scene->setAction(&scene->_sequenceManager, scene, 7715, NULL); + } + } else { + SceneHotspot::doAction(action); + } +} + +void Scene7700::signal() { + switch (_sceneMode) { + case 7701: + _globals->_player.setPriority2(-1); + _globals->_player.setStrip2(-1); + if (_globals->getFlag(78)) { + _globals->_player.enableControl(); + } else { + _sceneMode = 7711; + setAction(&_sequenceManager, this, 7711, 0); + } + break; + case 7702: + _soundHandler.proc1(0); + _globals->_sceneManager.changeScene(7600); + break; + case 7703: + case 7706: + case 7707: + case 7711: + case 7712: + _globals->_player.enableControl(); + break; + case 7704: + _globals->_soundHandler.startSound(256, 0, 127); + _prof.setStrip2(4); + _prof.setFrame2(1); + _prof.setPosition(Common::Point(159, 87), 0); + _globals->_player.enableControl(); + break; + case 7705: + case 7708: + _globals->_inventory._key._sceneNumber = 1; + _globals->_player.enableControl(); + break; + case 7709: + _globals->_events.setCursor(CURSOR_USE); + break; + case 7710: + _globals->_player.enableControl(); + SceneItem::display(7700, 62, SET_WIDTH, 200, SET_EXT_BGCOLOUR, 7, LIST_END); + break; + case 7713: + _emptyJar.remove(); + _globals->_inventory._emptyJar._sceneNumber = 1; + break; + default: + break; + } +} + +void Scene7700::process(Event &event) { + Scene::process(event); + + if (_globals->_sceneItems.contains(&_sceneItem10)) { + if (_gfxButton.process(event)) { + _sceneItem10.remove(); + _sceneHotspot15.remove(); + _sceneHotspot9.remove(); + if (_globals->_sceneObjects->contains(&_object10)) + _object10.remove(); + if (_globals->_sceneObjects->contains(&_object14)) + _object14.remove(); + _object19.remove(); + _gfxButton._bounds.expandPanes(); + _globals->_player._canWalk = true; + } + } + if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_p)) { + event.handled = true; + if (!_globals->_sceneObjects->contains(&_easterEgg1)) { + _easterEgg1.postInit(); + _easterEgg1.setVisage(7708); + _easterEgg1.setPosition(Common::Point(163, 50), 0); + _easterEgg1.setPriority2(1); + _easterEgg1.animate(ANIM_MODE_2, 0); + _easterEgg1.setAction(&_action6); + } + } +} + +void Scene7700::dispatch() { + if ((_globals->_sceneRegions.indexOf(_globals->_player._position) == 6) || (_globals->_player._position.x < 10)) + _globals->_player.changeZoom(100 - ((_globals->_player._position.y - 68) / 2)); + else + _globals->_player.changeZoom(-1); + + if ((_action == 0) && (_globals->_sceneRegions.indexOf(_globals->_player._position) == 30)) { + _globals->_player.disableControl(); + _sceneMode = 7702; + setAction(&_sequenceManager, this, 7702, &_globals->_player, 0); + } + Scene::dispatch(); +} + +void Scene7700::postInit(SceneObjectList *OwnerList) { + loadScene(7700); + Scene::postInit(); + setZoomPercents(100, 80, 200, 100); + _globals->setFlag(53); + _field97B = 0; + _field979 = 0; + _field977 = 0; + + _stripManager.addSpeaker(&_speakerEText); + _stripManager.addSpeaker(&_speakerQText); + _speakerQText._npc = &_globals->_player; + _speakerEText._npc = &_prof; + + _globals->_player.postInit(); + _globals->_player.setVisage(4201); + _globals->_player.animate(ANIM_MODE_1, 0); + SceneObjectWrapper *wrapper = new SceneObjectWrapper(); + _globals->_player.setObjectWrapper(wrapper); + _globals->_player.setPosition(Common::Point(-19, 68), 0); + _globals->_player.setStrip2(7); + _globals->_player.setPriority2(95); + _globals->_player.changeZoom(80); + _globals->_player._moveDiff.x = 6; + _globals->_player._moveDiff.y = 3; + _globals->_player.disableControl(); + + _prof.postInit(); + _prof.setVisage(7706); + + if (_globals->getFlag(78)) { + _prof.setStrip2(4); + _prof.setPriority2(80); + _prof.setPosition(Common::Point(159, 87), 0); + } else { + _prof.setPosition(Common::Point(203, 87), 0); + _prof.setStrip2(2); + _prof._numFrames = 6; + _prof.setAction(&_action2); + } + + _cloud.postInit(); + _cloud.setVisage(7700); + _cloud.setStrip2(5); + _cloud.setPriority2(1); + _cloud.setPosition(Common::Point(133, 160), 0); + _cloud._moveDiff.x = 1; + _cloud._field7A = 7; + _cloud.setAction(&_action5); + + _object1.postInit(); + _object1.setVisage(7700); + _object1.setPosition(Common::Point(184, 61), 0); + _object1._lookLineNum = 18; + _object1._defltLineNum = 16; + + _object2.postInit(); + _object2.setVisage(7700); + _object2.setPosition(Common::Point(184, 70), 0); + _object2.setPriority2(60); + _object2._lookLineNum = 19; + _object2._defltLineNum = 17; + + _object3.postInit(); + _object3.setVisage(7703); + _object3.setPosition(Common::Point(288, 36), 0); + _object3.setStrip(2); + + _object4.postInit(); + _object4.setVisage(7700); + _object4.setPosition(Common::Point(268, 59), 0); + _object4.setStrip(2); + _object4._lookLineNum = 37; + _object4._defltLineNum = 35; + + _object5.postInit(); + _object5.setVisage(7700); + _object5.setPosition(Common::Point(268, 67), 0); + _object5.setPriority2(58); + _object5.setStrip2(3); + _object5._lookLineNum = 38; + _object5._defltLineNum = 36; + + _object6.postInit(); + _object6.setVisage(7700); + _object6.setPosition(Common::Point(268, 75), 0); + _object6.setPriority2(57); + _object6.setStrip2(4); + _object6._lookLineNum = 40; + _object6._defltLineNum = 43; + + _object8.postInit(); + _object8.setVisage(7703); + _object8.setPosition(Common::Point(203, 91), 0); + _object8.setStrip2(4); + _object8.setPriority2(86); + + _sceneHotspot8.setBounds(82, 141, 161, 92); + _sceneHotspot9.setBounds(82, 187, 161, 141); + + _cork.postInit(); + _cork.setVisage(7703); + _cork.setPosition(Common::Point(32, 128), 0); + + if (_globals->getFlag(49)) + _cork.setFrame(_cork.getFrameCount()); + + if (_globals->_inventory._emptyJar._sceneNumber == 7700) { + _emptyJar.postInit(); + _emptyJar.setVisage(7700); + _emptyJar.setStrip(8); + _emptyJar.setPosition(Common::Point(189, 48), 0); + _globals->_sceneItems.addItems(&_emptyJar, NULL); + } + _sceneHotspot1._sceneRegionId = 28; + _sceneHotspot2._sceneRegionId = 6; + _sceneHotspot3._sceneRegionId = 10; + _sceneHotspot4._sceneRegionId = 11; + _sceneHotspot5._sceneRegionId = 9; + _sceneHotspot6._sceneRegionId = 7; + + _sceneItem7.setBounds(0, 320, 200, 0); + _sceneItem10.setBounds(0, 320, 200, 0); + + _sceneHotspot11._sceneRegionId = 57; + _sceneHotspot11._useLineNum = 0; + _sceneHotspot11._lookLineNum = 0; + _sceneHotspot12._sceneRegionId = 2; + _sceneHotspot12._useLineNum = 2; + _sceneHotspot12._lookLineNum = 2; + _sceneHotspot13._sceneRegionId = 12; + _sceneHotspot13._useLineNum = 3; + _sceneHotspot13._lookLineNum = 3; + _sceneHotspot14._sceneRegionId = 18; + _sceneHotspot14._useLineNum = 4; + _sceneHotspot14._lookLineNum = 5; + _sceneHotspot15.setBounds(0, 55, 50, 8); + _sceneHotspot15._useLineNum = 6; + _sceneHotspot15._lookLineNum = 7; + _sceneHotspot16.setBounds(0, 130, 34, 103); + _sceneHotspot16._useLineNum = 8; + _sceneHotspot16._lookLineNum = 9; + _sceneHotspot17.setBounds(41, 180, 46, 170); + _sceneHotspot17._useLineNum = 11; + _sceneHotspot17._lookLineNum = 13; + _sceneHotspot18.setBounds(38, 187, 46, 180); + _sceneHotspot18._useLineNum = 12; + _sceneHotspot18._lookLineNum = 14; + _sceneHotspot19._sceneRegionId = 3; + _sceneHotspot19._useLineNum = 14; + _sceneHotspot19._lookLineNum = 16; + _sceneHotspot20._sceneRegionId = 14; + _sceneHotspot20._useLineNum = 15; + _sceneHotspot20._lookLineNum = 17; + _sceneHotspot21.setBounds(9, 215, 26, 210); + _sceneHotspot21._useLineNum = 18; + _sceneHotspot21._lookLineNum = 20; + _sceneHotspot22.setBounds(10, 221, 26, 215); + _sceneHotspot22._useLineNum = 19; + _sceneHotspot22._lookLineNum = 21; + _sceneHotspot23.setBounds(6, 230, 26, 225); + _sceneHotspot23._useLineNum = 20; + _sceneHotspot23._lookLineNum = 22; + _sceneHotspot24._sceneRegionId = 13; + _sceneHotspot24._useLineNum = 21; + _sceneHotspot24._lookLineNum = 23; + _sceneHotspot25._sceneRegionId = 21; + _sceneHotspot25._useLineNum = 22; + _sceneHotspot25._lookLineNum = 24; + _sceneHotspot26._sceneRegionId = 19; + _sceneHotspot26._useLineNum = 23; + _sceneHotspot26._lookLineNum = 25; + _sceneHotspot27._sceneRegionId = 27; + _sceneHotspot27._useLineNum = 24; + _sceneHotspot27._lookLineNum = 26; + _sceneHotspot28._sceneRegionId = 15; + _sceneHotspot28._useLineNum = 25; + _sceneHotspot28._lookLineNum = 27; + _sceneHotspot29._sceneRegionId = 26; + _sceneHotspot29._useLineNum = 27; + _sceneHotspot29._lookLineNum = 29; + _sceneHotspot30.setBounds(0, 317, 34, 310); + _sceneHotspot30._useLineNum = 28; + _sceneHotspot30._lookLineNum = 30; + _sceneHotspot31._sceneRegionId = 17; + _sceneHotspot31._useLineNum = 29; + _sceneHotspot31._lookLineNum = 31; + _sceneHotspot32._sceneRegionId = 25; + _sceneHotspot32._useLineNum = 30; + _sceneHotspot32._lookLineNum = 32; + _sceneHotspot33._sceneRegionId = 5; + _sceneHotspot33._useLineNum = 31; + _sceneHotspot33._lookLineNum = 33; + _sceneHotspot34.setBounds(42, 292, 48, 281); + _sceneHotspot34._useLineNum = 32; + _sceneHotspot34._lookLineNum = 35; + _sceneHotspot35._sceneRegionId = 24; + _sceneHotspot35._useLineNum = 38; + _sceneHotspot35._lookLineNum = 41; + _sceneHotspot36._sceneRegionId = 1; + _sceneHotspot36._useLineNum = 39; + _sceneHotspot36._lookLineNum = 42; + + _globals->_sceneItems.addItems(&_prof, &_sceneHotspot35, &_object8, &_sceneHotspot34, &_sceneHotspot33, &_sceneHotspot32, NULL); + _globals->_sceneItems.addItems(&_sceneHotspot31, &_sceneHotspot30, &_sceneHotspot29, &_sceneHotspot5, &_sceneHotspot28, &_sceneHotspot27, NULL); + _globals->_sceneItems.addItems(&_sceneHotspot26, &_sceneHotspot25, &_sceneHotspot24, &_sceneHotspot23, &_sceneHotspot22, &_sceneHotspot21, NULL); + _globals->_sceneItems.addItems(&_sceneHotspot20, &_sceneHotspot19, &_sceneHotspot18, &_sceneHotspot17, &_sceneHotspot4, &_sceneHotspot3, NULL); + _globals->_sceneItems.addItems(&_sceneHotspot16, &_sceneHotspot15, &_sceneHotspot2, &_sceneHotspot14, &_cork, &_sceneHotspot1, NULL); + _globals->_sceneItems.addItems(&_sceneHotspot13, &_sceneHotspot12, &_sceneHotspot11, &_object2, &_object1, &_object3, NULL); + _globals->_sceneItems.addItems(&_object6, &_object5, &_object4, &_sceneHotspot6, &_sceneHotspot36, &_sceneItem7, NULL); + + _sceneMode = 7701; + setAction(&_sequenceManager, this, 7701, &_globals->_player, 0); + _soundHandler.startSound(256, 0, 127); +} + +Scene7700::Scene7700() { + _object1._state = 0; + _object2._state = 0; + _object4._state = 0; + _object5._state = 0; + _object6._state = 0; + _prof._state = 0; +} + +} // End of namespace tSage diff --git a/engines/tsage/ringworld_scenes8.h b/engines/tsage/ringworld_scenes8.h new file mode 100644 index 0000000000..929426696e --- /dev/null +++ b/engines/tsage/ringworld_scenes8.h @@ -0,0 +1,495 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/scene_logic.h $ + * $Id: scene_logic.h 232 2011-02-12 11:56:38Z dreammaster $ + * + */ + +#ifndef TSAGE_RINGWORLD_SCENES8_H +#define TSAGE_RINGWORLD_SCENES8_H + +#include "common/scummsys.h" +#include "tsage/ringworld_logic.h" +#include "tsage/events.h" +#include "tsage/core.h" +#include "tsage/scenes.h" +#include "tsage/globals.h" + +namespace tSage { + +class NamedHotspotMult: public SceneHotspot { +public: + int _useLineNum, _lookLineNum; + NamedHotspotMult(): SceneHotspot() {} + + virtual Common::String getClassName() { return "NamedHotspotMult"; } +}; + +class SceneObject7700: public SceneObjectExt { +public: + int _lookLineNum, _defltLineNum; + + virtual void synchronise(Serialiser &s) { + SceneObject::synchronise(s); + s.syncAsSint16LE(_lookLineNum); + s.syncAsSint16LE(_defltLineNum); + } + virtual Common::String getClassName() { return "SceneObject7700"; } +}; + +class Scene7000: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void dispatch(); + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + class Action5: public Action { + public: + virtual void signal(); + }; + class Action6: public Action { + public: + virtual void signal(); + }; + class Action7: public Action { + public: + virtual void signal(); + }; + + /* Objects */ + class Object1: public SceneObject { + public: + virtual void doAction(int action); + }; + + /* Items */ + class SceneItem1: public SceneItem { + public: + virtual void doAction(int action); + }; + +public: + SoundHandler _soundHandler; + SequenceManager _sequenceManager; + SpeakerSKText _speakerSKText; + SpeakerSKL _speakerSKL; + SpeakerQL _speakerQL; + SpeakerQR _speakerQR; + SpeakerQText _speakerQText; + SceneObject _object1; + SceneObject _object2; + SceneObject _object3; + SceneObject _object4; + SceneObject _object5; + SceneObject _object6; + SceneObject _object7; + SceneObject _object8; + SceneObject _object9; + SceneObject _object10; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Action5 _action5; + Action6 _action6; + Action7 _action7; + SceneItem1 _sceneItem1; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void dispatch(); +}; + +class Scene7100: public Scene { + /* Actions */ + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + class Action5: public Action { + public: + virtual void signal(); + }; + class Action6: public Action { + public: + virtual void signal(); + }; + class Action7: public Action { + public: + virtual void signal(); + }; + class Action8: public Action { + public: + virtual void signal(); + }; + class Action9: public Action { + public: + virtual void signal(); + }; + class Action10: public Action { + public: + virtual void signal(); + }; + class Action11: public Action { + public: + virtual void signal(); + }; + +public: + SoundHandler _soundHandler1; + SoundHandler _soundHandler2; + SceneObject _object1; + SceneObject _object2; + SceneObject _object3; + SceneObject _object4; + SceneObject _object5; + SceneObject _object6; + SceneObject _object7; + SceneObject _object8; + SceneObject _object9; + SceneObject _object10; + SceneObject _object11; + SceneObject _object12; + SceneObject _object13; + SceneObject _object14; + SceneObject _object15; + SceneObject _object16; + SceneObject _object17; + SceneObject _object18; + SceneObject _object19; + SceneObject _object20; + SceneObject _object21; + SceneObject _object22; + SceneObject _object23; + SceneObject _object24; + SceneObject _object25; + Action _action1; + Action _action2; + Action3 _action3; + Action4 _action4; + Action5 _action5; + Action6 _action6; + Action7 _action7; + Action8 _action8; + Action9 _action9; + Action10 _action10; + Action11 _action11; + + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + +class Scene7200: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + +public: + Action1 _action1; + Action2 _action2; + SceneObject _swimmer; + SceneObject _object2; + SceneObject _object3; + SceneObject _object4; + SceneObject _object5; + SceneObject _object6; + SceneObject _object7; + SceneObject _object8; + SceneObject _object9; + SoundHandler _soundHandler; + + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + +class Scene7300: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + +public: + SpeakerPOR _speakerPOR; + SpeakerPOText _speakerPOText; + SpeakerSKText _speakerSKText; + SpeakerQU _speakerQU; + SceneObject _object1; + SceneObject _object2; + SceneObject _object3; + SceneObject _object4; + SceneObject _object5; + SceneObject _object6; + SceneObject _object7; + SceneObject _object8; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void dispatch(); +}; + +class Scene7600: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + +public: + Action1 _action1; + Action2 _action2; + SceneObject _object1; + SceneObject _object2; + SceneObject _object3; + SceneObject _object4; + SceneObject _object5; + SceneObject _object6; + SoundHandler _soundHandler1; + SoundHandler _soundHandler2; + + virtual void postInit(SceneObjectList *OwnerList = NULL); +}; + +class Scene7700: public Scene { + /* Actions */ + class Action1: public Action { + public: + virtual void signal(); + }; + class Action2: public Action { + public: + virtual void signal(); + }; + class Action3: public Action { + public: + virtual void signal(); + }; + class Action4: public Action { + public: + virtual void signal(); + }; + class Action5: public Action { + public: + virtual void signal(); + }; + class Action6: public Action { + public: + virtual void signal(); + }; + + class Object1: public SceneObject7700 { + public: + virtual void signal(); + virtual void doAction(int action); + }; + class Object3: public SceneObject { + public: + virtual void doAction(int action); + }; + class Object7: public SceneObjectExt { + public: + virtual void doAction(int action); + }; + class Object8: public SceneObject { + public: + virtual void doAction(int action); + }; + class Object9: public SceneObject { + public: + virtual void doAction(int action); + }; + class Object10: public SceneObject { + public: + virtual void doAction(int action); + }; + class Object11: public SceneObject { + public: + virtual void doAction(int action); + }; + class Object12: public SceneObject { + public: + virtual void doAction(int action); + }; + + /* Items */ + class SceneHotspot1: public SceneHotspot { + public: + virtual void doAction(int action); + }; + class SceneHotspot2: public SceneHotspot { + public: + virtual void doAction(int action); + }; + class SceneHotspot3: public SceneHotspot { + public: + virtual void doAction(int action); + }; + class SceneHotspot4: public SceneHotspot { + public: + virtual void doAction(int action); + }; + class SceneHotspot5: public SceneHotspot { + public: + virtual void doAction(int action); + }; + class SceneHotspot6: public SceneHotspot { + public: + virtual void doAction(int action); + }; + class SceneItem7: public SceneItem { + public: + virtual void doAction(int action); + }; + class SceneHotspot8: public SceneHotspot { + public: + virtual void doAction(int action); + }; + class SceneHotspot9: public SceneHotspot { + public: + virtual void doAction(int action); + }; + class SceneItem10: public SceneItem { + public: + virtual void doAction(int action); + }; + class SceneHotspot11: public NamedHotspotMult { + public: + virtual void doAction(int action); + }; +public: + SoundHandler _soundHandler; + SequenceManager _sequenceManager; + GfxButton _gfxButton; + SpeakerEText _speakerEText; + SpeakerQText _speakerQText; + Object1 _object1; + Object1 _object2; + Object3 _object3; + Object1 _object4; + Object1 _object5; + Object1 _object6; + Object7 _prof; + Object8 _object8; + Object9 _object9; + Object10 _object10; + Object11 _cork; + Object12 _emptyJar; + SceneObject _object13; + SceneObject _object14; + SceneObject _object15; + SceneObject _cloud; + SceneObject _easterEgg1; + SceneObject _easterEgg2; + SceneObject _object19; + Action1 _action1; + Action2 _action2; + Action3 _action3; + Action4 _action4; + Action5 _action5; + Action6 _action6; + SceneHotspot1 _sceneHotspot1; + SceneHotspot2 _sceneHotspot2; + SceneHotspot3 _sceneHotspot3; + SceneHotspot4 _sceneHotspot4; + SceneHotspot5 _sceneHotspot5; + SceneHotspot6 _sceneHotspot6; + SceneItem7 _sceneItem7; + SceneHotspot8 _sceneHotspot8; + SceneHotspot9 _sceneHotspot9; + SceneItem10 _sceneItem10; + SceneHotspot11 _sceneHotspot11; + SceneHotspot11 _sceneHotspot12; + SceneHotspot11 _sceneHotspot13; + SceneHotspot11 _sceneHotspot14; + SceneHotspot11 _sceneHotspot15; + SceneHotspot11 _sceneHotspot16; + SceneHotspot11 _sceneHotspot17; + SceneHotspot11 _sceneHotspot18; + SceneHotspot11 _sceneHotspot19; + SceneHotspot11 _sceneHotspot20; + SceneHotspot11 _sceneHotspot21; + SceneHotspot11 _sceneHotspot22; + SceneHotspot11 _sceneHotspot23; + SceneHotspot11 _sceneHotspot24; + SceneHotspot11 _sceneHotspot25; + SceneHotspot11 _sceneHotspot26; + SceneHotspot11 _sceneHotspot27; + SceneHotspot11 _sceneHotspot28; + SceneHotspot11 _sceneHotspot29; + SceneHotspot11 _sceneHotspot30; + SceneHotspot11 _sceneHotspot31; + SceneHotspot11 _sceneHotspot32; + SceneHotspot11 _sceneHotspot33; + SceneHotspot11 _sceneHotspot34; + SceneHotspot11 _sceneHotspot35; + SceneHotspot11 _sceneHotspot36; + int _field977, _field979, _field97B; + + Scene7700(); + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void signal(); + virtual void process(Event &event); + virtual void dispatch(); +}; + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp new file mode 100644 index 0000000000..a33f0a5381 --- /dev/null +++ b/engines/tsage/saveload.cpp @@ -0,0 +1,387 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/saveload.cpp $ + * $Id: saveload.cpp 209 2011-02-06 00:46:36Z dreammaster $ + * + */ + +#include "common/savefile.h" +#include "graphics/scaler.h" +#include "graphics/thumbnail.h" +#include "tsage/globals.h" +#include "tsage/saveload.h" +#include "tsage/tsage.h" + +namespace tSage { + +Saver *_saver; + +SavedObject::SavedObject() { + _saver->addObject(this); +} + +SavedObject::~SavedObject() { + _saver->removeObject(this); +} + +/*--------------------------------------------------------------------------*/ + +Saver::Saver() { + _macroSaveFlag = false; + _macroRestoreFlag = false; +} + +Saver::~Saver() { + // Internal validation that no saved object is still present + int totalLost = 0; + for (List<SavedObject *>::iterator i = _saver->_objList.begin(); i != _saver->_objList.end(); ++i) { + SavedObject *so = *i; + if (so) + ++totalLost; + } + + if (totalLost) + warning("Saved object not destroyed"); +} + +/*--------------------------------------------------------------------------*/ + +void Serialiser::syncPointer(SavedObject **ptr, Common::Serializer::Version minVersion, + Common::Serializer::Version maxVersion) { + int idx; + assert(ptr); + + if (isSaving()) { + // Get the object index for the given pointer and write it out + if (!*ptr) { + idx = 0; + } else { + idx = _saver->blockIndexOf(*ptr); + assert(idx > 0); + } + syncAsUint32LE(idx); + } else { + // Load in the object index and add it into the unresolved pointer list + syncAsUint32LE(idx); + *ptr = NULL; + if (idx > 0) + // For non-zero (null) pointers, create a record for later resolving it to an address + _saver->addSavedObjectPtr(ptr, idx); + } +} + +void Serialiser::validate(const Common::String &s, Common::Serializer::Version minVersion, + Common::Serializer::Version maxVersion) { + Common::String tempStr = s; + syncString(tempStr, minVersion, maxVersion); + + if (isLoading() && (tempStr != s)) + error("Savegame is corrupt"); +} + +void Serialiser::validate(int v, Common::Serializer::Version minVersion, + Common::Serializer::Version maxVersion) { + int tempVal = v; + syncAsUint32LE(tempVal, minVersion, maxVersion); + if (isLoading() && (tempVal != v)) + error("Savegame is corrupt"); +} + +/*--------------------------------------------------------------------------*/ + +Common::Error Saver::save(int slot, const Common::String &saveName) { + assert(!getMacroRestoreFlag()); + + // Signal any objects registered for notification + _saveNotifiers.notify(false); + + // Set fields + _macroSaveFlag = true; + _saveSlot = slot; + + // Set up the serialiser + Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(_vm->generateSaveName(slot)); + Serialiser serialiser(NULL, saveFile); + + // Write out the savegame header + tSageSavegameHeader header; + header.saveName = saveName; + header.version = TSAGE_SAVEGAME_VERSION; + writeSavegameHeader(saveFile, header); + + // Save out objects that need to come at the start of the savegame + for (List<SaveListener *>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) { + (*i)->listenerSynchronise(serialiser); + } + + // Save each registered SaveObject descendant object into the savegame file + for (List<SavedObject *>::iterator i = _objList.begin(); i != _objList.end(); ++i) { + serialiser.validate((*i)->getClassName()); + (*i)->synchronise(serialiser); + } + + // Save file complete + saveFile->writeString("END"); + saveFile->finalize(); + delete saveFile; + + // Final post-save notification + _macroSaveFlag = false; + _saveNotifiers.notify(true); + + return Common::kNoError; +} + +Common::Error Saver::restore(int slot) { + assert(!getMacroSaveFlag()); + + // Signal any objects registered for notification + _loadNotifiers.notify(false); + + // Set fields + _macroSaveFlag = true; + _saveSlot = slot; + _unresolvedPtrs.clear(); + + // Set up the serialiser + Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(_vm->generateSaveName(slot)); + Serialiser serialiser(saveFile, NULL); + + // Read in the savegame header + tSageSavegameHeader header; + readSavegameHeader(saveFile, header); + delete header.thumbnail; + + // Load in data for objects that need to come at the start of the savegame + for (List<SaveListener *>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) { + (*i)->listenerSynchronise(serialiser); + } + + // Loop through each registered object to load in the data + for (List<SavedObject *>::iterator i = _objList.begin(); i != _objList.end(); ++i) { + serialiser.validate((*i)->getClassName()); + (*i)->synchronise(serialiser); + } + + // Loop through the remaining data of the file, instantiating new objects. + // Note: I don't store pointers to instantiated objects here, because it's not necessary - the mere act + // of instantiating a saved object registers it with the saver, and will then be resolved to whatever + // object originally had a pointer to it as part of the post-processing step + Common::String className; + serialiser.syncString(className); + while (className != "END") { + SavedObject *savedObject; + if (!_factoryPtr || ((savedObject = _factoryPtr(className)) == NULL)) + error("Unknown class name '%s' encountered trying to restore savegame", className.c_str()); + + // Populate the contents of the object + savedObject->synchronise(serialiser); + + // Move to next object + serialiser.syncString(className); + } + + // Post-process any unresolved pointers to get the correct pointer + resolveLoadPointers(); + + delete saveFile; + + // Final post-restore notifications + _macroRestoreFlag = false; + _loadNotifiers.notify(false); + + return Common::kNoError; +} + +const char *SAVEGAME_STR = "SCUMMVM_TSAGE"; +#define SAVEGAME_STR_SIZE 13 + +bool Saver::readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header) { + char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; + header.thumbnail = NULL; + + // Validate the header Id + in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1); + if (strncmp(saveIdentBuffer, SAVEGAME_STR, SAVEGAME_STR_SIZE)) + return false; + + header.version = in->readByte(); + if (header.version != TSAGE_SAVEGAME_VERSION) + return false; + + // Read in the string + header.saveName.clear(); + char ch; + while ((ch = (char)in->readByte()) != '\0') header.saveName += ch; + + // Get the thumbnail + header.thumbnail = new Graphics::Surface(); + if (!Graphics::loadThumbnail(*in, *header.thumbnail)) { + delete header.thumbnail; + header.thumbnail = NULL; + return false; + } + + // Read in save date/time + header.saveYear = in->readSint16LE(); + header.saveMonth = in->readSint16LE(); + header.saveDay = in->readSint16LE(); + header.saveHour = in->readSint16LE(); + header.saveMinutes = in->readSint16LE(); + header.totalFrames = in->readUint32LE(); + + return true; +} + +void Saver::writeSavegameHeader(Common::OutSaveFile *out, tSageSavegameHeader &header) { + // Write out a savegame header + out->write(SAVEGAME_STR, SAVEGAME_STR_SIZE + 1); + + out->writeByte(TSAGE_SAVEGAME_VERSION); + + // Write savegame name + out->write(header.saveName.c_str(), header.saveName.size() + 1); + + // Get the active palette + uint32 workPal[256]; + uint8 thumbPalette[256 * 3]; + const byte *srcP = (const byte *)&workPal[0]; + byte *destP = &thumbPalette[0]; + g_system->getPaletteManager()->grabPalette((byte *)workPal, 0, 256); + for (int idx = 0; idx < 256; ++idx, ++srcP) { + *destP++ = *srcP++; + *destP++ = *srcP++; + *destP++ = *srcP++; + } + + // Create a thumbnail and save it + Graphics::Surface *thumb = new Graphics::Surface(); + Graphics::Surface s = _globals->_screenSurface.lockSurface(); + ::createThumbnail(thumb, (const byte *)s.pixels, SCREEN_WIDTH, SCREEN_HEIGHT, thumbPalette); + Graphics::saveThumbnail(*out, *thumb); + _globals->_screenSurface.unlockSurface(); + delete thumb; + + // Write out the save date/time + TimeDate td; + g_system->getTimeAndDate(td); + out->writeSint16LE(td.tm_year + 1900); + out->writeSint16LE(td.tm_mon + 1); + out->writeSint16LE(td.tm_mday); + out->writeSint16LE(td.tm_hour); + out->writeSint16LE(td.tm_min); + out->writeUint32LE(_globals->_events.getFrameNumber()); +} + +/** + * Adds a serialisable object that should be saved/restored before any other objects + */ +void Saver::addListener(SaveListener *obj) { + _listeners.push_back(obj); +} + +/** + * Adds a listener to be notified before the saving starts + */ +void Saver::addSaveNotifier(SaveNotifierFn fn) { + _saveNotifiers.push_back(fn); +} + +/** + * Adds a listener to be notified before the saving starts + */ +void Saver::addLoadNotifier(SaveNotifierFn fn) { + _loadNotifiers.push_back(fn); +} + +/** + * Registers a SavedObject descendant object for being saved in savegame files + */ +void Saver::addObject(SavedObject *obj) { + _objList.push_back(obj); +} + +/** + * Removes a SavedObject descendant object from the save object list + */ +void Saver::removeObject(SavedObject *obj) { + _objList.remove(obj); +} + +/** + * Returns true if any savegames exist + */ +bool Saver::savegamesExist() const { + Common::String slot1Name = _vm->generateSaveName(1); + + Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(slot1Name); + bool result = saveFile != NULL; + delete saveFile; + return result; +} + +/** + * Returns the index of the saved block associated with the given saved object pointer + */ +int Saver::blockIndexOf(SavedObject *p) { + int objIndex = 1; + List<SavedObject *>::iterator iObj; + + for (iObj = _objList.begin(); iObj != _objList.end(); ++iObj, ++objIndex) { + SavedObject *iObjP = *iObj; + if (iObjP == p) + return objIndex; + } + + return 0; +} + +/** + * Returns the pointer associated with the specified object index + */ +void Saver::resolveLoadPointers() { + if (_unresolvedPtrs.size() == 0) + // Nothing to resolve + return; + + // Outer loop through the main object list + int objIndex = 1; + for (List<SavedObject *>::iterator iObj = _objList.begin(); iObj != _objList.end(); ++iObj, ++objIndex) { + Common::List<SavedObjectRef>::iterator iPtr; + + for (iPtr = _unresolvedPtrs.begin(); iPtr != _unresolvedPtrs.end(); ) { + SavedObjectRef &r = *iPtr; + if (r._objIndex == objIndex) { + // Found an unresolved pointer to this object + *r._savedObject = *iObj; + iPtr = _unresolvedPtrs.erase(iPtr); + } else { + ++iPtr; + } + } + } + + // At this point, all the unresolved pointers should have been resolved and removed + if (_unresolvedPtrs.size() > 0) + error("Could not resolve savegame block pointers"); +} + +} // End of namespace tSage diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h new file mode 100644 index 0000000000..12552f8104 --- /dev/null +++ b/engines/tsage/saveload.h @@ -0,0 +1,225 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/saveload.h $ + * $Id: saveload.h 209 2011-02-06 00:46:36Z dreammaster $ + * + */ + +#ifndef TSAGE_SAVELOAD_H +#define TSAGE_SAVELOAD_H + +#include "common/scummsys.h" +#include "common/list.h" +#include "common/memstream.h" +#include "common/savefile.h" +#include "common/serializer.h" + +namespace tSage { + +typedef void (*SaveNotifierFn)(bool postFlag); + +#define TSAGE_SAVEGAME_VERSION 1 + +class SavedObject; + +struct tSageSavegameHeader { + uint8 version; + Common::String saveName; + Graphics::Surface *thumbnail; + int saveYear, saveMonth, saveDay; + int saveHour, saveMinutes; + int totalFrames; +}; + +/*--------------------------------------------------------------------------*/ + +#define SYNC_POINTER(x) s.syncPointer((SavedObject **)&x) +#define SYNC_ENUM(FIELD, TYPE) int v_##FIELD = (int)FIELD; s.syncAsUint16LE(v_##FIELD); \ + if (s.isLoading()) FIELD = (TYPE)v_##FIELD; + +/** + * Derived serialiser class with extra synchronisation types + */ +class Serialiser: public Common::Serializer { +public: + Serialiser(Common::SeekableReadStream *in, Common::WriteStream *out): Common::Serializer(in, out) {} + + void syncPointer(SavedObject **ptr, Common::Serializer::Version minVersion = 0, + Common::Serializer::Version maxVersion = kLastVersion); + void validate(const Common::String &s, Common::Serializer::Version minVersion = 0, + Common::Serializer::Version maxVersion = kLastVersion); + void validate(int v, Common::Serializer::Version minVersion = 0, + Common::Serializer::Version maxVersion = kLastVersion); +}; + +/*--------------------------------------------------------------------------*/ + +class Serialisable { +public: + virtual ~Serialisable() {} + virtual void synchronise(Serialiser &s) = 0; +}; + +class SaveListener { +public: + virtual ~SaveListener() {} + virtual void listenerSynchronise(Serialiser &s) = 0; +}; + +/*--------------------------------------------------------------------------*/ + +class SavedObject: public Serialisable { +public: + SavedObject(); + virtual ~SavedObject(); + + virtual Common::String getClassName() { return "SavedObject"; } + virtual void synchronise(Serialiser &s) {} + + static SavedObject *createInstance(const Common::String &className); +}; + +/*--------------------------------------------------------------------------*/ + +/** + * Derived list class with extra functionality + */ +template<typename T> +class List: public Common::List<T> { +public: + bool contains(T v) { + for (typename List<T>::iterator i = this->begin(); i != this->end(); ++i) + if (*i == v) + return true; + return false; + } + + typedef void (*ForEachFn)(T fn); + void forEach(ForEachFn Fn) { + for (typename List<T>::iterator i = this->begin(); i != this->end(); ++i) + Fn(*i); + } + + void clear2() { + for (typename List<T>::iterator i = this->begin(); i != this->end(); ++i) + delete *i; + Common::List<T>::clear(); + } + + void synchronise(Serialiser &s) { + int entryCount; + + if (s.isLoading()) { + List<T>::clear(); + s.syncAsUint32LE(entryCount); + + for (int idx = 0; idx < entryCount; ++idx) { + List<T>::push_back(static_cast<T>((T)NULL)); + T &obj = List<T>::back(); + s.syncPointer((SavedObject **)&obj); + } + } else { + // Get the list size + entryCount = 0; + typename List<T>::iterator i; + for (i = List<T>::begin(); i != List<T>::end(); ++i, ++entryCount) + ; + + // Write out list + s.syncAsUint32LE(entryCount); + for (i = List<T>::begin(); i != List<T>::end(); ++i) { + s.syncPointer((SavedObject **)&*i); + } + } + } +}; + +/** + * Derived list class for holding function pointers + */ +template<typename T> +class FunctionList: public List<void (*)(T)> { +public: + void notify(T v) { + for (typename List<void (*)(T)>::iterator i = this->begin(); i != this->end(); ++i) { + (*i)(v); + } + } +}; + +/*--------------------------------------------------------------------------*/ + +class SavedObjectRef { +public: + SavedObject **_savedObject; + int _objIndex; + + SavedObjectRef(): _savedObject(NULL), _objIndex(-1) {} + SavedObjectRef(SavedObject **so, int objIndex): _savedObject(so), _objIndex(objIndex) {} +}; + +typedef SavedObject *(*SavedObjectFactory)(const Common::String &className); + +class Saver { +private: + List<SavedObject *> _objList; + FunctionList<bool> _saveNotifiers; + FunctionList<bool> _loadNotifiers; + List<SaveListener *> _listeners; + + Common::List<SavedObjectRef> _unresolvedPtrs; + SavedObjectFactory _factoryPtr; + + bool _macroSaveFlag; + bool _macroRestoreFlag; + int _saveSlot; + + void resolveLoadPointers(); +public: + Saver(); + ~Saver(); + + Common::Error save(int slot, const Common::String &saveName); + Common::Error restore(int slot); + static bool readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header); + static void writeSavegameHeader(Common::OutSaveFile *out, tSageSavegameHeader &header); + + void addListener(SaveListener *obj); + void addSaveNotifier(SaveNotifierFn fn); + void addLoadNotifier(SaveNotifierFn fn); + void addObject(SavedObject *obj); + void removeObject(SavedObject *obj); + void addFactory(SavedObjectFactory fn) { _factoryPtr = fn; } + void addSavedObjectPtr(SavedObject **ptr, int objIndex) { + _unresolvedPtrs.push_back(SavedObjectRef(ptr, objIndex)); + } + + bool savegamesExist() const; + bool getMacroSaveFlag() const { return _macroSaveFlag; } + bool getMacroRestoreFlag() const { return _macroRestoreFlag; } + int blockIndexOf(SavedObject *p); +}; + +extern Saver *_saver; + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp new file mode 100644 index 0000000000..5a351f3772 --- /dev/null +++ b/engines/tsage/scenes.cpp @@ -0,0 +1,471 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/scenes.cpp $ + * $Id: scenes.cpp 229 2011-02-12 06:50:14Z dreammaster $ + * + */ + +#include "tsage/scenes.h" +#include "tsage/globals.h" +#include "tsage/ringworld_logic.h" +#include "tsage/tsage.h" + +namespace tSage { + +SceneManager::SceneManager() { + _scene = NULL; + _hasPalette = false; + _sceneNumber = -1; + _nextSceneNumber = -1; + _previousScene = 0; + _fadeMode = FADEMODE_GRADUAL; + _scrollerRect = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + _saver->addListener(this); +} + +SceneManager::~SceneManager() { + delete _scene; +} + +void SceneManager::setNewScene(int sceneNumber) { + _nextSceneNumber = sceneNumber; +} + +void SceneManager::checkScene() { + if (_nextSceneNumber != -1) { + sceneChange(); + _nextSceneNumber = -1; + } + + _globals->_sceneListeners.forEach(SceneHandler::dispatchObject); +} + +void SceneManager::sceneChange() { + // Handle removing the scene + if (_scene) + _scene->remove(); + + // Clear the scene objects + List<SceneObject *>::iterator io = _globals->_sceneObjects->begin(); + while (io != _globals->_sceneObjects->end()) { + SceneObject *sceneObj = *io; + ++io; + sceneObj->removeObject(); + } + + // Clear the secondary scene object list + io = _globals->_sceneManager._altSceneObjects.begin(); + while (io != _globals->_sceneManager._altSceneObjects.end()) { + SceneObject *sceneObj = *io; + ++io; + sceneObj->removeObject(); + } + + // Clear the hotspot list + List<SceneItem *>::iterator ii = _globals->_sceneItems.begin(); + while (ii != _globals->_sceneItems.end()) { + SceneItem *sceneItem = *ii; + ++ii; + sceneItem->remove(); + } + + // TODO: Clear _list_45BAA list + + // If there is an active scene, deactivate it + if (_scene) { + _previousScene = _sceneNumber; + + delete _scene; + _scene = NULL; + _sceneNumber = -1; + } + + // Set the next scene to be active + _sceneNumber = _nextSceneNumber; + + // TODO: Unknown check of word_45CD3 / call to saver method + + // Free any regions + disposeRegions(); + + // Instantiate and set the new scene + _scene = getNewScene(); + _scene->postInit(); +} + +Scene *SceneManager::getNewScene() { + return SceneFactory::createScene(_nextSceneNumber); +} + +void SceneManager::fadeInIfNecessary() { + if (_hasPalette) { + uint32 adjustData = 0; + for (int percent = 0; percent < 100; percent += 5) { + if (_globals->_sceneManager._fadeMode == FADEMODE_IMMEDIATE) + percent = 100; + + _globals->_scenePalette.fade((const byte *)&adjustData, false, percent); + g_system->updateScreen(); + g_system->delayMillis(10); + } + + _globals->_scenePalette.refresh(); + _hasPalette = false; + } +} + +void SceneManager::changeScene(int newSceneNumber) { + // Fade out the scene + ScenePalette scenePalette; + uint32 adjustData = 0; + _globals->_scenePalette.clearListeners(); + scenePalette.getPalette(); + + for (int percent = 100; percent >= 0; percent -= 5) { + scenePalette.fade((byte *)&adjustData, false, percent); + g_system->delayMillis(10); + } + + // Stop any objects that were animating + List<SceneObject *>::iterator i; + for (i = _globals->_sceneObjects->begin(); i != _globals->_sceneObjects->end(); ++i) { + SceneObject *sceneObj = *i; + Common::Point pt(0, 0); + sceneObj->addMover(NULL, &pt); + sceneObj->setObjectWrapper(NULL); + sceneObj->animate(ANIM_MODE_NONE, 0); + + sceneObj->_flags &= !OBJFLAG_PANES; + } + + // Blank out the screen + _globals->_screenSurface.fillRect(_globals->_screenSurface.getBounds(), 0); + + // Set the new scene to be loaded + setNewScene(newSceneNumber); +} + +void SceneManager::setup() { + _saver->addLoadNotifier(SceneManager::loadNotifier); + setBackSurface(); +} + +void SceneManager::setBackSurface() { + int size = _globals->_sceneManager._scene->_backgroundBounds.width() * + _globals->_sceneManager._scene->_backgroundBounds.height(); + + if (size > 96000) { + if (_globals->_sceneManager._scene->_backgroundBounds.width() <= SCREEN_WIDTH) { + // Standard size creation + _globals->_sceneManager._scene->_backSurface.create(SCREEN_WIDTH, SCREEN_HEIGHT * 3 / 2); + _globals->_sceneManager._scrollerRect = Rect(0, 30, SCREEN_WIDTH, SCREEN_HEIGHT - 30); + } else { + // Wide screen needs extra space to allow for scrolling + _globals->_sceneManager._scene->_backSurface.create(SCREEN_WIDTH * 3 / 2, SCREEN_HEIGHT); + _globals->_sceneManager._scrollerRect = Rect(80, 0, SCREEN_WIDTH - 80, SCREEN_HEIGHT); + } + } else { + _globals->_sceneManager._scene->_backSurface.create( + _globals->_sceneManager._scene->_backgroundBounds.width(), + _globals->_sceneManager._scene->_backgroundBounds.height() + ); + _globals->_sceneManager._scrollerRect = Rect(80, 20, SCREEN_WIDTH - 80, SCREEN_HEIGHT - 20); + } +} + +void SceneManager::saveListener(int saveMode) { + warning("TODO: SceneManager::saveLIstener"); +} + +void SceneManager::loadNotifier(bool postFlag) { + if (postFlag) { + if (_globals->_sceneManager._scene->_activeScreenNumber != -1) + _globals->_sceneManager._scene->loadSceneData(_globals->_sceneManager._scene->_activeScreenNumber); + _globals->_sceneManager._hasPalette = true; + } +} + +void SceneManager::setBgOffset(const Common::Point &pt, int loadCount) { + _sceneBgOffset = pt; + _sceneLoadCount = loadCount; +} + +void SceneManager::listenerSynchronise(Serialiser &s) { + s.validate("SceneManager"); + _altSceneObjects.synchronise(s); + + s.syncAsSint32LE(_sceneNumber); + if (s.isLoading()) { + changeScene(_sceneNumber); + checkScene(); + } + + s.syncAsUint16LE(_globals->_sceneManager._scene->_activeScreenNumber); + _globals->_sceneManager._scrollerRect.synchronise(s); + SYNC_POINTER(_globals->_scrollFollower); + s.syncAsSint16LE(_loadMode); +} + +/*--------------------------------------------------------------------------*/ + +Scene::Scene(): _sceneBounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), + _backgroundBounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) { + _sceneMode = 0; + _oldSceneBounds = Rect(4000, 4000, 4100, 4100); +} + +Scene::~Scene() { +} + +void Scene::synchronise(Serialiser &s) { + s.syncAsSint32LE(_field12); + s.syncAsSint32LE(_sceneNumber); + s.syncAsSint32LE(_activeScreenNumber); + s.syncAsSint32LE(_sceneMode); + _backgroundBounds.synchronise(s); + _sceneBounds.synchronise(s); + _oldSceneBounds.synchronise(s); + s.syncAsSint16LE(_fieldA); + s.syncAsSint16LE(_fieldE); + + for (int i = 0; i < 256; ++i) + s.syncAsUint16LE(_enabledSections[i]); + for (int i = 0; i < 256; ++i) + s.syncAsSint16LE(_zoomPercents[i]); +} + +void Scene::postInit(SceneObjectList *OwnerList) { + _action = NULL; + _field12 = 0; + _sceneMode = 0; +} + +void Scene::process(Event &event) { + if (_action) + _action->process(event); +} + +void Scene::dispatch() { + if (_action) + _action->dispatch(); +} + +void Scene::loadScene(int sceneNum) { + _sceneNumber = sceneNum; + if (_globals->_scenePalette.loadPalette(sceneNum)) + _globals->_sceneManager._hasPalette = true; + + loadSceneData(sceneNum); +} + +void Scene::loadSceneData(int sceneNum) { + _globals->_sceneManager._scene->_activeScreenNumber = sceneNum; + + // Get the basic scene size + byte *data = _vm->_dataManager->getResource(RES_BITMAP, sceneNum, 9999); + _backgroundBounds = Rect(0, 0, READ_LE_UINT16(data), READ_LE_UINT16(data + 2)); + _globals->_sceneManager._scene->_sceneBounds.contain(_backgroundBounds); + DEALLOCATE(data); + + // Set up a surface for storing the scene background + SceneManager::setBackSurface(); + + // Load the data lists for the scene + _globals->_walkRegions.load(sceneNum); + + // Load the item regions of the scene + _globals->_sceneRegions.load(sceneNum); + + // Load the priority regions + _priorities.load(sceneNum); + + // Initialise the section enabled list + Common::set_to(&_enabledSections[0], &_enabledSections[16 * 16], 0xffff); + + _globals->_sceneOffset.x = (_sceneBounds.left / 160) * 160; + _globals->_sceneOffset.y = (_sceneBounds.top / 100) * 100; + _globals->_paneRefreshFlag[0] = 1; + _globals->_paneRefreshFlag[1] = 1; + _globals->_sceneManager._loadMode = 1; + _globals->_sceneManager._sceneLoadCount = 0; + _globals->_sceneManager._sceneBgOffset = Common::Point(0, 0); + + // Load the background for the scene + loadBackground(0, 0); +} + +void Scene::loadBackground(int xAmount, int yAmount) { + // Adjust the scene bounds by the passed scroll amounts + _sceneBounds.translate(xAmount, yAmount); + _sceneBounds.contain(_backgroundBounds); + _sceneBounds.left &= ~3; + _sceneBounds.right &= ~3; + _globals->_sceneOffset.x &= ~3; + + if ((_sceneBounds.top != _oldSceneBounds.top) || (_sceneBounds.left != _oldSceneBounds.left)) { + if (_globals->_sceneManager._loadMode == 0) { + _globals->_paneRefreshFlag[0] = 2; + _globals->_paneRefreshFlag[1] = 2; + _globals->_sceneManager._loadMode = 2; + } + _oldSceneBounds = _sceneBounds; + } + + _globals->_sceneOffset.x = (_sceneBounds.left / 160) * 160; + _globals->_sceneOffset.y = (_sceneBounds.top / 100) * 100; + + if ((_backgroundBounds.width() / 160) == 3) + _globals->_sceneOffset.x = 0; + if ((_backgroundBounds.height() / 100) == 3) + _globals->_sceneOffset.y = 0; + + if ((_globals->_sceneOffset.x != _globals->_prevSceneOffset.x) || + (_globals->_sceneOffset.y != _globals->_prevSceneOffset.y)) { + // Change has happend, so refresh background + _globals->_prevSceneOffset = _globals->_sceneOffset; + refreshBackground(xAmount, yAmount); + } +} + +void Scene::refreshBackground(int xAmount, int yAmount) { + if (_globals->_sceneManager._scene->_activeScreenNumber == -1) + return; + + // Set the quadrant ranges + int xHalfCount = MIN(_backSurface.getBounds().width() / 160, _backgroundBounds.width() / 160); + int yHalfCount = MIN(_backSurface.getBounds().height() / 100, _backgroundBounds.height() / 100); + int xHalfOffset = (_backgroundBounds.width() / 160) == 3 ? 0 : _sceneBounds.left / 160; + int yHalfOffset = (_backgroundBounds.height() / 100) == 3 ? 0 : _sceneBounds.top / 100; + + // Set the limits and increment amounts + int xInc = (xAmount < 0) ? -1 : 1; + int xSectionStart = (xAmount < 0) ? 15 : 0; + int xSectionEnd = (xAmount < 0) ? -1 : 16; + int yInc = (yAmount < 0) ? -1 : 1; + int ySectionStart = (yAmount < 0) ? 15 : 0; + int ySectionEnd = (yAmount < 0) ? -1 : 16; + bool changedFlag = false; + + for (int yp = ySectionStart; yp != ySectionEnd; yp += yInc) { + for (int xp = xSectionStart; xp != xSectionEnd; xp += xInc) { + if ((yp < yHalfOffset) || (yp >= (yHalfOffset + yHalfCount)) || + (xp < xHalfOffset) || (xp >= (xHalfOffset + xHalfCount))) { + // Flag section as enabled + _enabledSections[xp * 16 + yp] = 0xffff; + } else { + // Check if the section is already loaded + if ((_enabledSections[xp * 16 + yp] == 0xffff) || ((xAmount == 0) && (yAmount == 0))) { + // Chunk isn't loaded, so load it in + Graphics::Surface s = _backSurface.lockSurface(); + GfxSurface::loadScreenSection(s, xp - xHalfOffset, yp - yHalfOffset, xp, yp); + _backSurface.unlockSurface(); + changedFlag = true; + } else { + int yv = (_enabledSections[xp * 16 + yp] == ((xp - xHalfOffset) << 4)) ? 0 : 1; + if (yv | (yp - yHalfOffset)) { + // Copy an existing 160x100 screen section previously loaded + int xSectionDest = xp - xHalfOffset; + int ySectionDest = yp - yHalfOffset; + int xSectionSrc = _enabledSections[xp * 16 + yp] >> 4; + int ySectionSrc = _enabledSections[xp * 16 + yp] & 0xf; + + Rect srcBounds(xSectionSrc * 160, ySectionSrc * 100, + (xSectionSrc + 1) * 160, (ySectionSrc + 1) * 100); + Rect destBounds(xSectionDest * 160, ySectionDest * 100, + (xSectionDest + 1) * 160, (ySectionDest + 1) * 100); + + _backSurface.copyFrom(_backSurface, srcBounds, destBounds); + } + } + + _enabledSections[xp * 16 + yp] = + ((xp - xHalfOffset) << 4) | (yp - yHalfOffset); + } + } + } + + if (changedFlag) { + drawAltObjects(); + } +} + +void Scene::drawAltObjects() { + Common::Array<SceneObject *> objList; + + // Initial loop to set the priority for entries in the list + for (List<SceneObject *>::iterator i = _globals->_sceneManager._altSceneObjects.begin(); + i != _globals->_sceneManager._altSceneObjects.end(); ++i) { + SceneObject *obj = *i; + objList.push_back(obj); + + // Handle updating object priority + if (!(obj->_flags & OBJFLAG_FIXED_PRIORITY)) { + obj->_priority = MIN((int)obj->_position.y - 1, + (int)_globals->_sceneManager._scene->_backgroundBounds.bottom); + } + } + + // Sort the list by priority + _globals->_sceneManager._altSceneObjects.sortList(objList); + + // Drawing loop + for (uint objIndex = 0; objIndex < objList.size(); ++objIndex) { + SceneObject *obj = objList[objIndex]; + + obj->reposition(); + obj->draw(); + } +} + +void Scene::setZoomPercents(int yStart, int minPercent, int yEnd, int maxPercent) { + int var_6 = 0; + int v = 0; + while (v < yStart) + _zoomPercents[v++] = minPercent; + + int diff1 = ABS(maxPercent - minPercent); + int diff2 = ABS(yEnd - yStart); + int var_8 = MAX(diff1, diff2); + + while (var_8-- != 0) { + _zoomPercents[v] = minPercent; + if (diff2 <= diff1) { + ++minPercent; + var_6 += diff2; + if (var_6 >= diff1) { + var_6 -= diff1; + ++v; + } + } else { + ++v; + var_6 += diff1; + if (var_6 >= diff2) { + var_6 -= diff2; + ++minPercent; + } + } + } + + while (yEnd < 256) + _zoomPercents[yEnd++] = minPercent; +} + +} // End of namespace tSage diff --git a/engines/tsage/scenes.h b/engines/tsage/scenes.h new file mode 100644 index 0000000000..9d969c906b --- /dev/null +++ b/engines/tsage/scenes.h @@ -0,0 +1,115 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/scenes.h $ + * $Id: scenes.h 216 2011-02-08 08:10:46Z dreammaster $ + * + */ + +#ifndef TSAGE_SCENES_H +#define TSAGE_SCENES_H + +#include "common/scummsys.h" +#include "tsage/converse.h" +#include "tsage/events.h" +#include "tsage/core.h" +#include "tsage/saveload.h" + +namespace tSage { + +class Scene: public StripCallback { +private: + void drawAltObjects(); +public: + int _field12; + int _sceneNumber; + int _activeScreenNumber; + int _sceneMode; + StripManager _stripManager; + + Rect _backgroundBounds; + GfxSurface _backSurface; + Rect _sceneBounds; + Rect _oldSceneBounds; + int _enabledSections[256]; + int _zoomPercents[256]; + ScenePriorities _priorities; + + int _fieldA; + int _fieldE; +public: + Scene(); + virtual ~Scene(); + + virtual Common::String getClassName() { return "Scene"; } + virtual void synchronise(Serialiser &s); + virtual void stripCallback(int v) {} + virtual void postInit(SceneObjectList *OwnerList = NULL); + virtual void process(Event &event); + virtual void dispatch(); + virtual void loadScene(int sceneNum); + + void setZoomPercents(int yStart, int minPercent, int yEnd, int maxPercent); + void loadBackground(int xAmount, int yAmount); + void refreshBackground(int xAmount, int yAmount); + void loadSceneData(int sceneNum); +}; + +class SceneManager: public GameHandler, public SaveListener { +private: + void disposeRegions() { warning("TODO"); } + Scene *getNewScene(); +public: + Scene *_scene; + bool _hasPalette; + int _loadMode; + int _sceneNumber; + int _previousScene; + int _nextSceneNumber; + FadeMode _fadeMode; + Common::Point _sceneBgOffset; + int _sceneLoadCount; + Rect _scrollerRect; + SceneObjectList _altSceneObjects; +public: + SceneManager(); + virtual ~SceneManager(); + + virtual void listenerSynchronise(Serialiser &s); + void setNewScene(int sceneNumber); + void checkScene(); + void sceneChange(); + void fadeInIfNecessary(); + void changeScene(int newSceneNumber); + void setBgOffset(const Common::Point &pt, int loadCount); + + void removeAction(Action *action) { + // Not currently implemented because addAction method doesn't seem to have any callers + } + + static void setup(); + static void setBackSurface(); + static void saveListener(int saveMode); + static void loadNotifier(bool postFlag); +}; + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp new file mode 100644 index 0000000000..e4182cdbb6 --- /dev/null +++ b/engines/tsage/sound.cpp @@ -0,0 +1,62 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/sound.cpp $ + * $Id: sound.cpp 204 2011-02-05 12:23:20Z dreammaster $ + * + */ + +#include "common/config-manager.h" +#include "common/endian.h" +#include "tsage/core.h" +#include "tsage/globals.h" +#include "tsage/debugger.h" +#include "tsage/graphics.h" + +namespace tSage { + +void SoundManager::postInit() { + _saver->addSaveNotifier(&SoundManager::saveNotifier); + _saver->addLoadNotifier(&SoundManager::loadNotifier); + _saver->addListener(this); +} + +void SoundManager::saveNotifier(bool postFlag) { + _globals->_soundManager.saveNotifierProc(postFlag); +} + +void SoundManager::saveNotifierProc(bool postFlag) { + warning("TODO: SoundManager::saveNotifierProc"); +} + +void SoundManager::loadNotifier(bool postFlag) { + _globals->_soundManager.loadNotifierProc(postFlag); +} + +void SoundManager::loadNotifierProc(bool postFlag) { + warning("TODO: SoundManager::loadNotifierProc"); +} + +void SoundManager::listenerSynchronise(Serialiser &s) { + s.validate("SoundManager"); + warning("TODO: SoundManager listenerSynchronise"); +} + +} // End of namespace tSage diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h new file mode 100644 index 0000000000..c25cebd1c2 --- /dev/null +++ b/engines/tsage/sound.h @@ -0,0 +1,49 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/sound.h $ + * $Id: sound.h 184 2011-02-03 11:31:38Z dreammaster $ + * + */ + +#ifndef TSAGE_SOUND_H +#define TSAGE_SOUND_H + +#include "common/scummsys.h" +#include "tsage/saveload.h" + +namespace tSage { + +class SoundManager: public SaveListener { +public: + void dispatch() {} + virtual void listenerSynchronise(Serialiser &s); + virtual void postInit(); + + void proc2() {} + static void saveNotifier(bool postFlag); + void saveNotifierProc(bool postFlag); + static void loadNotifier(bool postFlag); + void loadNotifierProc(bool postFlag); +}; + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/staticres.cpp b/engines/tsage/staticres.cpp new file mode 100644 index 0000000000..59fca196b1 --- /dev/null +++ b/engines/tsage/staticres.cpp @@ -0,0 +1,117 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/staticres.cpp $ + * $Id: staticres.cpp 219 2011-02-08 12:05:46Z dreammaster $ + * + */ + +#include "tsage/staticres.h" + +namespace tSage { + +const byte CURSOR_ARROW_DATA[] = { + 15, 0, 15, 0, 0, 0, 0, 0, 9, 0, + 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x00, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x00, 0xFF, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09 +}; + +const byte CURSOR_WALK_DATA[] = { + 15, 0, 15, 0, 7, 0, 7, 0, 9, 0, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x09, 0x09, 0x09, 0x09, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0xFF, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 +}; + +const char *LOOK_SCENE_HOTSPOT = "You see nothing special."; +const char *USE_SCENE_HOTSPOT = "That accomplishes nothing."; +const char *TALK_SCENE_HOTSPOT = "Yak, yak."; +const char *SPECIAL_SCENE_HOTSPOT = "That is a unique use for that."; +const char *DEFAULT_SCENE_HOTSPOT = "That accomplishes nothing."; +const char *SAVE_ERROR_MSG = "Error occurred saving game. Please do not try to restore this game!"; +const char *SAVING_NOT_ALLOWED_MSG = "Saving is not allowed at this time."; +const char *RESTORING_NOT_ALLOWED_MSG = "Restoring is not allowed at this time."; +const char *RESTART_CONFIRM_MSG = "Do you want to restart your game?"; +const char *WATCH_INTRO_MSG = "Do you wish to watch the introduction?"; +const char *INV_EMPTY_MSG = "You have nothing in your possesion."; + +const char *HELP_MSG = "Ringworld\rRevenge of the Patriarch\x14\rScummVM Version\r\r\ +\x01 Keyboard shortcuts...\rF2 - Sound options\rF3 - Quit\r\ +F4 - Restart\rF5 - Save game\rF7 - Restore Game\rF10 - Pause game"; +const char *QUIT_CONFIRM_MSG = "Do you want to quit playing this game?"; +const char *RESTART_MSG = "Do you want to restart this game?"; +const char *GAME_PAUSED_MSG = "Game is paused."; +const char *OPTIONS_MSG = "\x01Options..."; +const char *OK_BTN_STRING = " Ok "; +const char *CANCEL_BTN_STRING = "Cancel"; +const char *QUIT_BTN_STRING = " Quit "; +const char *RESTART_BTN_STRING = "Restart"; +const char *SAVE_BTN_STRING = "Save"; +const char *RESTORE_BTN_STRING = "Restore"; +const char *SOUND_BTN_STRING = "Sound"; +const char *RESUME_BTN_STRING = " Resume \rplay"; +const char *LOOK_BTN_STRING = "Look"; +const char *PICK_BTN_STRING = "Pick"; +const char *START_PLAY_BTN_STRING = " Start Play "; +const char *INTRODUCTION_BTN_STRING = "Introduction"; + +const char *EXIT_MSG = " EXIT "; +const char *SCENE6100_CAREFUL = "Be careful! The probe cannot handle too much of that."; +const char *SCENE6100_TOUGHER = "Hey! This is tougher than it looks!"; +const char *SCENE6100_ONE_MORE_HIT = "You had better be more careful. One more hit like that \ +and the probe may be destroyed."; +const char *SCENE6100_DOING_BEST = "I'm doing the best I can. I just hope it holds together!"; +const char *SCENE6100_REPAIR = "\r\rQuinn and Seeker repair the probe...."; +const char *SCENE6100_ROCKY_AREA = "The rocky area should be directly ahead of you. Do you see it?"; +const char *SCENE6100_REPLY = "Yes. Now if I can just avoid those sunbeams."; +const char *SCENE6100_TAKE_CONTROLS = "You had better take the controls Seeker. My hands are sweating."; +const char *SCENE6100_SURPRISE = "You surprise me Quinn. I would have thought you of hardier stock."; +const char *SCENE6100_SWEAT = "Humans sweat, Kzin twitch their tail. What's the difference?"; +const char *SCENE6100_VERY_WELL = "Very well. I will retrieve the stasis box and return the probe. \ +Wait for it's return in the lander bay."; + +} // End of namespace tSage diff --git a/engines/tsage/staticres.h b/engines/tsage/staticres.h new file mode 100644 index 0000000000..d4690e47bc --- /dev/null +++ b/engines/tsage/staticres.h @@ -0,0 +1,84 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/staticres.h $ + * $Id: staticres.h 213 2011-02-07 10:02:58Z dreammaster $ + * + */ + +#ifndef TSAGE_STATICRES_H +#define TSAGE_STATICRES_H + +#include "common/scummsys.h" + +namespace tSage { + +extern const byte CURSOR_ARROW_DATA[]; + +extern const byte CURSOR_WALK_DATA[]; + +extern const char *LOOK_SCENE_HOTSPOT; +extern const char *USE_SCENE_HOTSPOT; +extern const char *TALK_SCENE_HOTSPOT; +extern const char *SPECIAL_SCENE_HOTSPOT; +extern const char *DEFAULT_SCENE_HOTSPOT; +extern const char *SAVE_ERROR_MSG; +extern const char *SAVING_NOT_ALLOWED_MSG; +extern const char *RESTORING_NOT_ALLOWED_MSG; +extern const char *RESTART_CONFIRM_MSG; +extern const char *WATCH_INTRO_MSG; + +// Dialogs +extern const char *HELP_MSG; +extern const char *QUIT_CONFIRM_MSG; +extern const char *RESTART_MSG; +extern const char *GAME_PAUSED_MSG; +extern const char *OPTIONS_MSG; +extern const char *OK_BTN_STRING; +extern const char *CANCEL_BTN_STRING; +extern const char *QUIT_BTN_STRING; +extern const char *RESTART_BTN_STRING; +extern const char *SAVE_BTN_STRING; +extern const char *RESTORE_BTN_STRING; +extern const char *SOUND_BTN_STRING; +extern const char *RESUME_BTN_STRING; +extern const char *LOOK_BTN_STRING; +extern const char *PICK_BTN_STRING; +extern const char *INV_EMPTY_MSG; +extern const char *START_PLAY_BTN_STRING; +extern const char *INTRODUCTION_BTN_STRING; + +// Scene specific resources +extern const char *EXIT_MSG; +extern const char *SCENE6100_CAREFUL; +extern const char *SCENE6100_TOUGHER; +extern const char *SCENE6100_ONE_MORE_HIT; +extern const char *SCENE6100_DOING_BEST; +extern const char *SCENE6100_REPAIR; +extern const char *SCENE6100_ROCKY_AREA; +extern const char *SCENE6100_REPLY; +extern const char *SCENE6100_TAKE_CONTROLS; +extern const char *SCENE6100_SURPRISE; +extern const char *SCENE6100_SWEAT; +extern const char *SCENE6100_VERY_WELL; + +} // End of namespace tSage + +#endif diff --git a/engines/tsage/tsage.cpp b/engines/tsage/tsage.cpp new file mode 100644 index 0000000000..5be5875652 --- /dev/null +++ b/engines/tsage/tsage.cpp @@ -0,0 +1,136 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/tsage.cpp $ + * $Id: tsage.cpp 211 2011-02-06 06:59:31Z dreammaster $ + * + */ + +#include "common/config-manager.h" +#include "common/debug.h" +#include "common/debug-channels.h" +#include "common/system.h" +#include "common/savefile.h" +#include "engines/util.h" + +#include "tsage/tsage.h" +#include "tsage/core.h" +#include "tsage/dialogs.h" +#include "tsage/events.h" +#include "tsage/resources.h" +#include "tsage/globals.h" + +namespace tSage { + +TSageEngine *_vm = NULL; + +TSageEngine::TSageEngine(OSystem *system, const tSageGameDescription *gameDesc): Engine(system), + _gameDescription(gameDesc) { + _vm = this; + DebugMan.addDebugChannel(kRingDebugScripts, "scripts", "Scripts debugging"); + _debugger = new Debugger(); + _dataManager = NULL; +} + +Common::Error TSageEngine::init() { + initGraphics(SCREEN_WIDTH, SCREEN_HEIGHT, false); + + return Common::kNoError; +} + +TSageEngine::~TSageEngine() { + // Remove all of our debug levels here + DebugMan.clearAllDebugChannels(); + delete _debugger; +} + +bool TSageEngine::hasFeature(EngineFeature f) const { + return + (f == kSupportsRTL) || + (f == kSupportsLoadingDuringRuntime) || + (f == kSupportsSavingDuringRuntime); +} + +void TSageEngine::initialise() { + _tSageManager = new RlbManager(_memoryManager, "tsage.rlb"); + _dataManager = new RlbManager(_memoryManager, "ring.rlb"); + + _saver = new Saver(); + _globals = new Globals(); + _globals->gfxManager().setDefaults(); +} + +void TSageEngine::deinitialise() { + delete _globals; + delete _saver; + delete _tSageManager; + delete _dataManager; +} + +Common::Error TSageEngine::run() { + // Basic initialisation + initialise(); + + _globals->_events.showCursor(); + + _globals->_sceneHandler.registerHandler(); + _globals->_game.execute(); + + deinitialise(); + return Common::kNoError; +} + +/** + * Returns true if it is currently okay to restore a game + */ +bool TSageEngine::canLoadGameStateCurrently() { + return _globals->getFlag(50) == 0; +} + +/** + * Returns true if it is currently okay to save the game + */ +bool TSageEngine::canSaveGameStateCurrently() { + return _globals->getFlag(50) == 0; +} + +/** + * Load the savegame at the specified slot index + */ +Common::Error TSageEngine::loadGameState(int slot) { + return _saver->restore(slot); +} + +/** + * Save the game to the given slot index, and with the given name + */ +Common::Error TSageEngine::saveGameState(int slot, const char *desc) { + return _saver->save(slot, desc); +} + +/** + * Support method that generates a savegame name + * @param slot Slot number + */ +Common::String TSageEngine::generateSaveName(int slot) { + return Common::String::format("%s.%03d", _targetName.c_str(), slot); +} + +} // End of namespace tSage diff --git a/engines/tsage/tsage.h b/engines/tsage/tsage.h new file mode 100644 index 0000000000..02516152ae --- /dev/null +++ b/engines/tsage/tsage.h @@ -0,0 +1,104 @@ +/* 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. + * + * $URL: https://scummvm-misc.svn.sourceforge.net/svnroot/scummvm-misc/trunk/engines/tsage/tsage.h $ + * $Id: tsage.h 212 2011-02-06 10:19:01Z dreammaster $ + * + */ + +#ifndef TSAGE_H +#define TSAGE_H + +#include "engines/advancedDetector.h" +#include "engines/engine.h" +#include "common/rect.h" +#include "audio/mixer.h" +#include "common/file.h" + +#include "tsage/core.h" +#include "tsage/resources.h" +#include "tsage/debugger.h" +#include "tsage/events.h" +#include "tsage/graphics.h" +#include "tsage/resources.h" + + +namespace tSage { + +enum { + GType_Ringworld = 0, + GType_BlueForce = 1 +}; + +enum { + GF_DEMO = 1 << 0, + GF_CD = 1 << 1, + GF_FLOPPY = 1 << 2 +}; + +enum { + kRingDebugScripts = 1 << 0 +}; + +struct tSageGameDescription; + +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 200 +#define SCREEN_CENTRE_X 160 +#define SCREEN_CENTRE_Y 100 + +class TSageEngine : public Engine { +private: + const tSageGameDescription *_gameDescription; +public: + TSageEngine(OSystem *system, const tSageGameDescription *gameDesc); + ~TSageEngine(); + virtual bool hasFeature(EngineFeature f) const; + + MemoryManager _memoryManager; + Debugger *_debugger; + RlbManager *_tSageManager; + RlbManager *_dataManager; + + const char *getGameId() const; + uint32 getGameID() const; + uint32 getFeatures() const; + + virtual Common::Error init(); + virtual Common::Error run(); + virtual bool canLoadGameStateCurrently(); + virtual bool canSaveGameStateCurrently(); + virtual Common::Error loadGameState(int slot); + virtual Common::Error saveGameState(int slot, const char *desc); + Common::String generateSaveName(int slot); + + void initialise(); + void deinitialise(); +}; + +extern TSageEngine *_vm; + +#define ALLOCATE_HANDLE(x) _vm->_memoryManager.allocate(x) +#define ALLOCATE(x) _vm->_memoryManager.allocate2(x) +#define DEALLOCATE(x) _vm->_memoryManager.deallocate(x) + +} // End of namespace tSage + +#endif |