/* 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. * */ #include "titanic/pet_control/pet_remote.h" #include "titanic/pet_control/pet_remote_glyphs.h" #include "titanic/pet_control/pet_control.h" #include "titanic/messages/pet_messages.h" #include "titanic/game_manager.h" #include "titanic/titanic.h" namespace Titanic { static const byte REMOTE_DATA[] = { 0x00, 0x02, GLYPH_SUMMON_ELEVATOR, GLYPH_SUCCUBUS_DELIVERY, 0x01, 0x02, GLYPH_SUMMON_PELLERATOR, GLYPH_SUCCUBUS_DELIVERY, 0x02, 0x03, GLYPH_TELEVISION_CONTROL, GLYPH_OPERATE_LIGHTS, GLYPH_SUCCUBUS_DELIVERY, 0x03, 0x02, GLYPH_SUMMON_ELEVATOR, GLYPH_SUCCUBUS_DELIVERY, 0x04, 0x02, GLYPH_TELEVISION_CONTROL, GLYPH_SUCCUBUS_DELIVERY, 0x05, 0x02, GLYPH_SUMMON_PELLERATOR, GLYPH_SUCCUBUS_DELIVERY, 0x06, 0x02, GLYPH_SUMMON_PELLERATOR, GLYPH_SUCCUBUS_DELIVERY, 0x07, 0x03, GLYPH_TELEVISION_CONTROL, GLYPH_SUMMON_PELLERATOR, GLYPH_SUCCUBUS_DELIVERY, 0x08, 0x01, GLYPH_SUCCUBUS_DELIVERY, 0x09, 0x01, GLYPH_SUCCUBUS_DELIVERY, 0x0A, 0x02, GLYPH_SUMMON_ELEVATOR, GLYPH_SUCCUBUS_DELIVERY, 0x0B, 0x01, GLYPH_NAVIGATION_CONTROLLER, 0x0C, 0x01, GLYPH_SUCCUBUS_DELIVERY, 0x0D, 0x01, GLYPH_SUCCUBUS_DELIVERY, 0x0E, 0x00, 0x0F, 0x01, GLYPH_TELEVISION_CONTROL, 0x10, 0x03, GLYPH_GOTO_BOTTOM_OF_WELL, GLYPH_GOTO_STATEROOM, GLYPH_GOTO_TOP_OF_WELL, 0x11, 0x01, GLYPH_SUCCUBUS_DELIVERY, 0x12, 0x00, 0x13, 0x02, GLYPH_SUMMON_PELLERATOR, GLYPH_SUCCUBUS_DELIVERY, 0x14, 0x00, 0x15, 0x02, GLYPH_SUCCUBUS_DELIVERY, GLYPH_TELEVISION_CONTROL, 0x16, 0x00, 0x17, 0x02, GLYPH_SUMMON_PELLERATOR, GLYPH_SUCCUBUS_DELIVERY, 0x18, 0x01, GLYPH_SUCCUBUS_DELIVERY, 0x19, 0x00, 0x1A, 0x00, 0x1B, 0x00, 0x1C, 0x00, 0x1D, 0x02, GLYPH_SUMMON_ELEVATOR, GLYPH_SUCCUBUS_DELIVERY, 0x1E, 0x0C, GLYPH_DEPLOY_FLORAL, GLYPH_DEPLOY_FULLY_RELAXATION, GLYPH_DEPLOY_COMFORT, GLYPH_DEPLOY_MINOR_STORAGE, GLYPH_ENTERTAINMENT_DEVICE, GLYPH_DEPLOY_MAJOR_RELAXATION, GLYPH_INFLATE_RELAXATION, GLYPH_DEPLOY_MAINTENANCE, GLYPH_DEPLOY_WORK_SURFACE, GLYPH_DEPLOY_MINOR_RELAXATION, GLYPH_DEPLOY_SINK, GLYPH_DEPLOY_MAJOR_STORAGE, 0x1F, 0x01, GLYPH_SUCCUBUS_DELIVERY, 0x20, 0x02, GLYPH_SUMMON_ELEVATOR, GLYPH_SUMMON_PELLERATOR, 0x21, 0x00 }; CPetRemote::CPetRemote() : CPetSection() { } bool CPetRemote::setup(CPetControl *petControl) { if (petControl && setupControl(petControl)) return reset(); return false; } bool CPetRemote::reset() { if (_petControl) { _onOff.reset("PetSwitchOn", _petControl, MODE_SELECTED); _onOff.reset("PetSwitchOff", _petControl, MODE_UNSELECTED); _up.reset("PetUp", _petControl, MODE_UNSELECTED); _down.reset("PetDown", _petControl, MODE_UNSELECTED); _left.reset("PetLeftUp", _petControl, MODE_SELECTED); _left.reset("PetLeft", _petControl, MODE_UNSELECTED); _right.reset("PetRightUp", _petControl, MODE_SELECTED); _right.reset("PetRight", _petControl, MODE_UNSELECTED); _top.reset("PetTopUp", _petControl, MODE_SELECTED); _top.reset("PetTop", _petControl, MODE_UNSELECTED); _bottom.reset("PetBottomUp", _petControl, MODE_UNSELECTED); _bottom.reset("PetBottom", _petControl, MODE_SELECTED); _action.reset("PetActionUp", _petControl, MODE_UNSELECTED); _action.reset("PetAction", _petControl, MODE_SELECTED); _send.reset("PetActSend0", _petControl, MODE_UNSELECTED); _send.reset("PetActSend1", _petControl, MODE_SELECTED); _receive.reset("PetActReceive0", _petControl, MODE_UNSELECTED); _receive.reset("PetActReceive1", _petControl, MODE_SELECTED); _call.reset("PetActCall0", _petControl, MODE_UNSELECTED); _call.reset("PetActCall1", _petControl, MODE_SELECTED); _items.reset(); uint col = getColor(0); _text.setColor(col); _text.setLineColor(0, col); } return true; } void CPetRemote::draw(CScreenManager *screenManager) { _petControl->drawSquares(screenManager, 6); _items.draw(screenManager); _text.draw(screenManager); } bool CPetRemote::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { return _items.MouseButtonDownMsg(msg->_mousePos); } bool CPetRemote::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { return _items.MouseButtonUpMsg(msg->_mousePos); } bool CPetRemote::MouseDoubleClickMsg(CMouseDoubleClickMsg *msg) { return _items.MouseButtonDownMsg(msg->_mousePos); } bool CPetRemote::VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) { return _items.VirtualKeyCharMsg(msg); } bool CPetRemote::MouseWheelMsg(CMouseWheelMsg *msg) { if (msg->_wheelUp) _items.scrollLeft(); else _items.scrollRight(); return true; } bool CPetRemote::isValid(CPetControl *petControl) { return setupControl(petControl); } void CPetRemote::postLoad() { reset(); CRoomItem *room = getRoom(); if (room) enterRoom(room); } void CPetRemote::enter(PetArea oldArea) { if (_items.highlighted14()) _text.setText(CString()); } void CPetRemote::enterRoom(CRoomItem *room) { clearGlyphs(); if (room) { CString roomName = room->getName(); int roomIndex = roomIndexOf(roomName); if (roomIndex != -1) { Common::Array indexes; if (getRemoteData(roomIndex, indexes)) { loadGlyphs(indexes); _items.scrollToStart(); } } } } CPetText *CPetRemote::getText() { return &_text; } CPetGfxElement *CPetRemote::getElement(uint id) { switch (id) { case 0: return &_onOff; case 1: return &_up; case 2: return &_down; case 3: return &_left; case 4: return &_right; case 5: return &_top; case 6: return &_bottom; case 7: return &_action; case 16: return &_send; case 17: return &_receive; case 18: return &_call; default: return nullptr; } } void CPetRemote::highlight(int id) { int highlightIndex = getHighlightIndex((RemoteGlyph)id); if (highlightIndex != -1) _items.highlight(highlightIndex); } bool CPetRemote::setupControl(CPetControl *petControl) { _petControl = petControl; if (!petControl) return false; _onOff.setBounds(Rect(0, 0, 15, 43)); _onOff.translate(519, 381); _up.setBounds(Rect(0, 0, 21, 24)); _up.translate(551, 381); _down.setBounds(Rect(0, 0, 21, 24)); _down.translate(551, 402); _left.setBounds(Rect(0, 0, 22, 21)); _left.translate(518, 393); _right.setBounds(Rect(0, 0, 21, 21)); _right.translate(560, 393); _top.setBounds(Rect(0, 0, 21, 22)); _top.translate(539, 371); _bottom.setBounds(Rect(0, 0, 21, 22)); _bottom.translate(539, 414); _action.setBounds(Rect(0, 0, 21, 21)); _action.translate(539, 393); _send.setBounds(Rect(0, 0, 62, 38)); _send.translate(503, 373); _receive.setBounds(Rect(0, 0, 62, 38)); _receive.translate(503, 420); _call.setBounds(Rect(0, 0, 62, 38)); _call.translate(503, 383); Rect rect(0, 0, 580, 15); rect.moveTo(32, 445); _text.setBounds(rect); _text.setHasBorder(false); _items.setup(6, this); _items.setFlags(19); return true; } CRoomItem *CPetRemote::getRoom() const { if (_petControl) { CGameManager *gameManager = _petControl->getGameManager(); if (gameManager) return gameManager->getRoom(); } return nullptr; } int CPetRemote::getHighlightIndex(RemoteGlyph val) { CRoomItem *room = getRoom(); if (!room) return -1; int roomIndex = roomIndexOf(room->getName()); if (roomIndex == -1) return -1; Common::Array remoteData; getRemoteData(roomIndex, remoteData); // Loop through the data for the room for (uint idx = 0; idx < remoteData.size(); ++idx) { if ((RemoteGlyph)remoteData[idx + 1] == val) return idx; } return -1; } int CPetRemote::roomIndexOf(const CString &name) { for (int idx = 0; idx < TOTAL_ROOMS; ++idx) { if (g_vm->_roomNames[idx] == name) return idx; } return -1; } bool CPetRemote::getRemoteData(int roomIndex, Common::Array &indexes) { const byte *p = &REMOTE_DATA[0]; for (int idx = 0; idx < TOTAL_ROOMS; ++idx) { if (*p == roomIndex) { for (int ctr = 0; ctr < p[1]; ++ctr) indexes.push_back(p[ctr + 2]); return true; } p += *(p + 1) + 2; } return false; } bool CPetRemote::loadGlyphs(const Common::Array &indexes) { for (uint idx = 0; idx < indexes.size(); ++idx) { if (!loadGlyph(indexes[idx])) return false; } return true; } bool CPetRemote::loadGlyph(int glyphIndex) { CPetRemoteGlyph *glyph = nullptr; switch (glyphIndex) { case GLYPH_SUMMON_ELEVATOR: glyph = new CSummonElevatorGlyph(); break; case GLYPH_SUMMON_PELLERATOR: glyph = new CSummonPelleratorGlyph(); break; case GLYPH_TELEVISION_CONTROL: glyph = new CTelevisionControlGlyph(); break; case GLYPH_ENTERTAINMENT_DEVICE: glyph = new CEntertainmentDeviceGlyph(); break; case GLYPH_OPERATE_LIGHTS: glyph = new COperateLightsGlyph(); break; case GLYPH_DEPLOY_FLORAL: glyph = new CDeployFloralGlyph(); break; case GLYPH_DEPLOY_FULLY_RELAXATION: glyph = new CDeployFullyRelaxationGlyph(); break; case GLYPH_DEPLOY_COMFORT: glyph = new CDeployComfortGlyph(); break; case GLYPH_DEPLOY_MINOR_STORAGE: glyph = new CDeployMinorStorageGlyph(); break; case GLYPH_DEPLOY_MAJOR_RELAXATION: glyph = new CDeployMajorRelaxationGlyph(); break; case GLYPH_INFLATE_RELAXATION: glyph = new CInflateRelaxationGlyph(); break; case GLYPH_DEPLOY_MAINTENANCE: glyph = new CDeployMaintenanceGlyph(); break; case GLYPH_DEPLOY_WORK_SURFACE: glyph = new CDeployWorkSurfaceGlyph(); break; case GLYPH_DEPLOY_MINOR_RELAXATION: glyph = new CDeployMinorRelaxationGlyph(); break; case GLYPH_DEPLOY_SINK: glyph = new CDeploySinkGlyph(); break; case GLYPH_DEPLOY_MAJOR_STORAGE: glyph = new CDeployMajorStorageGlyph(); break; case GLYPH_SUCCUBUS_DELIVERY: glyph = new CSuccubusDeliveryGlyph(); break; case GLYPH_NAVIGATION_CONTROLLER: glyph = new CNavigationControllerGlyph(); break; case GLYPH_GOTO_BOTTOM_OF_WELL: glyph = new CGotoBottomOfWellGlyph(); break; case GLYPH_GOTO_TOP_OF_WELL: glyph = new CGotoTopOfWellGlyph(); break; case GLYPH_GOTO_STATEROOM: glyph = new CGotoStateroomGlyph(); break; case GLYPH_GOTO_BAR: glyph = new CGotoBarGlyph(); case GLYPH_GOTO_PROMENADE: glyph = new CGotoPromenadeDeckGlyph(); break; case GLYPH_GOTO_ARBORETUM: glyph = new CGotoArboretumGlyph(); break; case GLYPH_GOTO_MUSIC_ROOM: glyph = new CGotoMusicRoomGlyph(); break; case GLYPH_GOTO_RESTAURANT: glyph = new CGotoRestaurantGlyph(); break; default: break; } if (glyph) { if (glyph->setup(_petControl, &_items)) { _items.push_back(glyph); return true; } } return false; } void CPetRemote::generateMessage(RemoteMessage msgNum, const CString &name, int num) { switch (msgNum) { case RMSG_LEFT: { CPETLeftMsg msg(name, num); msg.execute(_petControl->_remoteTarget); break; } case RMSG_RIGHT: { CPETRightMsg msg(name, num); msg.execute(_petControl->_remoteTarget); break; } case RMSG_UP: { CPETUpMsg msg(name, num); msg.execute(_petControl->_remoteTarget); break; } case RMSG_DOWN: { CPETDownMsg msg(name, num); msg.execute(_petControl->_remoteTarget); break; } case RMSG_ACTIVATE: { CPETActivateMsg msg(name, num); msg.execute(_petControl->_remoteTarget); break; } default: break; } } } // End of namespace Titanic