517 lines
12 KiB
C++
517 lines
12 KiB
C++
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#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,
|
|
#if defined(DISABLE_SKIP)
|
|
0x0B, 0x01,
|
|
GLYPH_NAVIGATION_CONTROLLER,
|
|
#else
|
|
0x0B, 0x02,
|
|
GLYPH_NAVIGATION_CONTROLLER, GLYPH_SKIP_NAVIGATION,
|
|
#endif
|
|
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_UNSELECTED);
|
|
_left.reset("PetLeft", _petControl, MODE_SELECTED);
|
|
_right.reset("PetRightUp", _petControl, MODE_UNSELECTED);
|
|
_right.reset("PetRight", _petControl, MODE_SELECTED);
|
|
_top.reset("PetTopUp", _petControl, MODE_UNSELECTED);
|
|
_top.reset("PetTop", _petControl, MODE_SELECTED);
|
|
_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::ActionMsg(CActionMsg *msg) {
|
|
return _items.ActionMsg(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<uint> indexes;
|
|
if (getRemoteData(roomIndex, indexes)) {
|
|
loadGlyphs(indexes);
|
|
_items.scrollToStart();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CTextControl *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<uint> remoteData;
|
|
getRemoteData(roomIndex, remoteData);
|
|
|
|
// Loop through the data for the room
|
|
for (uint idx = 0; idx < remoteData.size(); ++idx) {
|
|
if ((RemoteGlyph)remoteData[idx] == 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<uint> &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<uint> &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;
|
|
|
|
#if !defined(DISABLE_SKIP)
|
|
case GLYPH_SKIP_NAVIGATION:
|
|
glyph = new CSkipNavigationGlyph();
|
|
break;
|
|
#endif
|
|
|
|
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();
|
|
break;
|
|
|
|
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
|