diff options
Diffstat (limited to 'engines/titanic/core')
48 files changed, 8560 insertions, 0 deletions
diff --git a/engines/titanic/core/background.cpp b/engines/titanic/core/background.cpp new file mode 100644 index 0000000000..f180df8867 --- /dev/null +++ b/engines/titanic/core/background.cpp @@ -0,0 +1,78 @@ +/* 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/core/background.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CBackground, CGameObject) + ON_MESSAGE(StatusChangeMsg) + ON_MESSAGE(SetFrameMsg) + ON_MESSAGE(VisibleMsg) +END_MESSAGE_MAP() + +CBackground::CBackground() : CGameObject(), _fieldBC(0), _fieldC0(0), _fieldDC(0) { +} + +void CBackground::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldBC, indent); + file->writeNumberLine(_fieldC0, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + file->writeNumberLine(_fieldDC, indent); + + CGameObject::save(file, indent); +} + +void CBackground::load(SimpleFile *file) { + file->readNumber(); + _fieldBC = file->readNumber(); + _fieldC0 = file->readNumber(); + _string1 = file->readString(); + _string2 = file->readString(); + _fieldDC = file->readNumber(); + + CGameObject::load(file); +} + +bool CBackground::StatusChangeMsg(CStatusChangeMsg *msg) { + setVisible(true); + if (_fieldDC) { + playMovie(_fieldBC, _fieldC0, 16); + } else { + playMovie(_fieldBC, _fieldC0, 0); + } + return true; +} + +bool CBackground::SetFrameMsg(CSetFrameMsg *msg) { + loadFrame(msg->_frameNumber); + return true; +} + +bool CBackground::VisibleMsg(CVisibleMsg *msg) { + setVisible(msg->_visible); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/background.h b/engines/titanic/core/background.h new file mode 100644 index 0000000000..6a2fd21454 --- /dev/null +++ b/engines/titanic/core/background.h @@ -0,0 +1,59 @@ +/* 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. + * + */ + +#ifndef TITANIC_BACKGROUND_H +#define TITANIC_BACKGROUND_H + +#include "titanic/core/game_object.h" +#include "titanic/messages/messages.h" + +namespace Titanic { + +class CBackground : public CGameObject { + DECLARE_MESSAGE_MAP; + bool StatusChangeMsg(CStatusChangeMsg *msg); + bool SetFrameMsg(CSetFrameMsg *msg); + bool VisibleMsg(CVisibleMsg *msg); +protected: + int _fieldBC; + int _fieldC0; + CString _string1; + CString _string2; + int _fieldDC; +public: + CLASSDEF; + CBackground(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_BACKGROUND_H */ diff --git a/engines/titanic/core/click_responder.cpp b/engines/titanic/core/click_responder.cpp new file mode 100644 index 0000000000..f9694557df --- /dev/null +++ b/engines/titanic/core/click_responder.cpp @@ -0,0 +1,43 @@ +/* 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/core/click_responder.h" + +namespace Titanic { + +void CClickResponder::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + + CGameObject::save(file, indent); +} + +void CClickResponder::load(SimpleFile *file) { + file->readNumber(); + _string1 = file->readString(); + _string2 = file->readString(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/click_responder.h b/engines/titanic/core/click_responder.h new file mode 100644 index 0000000000..78381b9948 --- /dev/null +++ b/engines/titanic/core/click_responder.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. + * + */ + +#ifndef TITANIC_CLICK_RESPONDER_H +#define TITANIC_CLICK_RESPONDER_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CClickResponder : public CGameObject { +protected: + CString _string1, _string2; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CLICK_RESPONDER_H */ diff --git a/engines/titanic/core/dont_save_file_item.cpp b/engines/titanic/core/dont_save_file_item.cpp new file mode 100644 index 0000000000..b8864bb2b5 --- /dev/null +++ b/engines/titanic/core/dont_save_file_item.cpp @@ -0,0 +1,37 @@ +/* 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/core/dont_save_file_item.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CDontSaveFileItem, CFileItem); + +void CDontSaveFileItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); +} + +void CDontSaveFileItem::load(SimpleFile *file) { + file->readNumber(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/dont_save_file_item.h b/engines/titanic/core/dont_save_file_item.h new file mode 100644 index 0000000000..f5ec4f791d --- /dev/null +++ b/engines/titanic/core/dont_save_file_item.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. + * + */ + +#ifndef TITANIC_DONT_SAVE_FILE_ITEM_H +#define TITANIC_DONT_SAVE_FILE_ITEM_H + +#include "titanic/core/file_item.h" + +namespace Titanic { + +class CDontSaveFileItem : public CFileItem { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DONT_SAVE_FILE_ITEM_H */ diff --git a/engines/titanic/core/drop_target.cpp b/engines/titanic/core/drop_target.cpp new file mode 100644 index 0000000000..05ea6445c3 --- /dev/null +++ b/engines/titanic/core/drop_target.cpp @@ -0,0 +1,72 @@ +/* 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/core/drop_target.h" + +namespace Titanic { + +CDropTarget::CDropTarget() : CGameObject(), _fieldC4(0), + _fieldD4(0), _fieldE4(0), _fieldF4(0), _fieldF8(0), + _fieldFC(0), _field10C(1), _field110(8), _field114(20) { +} + +void CDropTarget::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writePoint(_pos1, indent); + file->writeNumberLine(_fieldC4, indent); + file->writeQuotedLine(_string1, indent); + file->writeNumberLine(_fieldD4, indent); + file->writeQuotedLine(_string2, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeQuotedLine(_string3, indent); + file->writeNumberLine(_fieldF4, indent); + file->writeNumberLine(_fieldF8, indent); + file->writeNumberLine(_fieldFC, indent); + file->writeQuotedLine(_string4, indent); + file->writeNumberLine(_field10C, indent); + file->writeNumberLine(_field110, indent); + file->writeNumberLine(_field114, indent); + + CGameObject::save(file, indent); +} + +void CDropTarget::load(SimpleFile *file) { + file->readNumber(); + _pos1 = file->readPoint(); + _fieldC4 = file->readNumber(); + _string1 = file->readString(); + _fieldD4 = file->readNumber(); + _string2 = file->readString(); + _fieldE4 = file->readNumber(); + _string3 = file->readString(); + _fieldF4 = file->readNumber(); + _fieldF8 = file->readNumber(); + _fieldFC = file->readNumber(); + _string4 = file->readString(); + _field10C = file->readNumber(); + _field110 = file->readNumber(); + _field114 = file->readNumber(); + + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/drop_target.h b/engines/titanic/core/drop_target.h new file mode 100644 index 0000000000..4bd0ae448c --- /dev/null +++ b/engines/titanic/core/drop_target.h @@ -0,0 +1,63 @@ +/* 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. + * + */ + +#ifndef TITANIC_DROP_TARGET_H +#define TITANIC_DROP_TARGET_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CDropTarget : public CGameObject { +private: + Point _pos1; + int _fieldC4; + CString _string1; + int _fieldD4; + CString _string2; + int _fieldE4; + CString _string3; + int _fieldF4; + int _fieldF8; + int _fieldFC; + CString _string4; + int _field10C; + int _field110; + int _field114; +public: + CLASSDEF; + CDropTarget(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DROP_TARGET_H */ diff --git a/engines/titanic/core/file_item.cpp b/engines/titanic/core/file_item.cpp new file mode 100644 index 0000000000..b783c758df --- /dev/null +++ b/engines/titanic/core/file_item.cpp @@ -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. + * + */ + +#include "titanic/core/file_item.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CFileItem, CTreeItem); + +void CFileItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + CTreeItem::save(file, indent); +} + +void CFileItem::load(SimpleFile *file) { + file->readNumber(); + + CTreeItem::load(file); +} + +CString CFileItem::formFilename() const { + return ""; +} + +CString CFileItem::getFilename() const { + //dynamic_cast<CFileItem *>(getRoot())->formDataPath(); + return _filename; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/file_item.h b/engines/titanic/core/file_item.h new file mode 100644 index 0000000000..4cecee4882 --- /dev/null +++ b/engines/titanic/core/file_item.h @@ -0,0 +1,67 @@ +/* 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. + * + */ + +#ifndef TITANIC_FILE_ITEM_H +#define TITANIC_FILE_ITEM_H + +#include "titanic/support/string.h" +#include "titanic/core/list.h" +#include "titanic/core/tree_item.h" + +namespace Titanic { + +class CFileItem: public CTreeItem { + DECLARE_MESSAGE_MAP; +private: + CString _filename; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Returns true if the item is a file item + */ + virtual bool isFileItem() const { return true; } + + /** + * Form a filename for the file item + */ + CString formFilename() const; + + /** + * Get a string? + */ + CString getFilename() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FILE_ITEM_H */ diff --git a/engines/titanic/core/game_object.cpp b/engines/titanic/core/game_object.cpp new file mode 100644 index 0000000000..39e4f8412e --- /dev/null +++ b/engines/titanic/core/game_object.cpp @@ -0,0 +1,1510 @@ +/* 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/core/game_object.h" +#include "titanic/core/mail_man.h" +#include "titanic/core/resource_key.h" +#include "titanic/core/room_item.h" +#include "titanic/npcs/true_talk_npc.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/star_control/star_control.h" +#include "titanic/support/files_manager.h" +#include "titanic/support/screen_manager.h" +#include "titanic/support/video_surface.h" +#include "titanic/game_manager.h" +#include "titanic/titanic.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CGameObject, CNamedItem); + +CCreditText *CGameObject::_credits; + +void CGameObject::init() { + _credits = nullptr; +} + +void CGameObject::deinit() { + if (_credits) { + _credits->clear(); + delete _credits; + _credits = nullptr; + } +} + +CGameObject::CGameObject(): CNamedItem() { + _bounds = Rect(0, 0, 15, 15); + _field34 = 0; + _field38 = 0; + _field3C = 0; + _field40 = 0; + _field44 = 0xF0; + _field48 = 0xF0; + _field4C = 0xFF; + _isMail = false; + _id = 0; + _roomFlags = 0; + _visible = true; + _field60 = 0; + _cursorId = CURSOR_ARROW; + _initialFrame = 0; + _frameNumber = -1; + _text = nullptr; + _textBorder = _textBorderRight = 0; + _field9C = 0; + _surface = nullptr; + _fieldB8 = 0; +} + +CGameObject::~CGameObject() { + delete _surface; + delete _text; +} + +void CGameObject::save(SimpleFile *file, int indent) { + file->writeNumberLine(7, indent); + _movieRangeInfoList.destroyContents(); + + if (_surface) { + const CMovieRangeInfoList *rangeList = _surface->getMovieRangeInfo(); + + if (rangeList) { + for (CMovieRangeInfoList::const_iterator i = rangeList->begin(); + i != rangeList->end(); ++i) { + CMovieRangeInfo *rangeInfo = new CMovieRangeInfo(*i); + rangeInfo->_initialFrame = (i == rangeList->begin()) ? getMovieFrame() : -1; + } + } + } + + _movieRangeInfoList.save(file, indent); + _movieRangeInfoList.destroyContents(); + + file->writeNumberLine(getMovieFrame(), indent + 1); + file->writeNumberLine(_cursorId, indent + 1); + _movieClips.save(file, indent + 1); + file->writeNumberLine(_field60, indent + 1); + file->writeNumberLine(_field40, indent + 1); + file->writeQuotedLine(_resource, indent + 1); + file->writeBounds(_bounds, indent + 1); + + file->writeFloatLine(_field34, indent + 1); + file->writeFloatLine(_field38, indent + 1); + file->writeFloatLine(_field3C, indent + 1); + + file->writeNumberLine(_field44, indent + 1); + file->writeNumberLine(_field48, indent + 1); + file->writeNumberLine(_field4C, indent + 1); + file->writeNumberLine(_fieldB8, indent + 1); + file->writeNumberLine(_visible, indent + 1); + file->writeNumberLine(_isMail, indent + 1); + file->writeNumberLine(_id, indent + 1); + file->writeNumberLine(_roomFlags, indent + 1); + + if (_surface) { + _surface->_resourceKey.save(file, indent); + } else { + CResourceKey resourceKey; + resourceKey.save(file, indent); + } + file->writeNumberLine(_surface != nullptr, indent); + + CNamedItem::save(file, indent); +} + +void CGameObject::load(SimpleFile *file) { + int val = file->readNumber(); + CResourceKey resourceKey; + + switch (val) { + case 7: + _movieRangeInfoList.load(file); + _frameNumber = file->readNumber(); + // Deliberate fall-through + + case 6: + _cursorId = (CursorId)file->readNumber(); + // Deliberate fall-through + + case 5: + _movieClips.load(file); + // Deliberate fall-through + + case 4: + _field60 = file->readNumber(); + // Deliberate fall-through + + case 3: + _field40 = file->readNumber(); + // Deliberate fall-through + + case 2: + _resource = file->readString(); + // Deliberate fall-through + + case 1: + _bounds = file->readBounds(); + _field34 = file->readFloat(); + _field38 = file->readFloat(); + _field3C = file->readFloat(); + _field44 = file->readNumber(); + _field48 = file->readNumber(); + _field4C = file->readNumber(); + _fieldB8 = file->readNumber(); + _visible = file->readNumber() != 0; + _isMail = file->readNumber(); + _id = file->readNumber(); + _roomFlags = file->readNumber(); + + resourceKey.load(file); + _surface = nullptr; + val = file->readNumber(); + if (val) { + _resource = resourceKey.getString(); + } + break; + + default: + break; + } + + CNamedItem::load(file); +} + +void CGameObject::draw(CScreenManager *screenManager) { + if (!_visible) + return; + if (_credits && _credits->_objectP == this) { + if (!_credits->draw()) + CGameObject::deinit(); + + return; + } + + if (_field40) { + // If a text object is defined, handle drawing it + if (_text && _bounds.intersects(getGameManager()->_bounds)) + _text->draw(screenManager); + + return; + } else { + if (!_surface) { + if (!_resource.empty()) { + loadResource(_resource); + _resource = ""; + } + } + + if (_surface) { + _bounds.setWidth(_surface->getWidth()); + _bounds.setHeight(_surface->getHeight()); + + if (!_bounds.width() || !_bounds.height()) + return; + + if (_frameNumber >= 0) { + loadFrame(_frameNumber); + _frameNumber = -1; + } + + if (!_movieRangeInfoList.empty()) + processMoveRangeInfo(); + + if (_bounds.intersects(getGameManager()->_bounds)) { + if (_surface) { + Point destPos(_bounds.left, _bounds.top); + screenManager->blitFrom(SURFACE_BACKBUFFER, _surface, &destPos); + } + + if (_text) + _text->draw(screenManager); + } + } + } +} + +Rect CGameObject::getBounds() const { + return (_surface && _surface->hasFrame()) ? _bounds : Rect(); +} + +void CGameObject::viewChange() { + // Handle freeing the surfaces of objects when their view is left + if (_surface) { + _resource = _surface->_resourceKey.getString(); + _initialFrame = getMovieFrame(); + + delete _surface; + _surface = nullptr; + } +} + +void CGameObject::stopMovie() { + if (_surface) + _surface->stopMovie(); +} + +bool CGameObject::checkPoint(const Point &pt, bool ignore40, bool visibleOnly) { + if ((!_visible && visibleOnly) || !_bounds.contains(pt)) + return false; + + if (ignore40 || _field40) + return true; + + if (!_surface) { + if (_frameNumber == -1) + return true; + loadFrame(_frameNumber); + if (!_surface) + return true; + } + + Common::Point pixelPos = pt - _bounds; + if (_surface->_transBlitFlag) { + pixelPos.y = ((_bounds.height() - _bounds.top) / 2) * 2 - pixelPos.y; + } + + uint transColor = _surface->getTransparencyColor(); + uint pixel = _surface->getPixel(pixelPos); + return pixel != transColor; +} + +bool CGameObject::clipRect(const Rect &rect1, Rect &rect2) const { + if (!rect2.intersects(rect1)) + return false; + + rect2.clip(rect1); + return true; +} + +void CGameObject::draw(CScreenManager *screenManager, const Rect &destRect, const Rect &srcRect) { + Rect tempRect = destRect; + if (clipRect(srcRect, tempRect)) { + if (!_surface && !_resource.empty()) { + loadResource(_resource); + _resource.clear(); + } + + if (_surface) + screenManager->blitFrom(SURFACE_PRIMARY, &tempRect, _surface); + } +} + +void CGameObject::draw(CScreenManager *screenManager, const Point &destPos) { + if (!_surface && !_resource.empty()) { + loadResource(_resource); + _resource.clear(); + } + + if (_surface) { + int xSize = _surface->getWidth(); + int ySize = _surface->getHeight(); + + if (xSize > 0 && ySize > 0) { + screenManager->blitFrom(SURFACE_BACKBUFFER, _surface, &destPos); + } + } +} + +void CGameObject::draw(CScreenManager *screenManager, const Point &destPos, const Rect &srcRect) { + draw(screenManager, Rect(destPos.x, destPos.y, destPos.x + 52, destPos.y + 52), srcRect); +} + +bool CGameObject::isPet() const { + return isInstanceOf(CPetControl::_type); +} + +void CGameObject::loadResource(const CString &name) { + switch (name.fileTypeSuffix()) { + case FILETYPE_IMAGE: + loadImage(name); + break; + case FILETYPE_MOVIE: + loadMovie(name); + break; + default: + break; + } +} + +void CGameObject::loadMovie(const CString &name, bool pendingFlag) { + g_vm->_filesManager->preload(name); + + // Create the surface if it doesn't already exist + if (!_surface) { + CGameManager *gameManager = getGameManager(); + _surface = new OSVideoSurface(gameManager->setScreenManager(), nullptr); + } + + // Load the new movie resource + CResourceKey key(name); + _surface->loadResource(key); + + if (_surface->hasSurface() && !pendingFlag) { + _bounds.setWidth(_surface->getWidth()); + _bounds.setHeight(_surface->getHeight()); + } + + if (_initialFrame) + loadFrame(_initialFrame); +} + +void CGameObject::loadImage(const CString &name, bool pendingFlag) { + // Get a refernce to the game and screen managers + CGameManager *gameManager = getGameManager(); + CScreenManager *screenManager; + + if (gameManager && (screenManager = CScreenManager::setCurrent()) != nullptr) { + // Destroy the object's surface if it already had one + if (_surface) { + delete _surface; + _surface = nullptr; + } + + g_vm->_filesManager->preload(name); + + if (!name.empty()) { + _surface = new OSVideoSurface(screenManager, CResourceKey(name), pendingFlag); + } + + if (_surface && !pendingFlag) { + _bounds.right = _surface->getWidth(); + _bounds.bottom = _surface->getHeight(); + } + + // Mark the object's area as dirty, so that on the next frame rendering + // this object will be redrawn + makeDirty(); + } + + _initialFrame = 0; +} + +void CGameObject::loadFrame(int frameNumber) { + if (frameNumber != -1 && !_resource.empty()) + loadResource(_resource); + + if (_surface) + _surface->setMovieFrame(frameNumber); + + makeDirty(); +} + +void CGameObject::processMoveRangeInfo() { + for (CMovieRangeInfoList::iterator i = _movieRangeInfoList.begin(); i != _movieRangeInfoList.end(); ++i) + (*i)->process(this); + + _movieRangeInfoList.destroyContents(); +} + +void CGameObject::makeDirty(const Rect &r) { + CGameManager *gameManager = getGameManager(); + if (gameManager) + gameManager->extendBounds(r); +} + +void CGameObject::makeDirty() { + makeDirty(_bounds); +} + +bool CGameObject::soundFn1(int handle) { + if (handle != 0 && handle != -1) { + CGameManager *gameManager = getGameManager(); + if (gameManager) + return gameManager->_sound.fn1(handle); + } + + return false; +} + +void CGameObject::soundFn2(const CString &resName, int v1, int v2, int v3, int handleIndex) { + warning("TODO: CGameObject::soundFn2"); +} + +void CGameObject::soundFn3(int handle, int val2, int val3) { + if (handle != 0 && handle != -1) { + CGameManager *gameManager = getGameManager(); + if (gameManager) + return gameManager->_sound.fn3(handle, val2, val3); + } +} + +void CGameObject::soundFn4(int v1, int v2, int v3) { + warning("CGameObject::soundFn4"); +} + +void CGameObject::soundFn5(int v1, int v2, int v3) { + warning("CGameObject::soundFn5"); +} + +void CGameObject::sound8(bool flag) const { + getGameManager()->_sound.managerProc8(flag ? 3 : 0); +} + +void CGameObject::setVisible(bool val) { + if (val != _visible) { + _visible = val; + makeDirty(); + } +} + +void CGameObject::petHighlightGlyph(int val) { + CPetControl *pet = getPetControl(); + if (pet) + pet->highlightGlyph(val); +} + +void CGameObject::petHideCursor() { + CPetControl *pet = getPetControl(); + if (pet) + pet->hideCursor(); +} + +void CGameObject::petShowCursor() { + CPetControl *pet = getPetControl(); + if (pet) + pet->showCursor(); +} + +void CGameObject::petShow() { + CGameManager *gameManager = getGameManager(); + if (gameManager) { + gameManager->_gameState._petActive = true; + gameManager->_gameState.setMode(GSMODE_INTERACTIVE); + gameManager->initBounds(); + } +} + +void CGameObject::petHide() { + CGameManager *gameManager = getGameManager(); + if (gameManager) { + gameManager->_gameState._petActive = false; + gameManager->_gameState.setMode(GSMODE_INTERACTIVE); + gameManager->initBounds(); + } +} + +void CGameObject::petSetRemoteTarget() { + CPetControl *pet = getPetControl(); + if (pet) + pet->setRemoteTarget(this); +} + +void CGameObject::playMovie(uint flags) { + _frameNumber = -1; + + if (!_surface && !_resource.empty()) { + loadResource(_resource); + _resource.clear(); + } + + CGameObject *obj = (flags & MOVIE_NOTIFY_OBJECT) ? this : nullptr; + if (_surface) { + _surface->playMovie(flags, obj); + if (flags & MOVIE_GAMESTATE) + getGameManager()->_gameState.addMovie(_surface->_movie); + } +} + +void CGameObject::playMovie(int startFrame, int endFrame, uint flags) { + _frameNumber = -1; + + if (!_surface) { + if (!_resource.empty()) + loadResource(_resource); + _resource.clear(); + } + + CGameObject *obj = (flags & MOVIE_NOTIFY_OBJECT) ? this : nullptr; + if (_surface) { + _surface->playMovie(startFrame, endFrame, flags, obj); + if (flags & MOVIE_GAMESTATE) + getGameManager()->_gameState.addMovie(_surface->_movie); + } +} + + +void CGameObject::playMovie(int startFrame, int endFrame, int initialFrame, uint flags) { + _frameNumber = -1; + + if (!_surface) { + if (!_resource.empty()) + loadResource(_resource); + _resource.clear(); + } + + CGameObject *obj = (flags & MOVIE_NOTIFY_OBJECT) ? this : nullptr; + if (_surface) { + _surface->playMovie(startFrame, endFrame, initialFrame, flags, obj); + if (flags & MOVIE_GAMESTATE) + getGameManager()->_gameState.addMovie(_surface->_movie); + } +} + +void CGameObject::playClip(const CString &name, uint flags) { + _frameNumber = -1; + CMovieClip *clip = _movieClips.findByName(name); + if (clip) + playMovie(clip->_startFrame, clip->_endFrame, flags); +} + +void CGameObject::playClip(uint startFrame, uint endFrame) { + CMovieClip *clip = new CMovieClip("", startFrame, endFrame); + CGameManager *gameManager = getGameManager(); + CRoomItem *room = gameManager->getRoom(); + + gameManager->playClip(clip, room, room); +} + +void CGameObject::playRandomClip(const char **names, uint flags) { + // Count size of array + int count = 0; + for (const char **p = names; *p; ++p) + ++count; + + // Play clip + const char *name = names[g_vm->getRandomNumber(count - 1)]; + playClip(name, flags); +} + +void CGameObject::savePosition() { + _savedPos = _bounds; +} + +void CGameObject::resetPosition() { + setPosition(_savedPos); +} + +void CGameObject::setPosition(const Point &newPos) { + makeDirty(); + _bounds.moveTo(newPos); + makeDirty(); +} + +bool CGameObject::checkStartDragging(CMouseDragStartMsg *msg) { + if (_visible && checkPoint(msg->_mousePos, msg->_handled, 1)) { + savePosition(); + msg->_dragItem = this; + return true; + } else { + return false; + } +} + +bool CGameObject::hasActiveMovie() const { + if (_surface && _surface->_movie) + return _surface->_movie->isActive(); + return false; +} + +int CGameObject::getMovieFrame() const { + if (_surface && _surface->_movie) + return _surface->_movie->getFrame(); + return _initialFrame; +} + +bool CGameObject::surfaceHasFrame() const { + return _surface ? _surface->hasFrame() : false; +} + +void CGameObject::loadSound(const CString &name) { + CGameManager *gameManager = getGameManager(); + if (gameManager) { + g_vm->_filesManager->preload(name); + if (!name.empty()) + gameManager->_sound.loadSound(name); + } +} + +int CGameObject::playSound(const CString &name, int val2, int val3, int val4) { + CProximity prox; + prox._field8 = val2; + prox._fieldC = val3; + prox._field20 = val4; + return playSound(name, prox); +} + +int CGameObject::playSound(const CString &name, CProximity &prox) { + if (prox._field28 == 2) { + // TODO + } + + return 0; +} + +void CGameObject::stopSound(int handle, int val2) { + if (handle != 0 && handle != -1) { + CGameManager *gameManager = getGameManager(); + if (gameManager) { + if (val2) + gameManager->_sound.fn3(handle, 0, val2); + else + gameManager->_sound.fn2(handle); + } + } +} + +int CGameObject::addTimer(int endVal, uint firstDuration, uint repeatDuration) { + CTimeEventInfo *timer = new CTimeEventInfo(g_vm->_events->getTicksCount(), + repeatDuration != 0, firstDuration, repeatDuration, this, endVal, CString()); + + getGameManager()->addTimer(timer); + return timer->_id; +} + +int CGameObject::addTimer(uint firstDuration, uint repeatDuration) { + CTimeEventInfo *timer = new CTimeEventInfo(g_vm->_events->getTicksCount(), + repeatDuration != 0, firstDuration, repeatDuration, this, 0, CString()); + + getGameManager()->addTimer(timer); + return timer->_id; +} + +void CGameObject::stopTimer(int id) { + getGameManager()->stopTimer(id); +} + +void CGameObject::gotoView(const CString &viewName, const CString &clipName) { + CViewItem *newView = parseView(viewName); + CGameManager *gameManager = getGameManager(); + CViewItem *oldView = gameManager ? gameManager->getView() : newView; + if (!oldView || !newView) + return; + + CMovieClip *clip = nullptr; + if (clipName.empty()) { + CLinkItem *link = oldView->findLink(newView); + if (link) + clip = link->getClip(); + } else { + clip = oldView->findNode()->findRoom()->findClip(clipName); + } + + // Change the view + gameManager->_gameState.changeView(newView, clip); +} + +CViewItem *CGameObject::parseView(const CString &viewString) { + int firstIndex = viewString.indexOf('.'); + int lastIndex = viewString.lastIndexOf('.'); + CString roomName, nodeName, viewName; + + if (firstIndex == -1) { + roomName = viewString; + } else { + roomName = viewString.left(firstIndex); + + if (lastIndex > firstIndex) { + nodeName = viewString.mid(firstIndex + 1, lastIndex - firstIndex - 1); + viewName = viewString.mid(lastIndex + 1); + } else { + nodeName = viewString.mid(firstIndex + 1); + } + } + + CGameManager *gameManager = getGameManager(); + if (!gameManager) + return nullptr; + + CRoomItem *room = gameManager->getRoom(); + CProjectItem *project = room->getRoot(); + + // Ensure we have the specified room + if (project) { + if (room->getName() != roomName) { + // Scan for the correct room + for (room = project->findFirstRoom(); room && room->getName() != roomName; + room = project->findNextRoom(room)) ; + } + } + if (!room) + return nullptr; + + // Find the designated node within the room + CNodeItem *node = static_cast<CNodeItem *>(room->findChildInstanceOf(CNodeItem::_type)); + while (node && node->getName() != nodeName) + node = static_cast<CNodeItem *>(room->findNextInstanceOf(CNodeItem::_type, node)); + if (!node) + return nullptr; + + CViewItem *view = static_cast<CViewItem *>(node->findChildInstanceOf(CViewItem::_type)); + while (view && view->getName() != viewName) + view = static_cast<CViewItem *>(node->findNextInstanceOf(CViewItem::_type, view)); + if (!view) + return nullptr; + + // Find the view, so return it + return view; +} + +CString CGameObject::getViewFullName() const { + CGameManager *gameManager = getGameManager(); + CViewItem *view = gameManager->getView(); + CNodeItem *node = view->findNode(); + CRoomItem *room = node->findRoom(); + + return CString::format("%s.%s.%s", room->getName().c_str(), + node->getName().c_str(), view->getName().c_str()); +} + +void CGameObject::sleep(uint milli) { + g_vm->_events->sleep(milli); +} + +Point CGameObject::getMousePos() const { + return getGameManager()->_gameState.getMousePos(); +} + +bool CGameObject::compareViewNameTo(const CString &name) const { + return getViewFullName().compareToIgnoreCase(name); +} + +int CGameObject::compareRoomNameTo(const CString &name) { + CRoomItem *room = getGameManager()->getRoom(); + return room->getName().compareToIgnoreCase(name); +} + +CString CGameObject::getRoomName() const { + CRoomItem *room = getRoom(); + return room ? room->getName() : CString(); +} + +CString CGameObject::getRoomNodeName() const { + CNodeItem *node = getNode(); + if (!node) + return CString(); + + CRoomItem *room = node->findRoom(); + + return CString::format("%s.%s", room->getName().c_str(), node->getName().c_str()); +} + +CString CGameObject::getFullViewName() { + CGameManager *gameManager = getGameManager(); + return gameManager ? gameManager->getFullViewName() : CString(); +} + +CGameObject *CGameObject::getMailManFirstObject() const { + CMailMan *mailMan = getMailMan(); + return mailMan ? mailMan->getFirstObject() : nullptr; +} + +CGameObject *CGameObject::getMailManNextObject(CGameObject *prior) const { + CMailMan *mailMan = getMailMan(); + return mailMan ? mailMan->getNextObject(prior) : nullptr; +} + +CGameObject *CGameObject::findMailByFlags(int mode, uint roomFlags) { + CMailMan *mailMan = getMailMan(); + if (!mailMan) + return nullptr; + + for (CGameObject *obj = mailMan->getFirstObject(); obj; + obj = mailMan->getNextObject(obj)) { + if (compareRoomFlags(mode, roomFlags, obj->_roomFlags)) + return obj; + } + + return nullptr; +} + +CGameObject *CGameObject::getNextMail(CGameObject *prior) { + CMailMan *mailMan = getMailMan(); + return mailMan ? mailMan->getNextObject(prior) : nullptr; +} + +CGameObject *CGameObject::findRoomObject(const CString &name) const { + return static_cast<CGameObject *>(findRoom()->findByName(name)); +} + +CGameObject *CGameObject::findInRoom(const CString &name) { + CRoomItem *room = getRoom(); + return room ? static_cast<CGameObject *>(room->findByName(name)) : nullptr; +} + +Found CGameObject::find(const CString &name, CGameObject **item, int findAreas) { + CGameObject *go; + *item = nullptr; + + // Scan under PET if flagged + if (findAreas & FIND_PET) { + for (go = getPetControl()->getFirstObject(); go; go = getPetControl()->getNextObject(go)) { + if (go->getName() == name) { + *item = go; + return FOUND_PET; + } + } + } + + if (findAreas & FIND_MAILMAN) { + for (go = getMailManFirstObject(); go; go = getMailManNextObject(go)) { + if (go->getName() == name) { + *item = go; + return FOUND_MAILMAN; + } + } + } + + if (findAreas & FIND_GLOBAL) { + go = static_cast<CGameObject *>(getRoot()->findByName(name)); + if (go) { + *item = go; + return FOUND_GLOBAL; + } + } + + if (findAreas & FIND_ROOM) { + go = findRoomObject(name); + if (go) { + *item = go; + return FOUND_ROOM; + } + } + + return FOUND_NONE; +} + +void CGameObject::moveToView() { + CViewItem *view = getGameManager()->getView(); + detach(); + view->addUnder(this); +} + +void CGameObject::moveToView(const CString &name) { + CViewItem *view = parseView(name); + detach(); + view->addUnder(this); +} + +void CGameObject::stateInc14() { + getGameManager()->_gameState.inc14(); +} + +int CGameObject::stateGet14() const { + return getGameManager()->_gameState._field14; +} + +void CGameObject::stateSet24() { + getGameManager()->_gameState.set24(1); +} + +int CGameObject::stateGet24() const { + return getGameManager()->_gameState.get24(); +} + +void CGameObject::stateInc38() { + getGameManager()->_gameState.inc38(); +} + +int CGameObject::stateGet38() const { + return getGameManager()->_gameState._field38; +} + +void CGameObject::quitGame() { + getGameManager()->_gameState._quitGame = true; +} + +void CGameObject::inc54() { + getGameManager()->inc54(); +} + +void CGameObject::dec54() { + getGameManager()->dec54(); +} + +void CGameObject::setMovieFrameRate(double rate) { + if (_surface) + _surface->setMovieFrameRate(rate); +} + +void CGameObject::setTextBorder(const CString &str, int border, int borderRight) { + if (!_text) + _text = new CPetText(); + _textBorder = border; + _textBorderRight = borderRight; + + _text->setText(str); + CScreenManager *screenManager = getGameManager()->setScreenManager(); + _text->scrollToTop(screenManager); +} + +void CGameObject::setTextHasBorders(bool hasBorders) { + if (!_text) + _text = new CPetText(); + + _text->setHasBorder(hasBorders); +} + +void CGameObject::setTextBounds() { + Rect rect = _bounds; + rect.grow(_textBorder); + rect.right -= _textBorderRight; + + _text->setBounds(rect); + makeDirty(); +} + +void CGameObject::setTextColor(byte r, byte g, byte b) { + if (!_text) + _text = new CPetText(); + + _text->setColor(r, g, b); +} + +void CGameObject::setTextFontNumber(int fontNumber) { + if (!_text) + _text = new CPetText(); + + _text->setFontNumber(fontNumber); +} + +int CGameObject::getTextWidth() const { + assert(_text); + return _text->getTextWidth(CScreenManager::_screenManagerPtr); +} + +CTextCursor *CGameObject::getTextCursor() const { + return CScreenManager::_screenManagerPtr->_textCursor; +} + +void CGameObject::scrollTextUp() { + if (_text) + _text->scrollUp(CScreenManager::_screenManagerPtr); +} + +void CGameObject::scrollTextDown() { + if (_text) + _text->scrollDown(CScreenManager::_screenManagerPtr); +} + +void CGameObject::lockMouse() { + CGameManager *gameMan = getGameManager(); + gameMan->lockInputHandler(); + + if (CScreenManager::_screenManagerPtr->_mouseCursor) + CScreenManager::_screenManagerPtr->_mouseCursor->hide(); +} + +void CGameObject::hideMouse() { + CScreenManager::_screenManagerPtr->_mouseCursor->hide(); +} + +void CGameObject::showMouse() { + CScreenManager::_screenManagerPtr->_mouseCursor->show(); +} + +void CGameObject::disableMouse() { + lockInputHandler(); + hideMouse(); +} + +void CGameObject::enableMouse() { + unlockInputHandler(); + showMouse(); +} + +void CGameObject::mouseLockE4() { + CScreenManager::_screenManagerPtr->_mouseCursor->lockE4(); +} + +void CGameObject::mouseUnlockE4() { + CScreenManager::_screenManagerPtr->_mouseCursor->unlockE4(); +} + +void CGameObject::mouseSaveState(int v1, int v2, int v3) { + CScreenManager::_screenManagerPtr->_mouseCursor->saveState(v1, v2, v3); +} + +void CGameObject::lockInputHandler() { + getGameManager()->lockInputHandler(); +} + +void CGameObject::unlockInputHandler() { + getGameManager()->unlockInputHandler(); +} + +void CGameObject::unlockMouse() { + if (CScreenManager::_screenManagerPtr->_mouseCursor) + CScreenManager::_screenManagerPtr->_mouseCursor->show(); + + CGameManager *gameMan = getGameManager(); + gameMan->unlockInputHandler(); +} + +void CGameObject::loadSurface() { + if (!_surface && !_resource.empty()) { + loadResource(_resource); + _resource.clear(); + } + + if (_surface) + _surface->loadIfReady(); +} + +bool CGameObject::changeView(const CString &viewName, const CString &clipName) { + CViewItem *newView = parseView(viewName); + CGameManager *gameManager = getGameManager(); + CViewItem *oldView = gameManager->getView(); + + if (!oldView || !newView) + return false; + + CMovieClip *clip = nullptr; + if (!clipName.empty()) { + clip = oldView->findNode()->findRoom()->findClip(clipName); + } else { + CLinkItem *link = oldView->findLink(newView); + if (link) + clip = link->getClip(); + } + + gameManager->_gameState.changeView(newView, clip); + return true; +} + +void CGameObject::dragMove(const Point &pt) { + if (_surface) { + _bounds.setWidth(_surface->getWidth()); + _bounds.setHeight(_surface->getHeight()); + } + + setPosition(Point(pt.x - _bounds.width() / 2, pt.y - _bounds.height() / 2)); +} + +bool CGameObject::isObjectDragging() const { + CTreeItem *item = getGameManager()->_dragItem; + return item ? static_cast<CGameObject *>(item) != nullptr : false; +} + +Point CGameObject::getControid() const { + return Point(_bounds.left + _bounds.width() / 2, + _bounds.top + _bounds.height() / 2); +} + +bool CGameObject::clipExistsByStart(const CString &name, int startFrame) const { + return _movieClips.existsByStart(name, startFrame); +} + +bool CGameObject::clipExistsByEnd(const CString &name, int endFrame) const { + return _movieClips.existsByEnd(name, endFrame); +} + +void CGameObject::petClear() const { + CPetControl *petControl = getPetControl(); + if (petControl) + petControl->resetActiveNPC(); +} + +CDontSaveFileItem *CGameObject::getDontSave() const { + CProjectItem *project = getRoot(); + return project ? project->getDontSaveFileItem() : nullptr; +} + +CPetControl *CGameObject::getPetControl() const { + return static_cast<CPetControl *>(getDontSaveChild(CPetControl::_type)); +} + +CMailMan *CGameObject::getMailMan() const { + return dynamic_cast<CMailMan *>(getDontSaveChild(CMailMan::_type)); +} + +CTreeItem *CGameObject::getDontSaveChild(ClassDef *classDef) const { + CProjectItem *root = getRoot(); + if (!root) + return nullptr; + + CDontSaveFileItem *dontSave = root->getDontSaveFileItem(); + if (!dontSave) + return nullptr; + + return dontSave->findChildInstanceOf(classDef); +} + +CRoomItem *CGameObject::getHiddenRoom() const { + CProjectItem *root = getRoot(); + return root ? root->findHiddenRoom() : nullptr; +} + +CGameObject *CGameObject::getHiddenObject(const CString &name) const { + CRoomItem *room = getHiddenRoom(); + return room ? static_cast<CGameObject *>(findUnder(room, name)) : nullptr; +} + +CTreeItem *CGameObject::findUnder(CTreeItem *parent, const CString &name) const { + if (!parent) + return nullptr; + + for (CTreeItem *item = parent->getFirstChild(); item; item = item->scan(parent)) { + if (item->getName() == name) + return item; + } + + return nullptr; +} + +CRoomItem *CGameObject::findRoomByName(const CString &name) { + CProjectItem *project = getRoot(); + for (CRoomItem *room = project->findFirstRoom(); room; room = project->findNextRoom(room)) { + if (!room->getName().compareToIgnoreCase(name)) + return room; + } + + return nullptr; +} + +CMusicRoom *CGameObject::getMusicRoom() const { + CGameManager *gameManager = getGameManager(); + return gameManager ? &gameManager->_musicRoom : nullptr; +} + +int CGameObject::getPassengerClass() const { + CGameManager *gameManager = getGameManager(); + return gameManager ? gameManager->_gameState._passengerClass : 3; +} + +int CGameObject::getPriorClass() const { + CGameManager *gameManager = getGameManager(); + return gameManager ? gameManager->_gameState._priorClass : 3; +} + +void CGameObject::setPassengerClass(int newClass) { + if (newClass >= 1 && newClass <= 4) { + // Change the passenger class + CGameManager *gameMan = getGameManager(); + gameMan->_gameState._priorClass = gameMan->_gameState._passengerClass; + gameMan->_gameState._passengerClass = newClass; + + // Setup the PET again, so the new class's PET background can take effect + CPetControl *petControl = getPetControl(); + if (petControl) + petControl->setup(); + } +} + +void CGameObject::createCredits() { + _credits = new CCreditText(); + CScreenManager *screenManager = getGameManager()->setScreenManager(); + _credits->load(this, screenManager, _bounds); +} + +void CGameObject::fn10(int v1, int v2, int v3) { + makeDirty(); + _field44 = v1; + _field48 = v2; + _field4C = v3; +} + +void CGameObject::setMovie14(int v) { + if (!_surface && !_resource.empty()) { + loadResource(_resource); + _resource.clear(); + } + + if (_surface && _surface->_movie) + _surface->_movie->_field14 = v; +} + +void CGameObject::movieEvent(int frameNumber) { + if (_surface) + _surface->addMovieEvent(frameNumber, this); +} + +void CGameObject::movieEvent() { + if (_surface) + _surface->addMovieEvent(-1, this); +} + +int CGameObject::getClipDuration(const CString &name, int frameRate) const { + CMovieClip *clip = _movieClips.findByName(name); + return clip ? (clip->_endFrame - clip->_startFrame) * 1000 / frameRate : 0; +} + +uint32 CGameObject::getTickCount() { + return g_vm->_events->getTicksCount(); +} + +bool CGameObject::compareRoomFlags(int mode, uint flags1, uint flags2) { + switch (mode) { + case 1: + return CRoomFlags::compareLocation(flags1, flags2); + + case 2: + return CRoomFlags::compareClassElevator(flags1, flags2); + + case 3: + return CRoomFlags::isTitania(flags1, flags2); + + default: + return false; + } +} + +void CGameObject::setState1C(bool flag) { + getGameManager()->_gameState._field1C = flag; +} + +void CGameObject::addMail(int mailId) { + CMailMan *mailMan = getMailMan(); + if (mailMan) { + makeDirty(); + mailMan->addMail(this, mailId); + } +} + +void CGameObject::setMailId(int mailId) { + CMailMan *mailMan = getMailMan(); + if (mailMan) { + makeDirty(); + mailMan->setMailId(this, mailId); + } +} + +bool CGameObject::mailExists(int id) const { + return findMail(id) != nullptr; +} + +CGameObject *CGameObject::findMail(int id) const { + CMailMan *mailMan = getMailMan(); + return mailMan ? mailMan->findMail(id) : nullptr; +} + +void CGameObject::removeMail(int id, int v) { + CMailMan *mailMan = getMailMan(); + if (mailMan) + mailMan->removeMail(id, v); +} + +void CGameObject::resetMail() { + CMailMan *mailMan = getMailMan(); + if (mailMan) + mailMan->resetValue(); +} + +/*------------------------------------------------------------------------*/ + +CRoomItem *CGameObject::getRoom() const { + CGameManager *gameManager = getGameManager(); + return gameManager ? gameManager->getRoom() : nullptr; +} + +CNodeItem *CGameObject::getNode() const { + CGameManager *gameManager = getGameManager(); + return gameManager ? gameManager->getNode() : nullptr; +} + +CViewItem *CGameObject::getView() const { + CGameManager *gameManager = getGameManager(); + return gameManager ? gameManager->getView() : nullptr; +} + +/*------------------------------------------------------------------------*/ + +void CGameObject::petAddToCarryParcel(CGameObject *obj) { + CPetControl *pet = getPetControl(); + if (pet) { + CGameObject *parcel = pet->getHiddenObject("CarryParcel"); + if (parcel) + parcel->moveUnder(obj); + } +} + +void CGameObject::petAddToInventory() { + CPetControl *pet = getPetControl(); + if (pet) { + makeDirty(); + pet->addToInventory(this); + } +} + +CTreeItem *CGameObject::petContainerRemove(CGameObject *obj) { + CPetControl *pet = getPetControl(); + if (!obj || !pet) + return nullptr; + if (!obj->compareRoomNameTo("CarryParcel")) + return obj; + + CGameObject *item = static_cast<CGameObject *>(pet->getLastChild()); + if (item) + item->detach(); + + pet->moveToHiddenRoom(obj); + pet->removeFromInventory(item, false, false); + + return item; +} + +bool CGameObject::petDismissBot(const CString &name) { + CPetControl *pet = getPetControl(); + return pet ? pet->dismissBot(name) : false; +} + +bool CGameObject::petDoorOrBellbotPresent() const { + CPetControl *pet = getPetControl(); + return pet ? pet->isDoorOrBellbotPresent() : false; +} + +void CGameObject::petDisplayMessage(int unused, const CString &msg) { + petDisplayMessage(msg); +} + +void CGameObject::petDisplayMessage(const CString &msg) { + CPetControl *pet = getPetControl(); + if (pet) + pet->displayMessage(msg); +} + +int CGameObject::petGetRooms1D0() const { + CPetControl *petControl = getPetControl(); + return petControl ? petControl->getRooms1D0() : 0; +} + +void CGameObject::petInvChange() { + CPetControl *pet = getPetControl(); + if (pet) + pet->invChange(this); +} + +void CGameObject::petLockInput() { + getPetControl()->incInputLocks(); +} + +void CGameObject::petMoveToHiddenRoom() { + CPetControl *pet = getPetControl(); + if (pet) { + makeDirty(); + pet->moveToHiddenRoom(this); + } +} + +void CGameObject::petReassignRoom(int passClassNum) { + CPetControl *petControl = getPetControl(); + if (petControl) + petControl->reassignRoom(passClassNum); +} + +void CGameObject::petSetArea(PetArea newArea) const { + CPetControl *pet = getPetControl(); + if (pet) + pet->setArea(newArea); +} + +void CGameObject::petSetRooms1D0(int val) { + CPetControl *petControl = getPetControl(); + if (petControl) + petControl->setRooms1D0(val); +} + +void CGameObject::petSetRooms1D4(int v) { + CPetControl *pet = getPetControl(); + if (pet) + pet->setRooms1D4(v); +} + +void CGameObject::petOnSummonBot(const CString &name, int val) { + CPetControl *pet = getPetControl(); + if (pet) + pet->summonBot(name, val); +} + +void CGameObject::petUnlockInput() { + getPetControl()->decInputLocks(); +} + +/*------------------------------------------------------------------------*/ + +CStarControl *CGameObject::getStarControl() const { + CStarControl *starControl = static_cast<CStarControl *>(getDontSaveChild(CStarControl::_type)); + if (!starControl) { + CViewItem *view = getGameManager()->getView(); + if (view) + starControl = static_cast<CStarControl *>(view->findChildInstanceOf(CStarControl::_type)); + } + + return starControl; +} + +void CGameObject::starFn1(int v) { + CStarControl *starControl = getStarControl(); + if (starControl) + starControl->fn1(v); +} + +void CGameObject::starFn2() { + CStarControl *starControl = getStarControl(); + if (starControl) + starControl->fn4(); +} + +/*------------------------------------------------------------------------*/ + +void CGameObject::startTalking(const CString &npcName, uint id, CViewItem *view) { + CTrueTalkNPC *npc = static_cast<CTrueTalkNPC *>(getRoot()->findByName(npcName)); + startTalking(npc, id, view); +} + +void CGameObject::startTalking(CTrueTalkNPC *npc, uint id, CViewItem *view) { + CGameManager *gameManager = getGameManager(); + if (gameManager) { + CTrueTalkManager *talkManager = gameManager->getTalkManager(); + if (talkManager) + talkManager->start(npc, id, view); + } +} + +void CGameObject::endTalking(CTrueTalkNPC *npc, bool viewFlag, CViewItem *view) { + CPetControl *pet = getPetControl(); + if (pet) + pet->setActiveNPC(npc); + + if (viewFlag) + npc->setView(view); + + if (pet) + pet->refreshNPC(); +} + +void CGameObject::talkSetDialRegion(const CString &name, int dialNum, int regionNum) { + CGameManager *gameManager = getGameManager(); + if (gameManager) { + CTrueTalkManager *talkManager = gameManager->getTalkManager(); + if (talkManager) { + TTnpcScript *npcScript = talkManager->getTalker(name); + if (npcScript) + npcScript->setDialRegion(dialNum, regionNum); + } + } +} + +int CGameObject::talkGetDIalRegion(const CString &name, int dialNum) { + CGameManager *gameManager = getGameManager(); + if (gameManager) { + CTrueTalkManager *talkManager = gameManager->getTalkManager(); + if (talkManager) { + TTnpcScript *npcScript = talkManager->getTalker(name); + if (npcScript) + return npcScript->getDialRegion(dialNum); + } + } + + return 0; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/game_object.h b/engines/titanic/core/game_object.h new file mode 100644 index 0000000000..69036b1690 --- /dev/null +++ b/engines/titanic/core/game_object.h @@ -0,0 +1,861 @@ +/* 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. + * + */ + +#ifndef TITANIC_GAME_OBJECT_H +#define TITANIC_GAME_OBJECT_H + +#include "titanic/support/mouse_cursor.h" +#include "titanic/support/credit_text.h" +#include "titanic/support/movie_range_info.h" +#include "titanic/support/proximity.h" +#include "titanic/support/rect.h" +#include "titanic/support/movie_clip.h" +#include "titanic/core/named_item.h" +#include "titanic/pet_control/pet_section.h" +#include "titanic/pet_control/pet_text.h" + +namespace Titanic { + +enum Find { FIND_GLOBAL = 1, FIND_ROOM = 2, FIND_PET = 4, FIND_MAILMAN = 8 }; +enum Found { FOUND_NONE = 0, FOUND_GLOBAL = 1, FOUND_ROOM = 2, FOUND_PET = 3, FOUND_MAILMAN = 4 }; + +class CDontSaveFileItem; +class CMailMan; +class CMusicRoom; +class CRoomItem; +class CStarControl; +class CMouseDragStartMsg; +class CTrueTalkNPC; +class CVideoSurface; +class OSMovie; + +class CGameObject : public CNamedItem { + friend class OSMovie; + DECLARE_MESSAGE_MAP; +private: + static CCreditText *_credits; +private: + /** + * Load a visual resource for the object + */ + void loadResource(const CString &name); + + /** + * Loads a movie + */ + void loadMovie(const CString &name, bool pendingFlag = true); + + /** + * Loads an image + */ + void loadImage(const CString &name, bool pendingFlag = true); + + /** + * Process and remove any registered movie range info + */ + void processMoveRangeInfo(); + + /** + * Merges one rect into another, and returns true if there was + * a common intersection + */ + bool clipRect(const Rect &rect1, Rect &rect2) const; +protected: + Rect _bounds; + double _field34; + double _field38; + double _field3C; + int _field40; + int _field44; + int _field48; + int _field4C; + CMovieClipList _movieClips; + int _initialFrame; + CMovieRangeInfoList _movieRangeInfoList; + int _frameNumber; + CPetText *_text; + uint _textBorder; + uint _textBorderRight; + int _field9C; + Common::Point _savedPos; + CVideoSurface *_surface; + CString _resource; + int _fieldB8; +protected: + /** + * Saves the current position the object is located at + */ + void savePosition(); + + /** + * Resets the object back to the previously saved starting position + */ + void resetPosition(); + + /** + * Check for starting to drag the object + */ + bool checkStartDragging(CMouseDragStartMsg *msg); + + /** + * Goto a new view + */ + void gotoView(const CString &viewName, const CString &clipName); + + /** + * Parses a view into it's components of room, node, and view, + * and locates the designated view + */ + CViewItem * parseView(const CString &viewString); + + void inc54(); + void dec54(); + + /** + * Locks/hides the mouse + */ + void lockMouse(); + + /** + * Unlocks/shows the mouse + */ + void unlockMouse(); + + /** + * Hides the mouse cursor + */ + void hideMouse(); + + /** + * Shows the mouse cursor + */ + void showMouse(); + + /** + * Disable the mouse + */ + void disableMouse(); + + /** + * Enable the mouse + */ + void enableMouse(); + + void mouseLockE4(); + void mouseUnlockE4(); + + void mouseSaveState(int v1, int v2, int v3); + + /** + * Lock the input handler + */ + void lockInputHandler(); + + /** + * Unlock the input handler + */ + void unlockInputHandler(); + + /** + * Load a sound + */ + void loadSound(const CString &name); + + /** + * Plays a sound + */ + int playSound(const CString &name, int val2 = 100, int val3 = 0, int val4 = 0); + + /** + * Plays a sound + */ + int playSound(const CString &name, CProximity &prox); + + /** + * Stop a sound + */ + void stopSound(int handle, int val2 = 0); + + bool soundFn1(int handle); + + void soundFn2(const CString &resName, int v1, int v2, int v3, int handleIndex); + + void soundFn3(int handle, int val2, int val3); + + void soundFn4(int v1, int v2, int v3); + + void soundFn5(int v1, int v2, int v3); + + void sound8(bool flag) const; + + /** + * Adds a timer + */ + int addTimer(int endVal, uint firstDuration, uint repeatDuration); + + /** + * Adds a timer + */ + int addTimer(uint firstDuration, uint repeatDuration); + + /** + * Stops a timer + */ + void stopTimer(int id); + + /** + * Causes the game to sleep for the specified time + */ + void sleep(uint milli); + + /** + * Get the current mouse cursor position + */ + Point getMousePos() const; + + /* + * Compares the current view's name in a Room.Node.View tuplet + * string form to the passed string + */ + bool compareViewNameTo(const CString &name) const; + + /** + * Compare the name of the parent room to the item to a passed string + */ + int compareRoomNameTo(const CString &name); + + /** + * Gets the first object under the system MailMan + */ + CGameObject *getMailManFirstObject() const; + + /** + * Gets the next object under the system MailMan + */ + CGameObject *getMailManNextObject(CGameObject *prior) const; + + /** + * Find mail by room flags + */ + CGameObject *findMailByFlags(int mode, uint roomFlags); + + /** + * Find next mail from a given prior one + */ + CGameObject *getNextMail(CGameObject *prior); + + /** + * Finds an object by name within the object's room + */ + CGameObject *findRoomObject(const CString &name) const; + + /** + * FInds an object under the current room + */ + CGameObject *findInRoom(const CString &name); + + /** + * Moves the object to be under the current view + */ + void moveToView(); + + /** + * Moves the object to be under the specified view + */ + void moveToView(const CString &name); + + /** + * Change the view + */ + bool changeView(const CString &viewName, const CString &clipName); + + /** + * Get the centre of the game object's bounds + */ + Point getControid() const; + + /** + * Play an arbitrary clip + */ + void playClip(const CString &name, uint flags); + + /** + * Play a clip + */ + void playClip(uint startFrame, uint endFrame); + + /** + * Play a clip randomly from a passed list of names + */ + void playRandomClip(const char **names, uint flags); + + /** + * Return the current view/node/room as a single string + */ + CString getViewFullName() const; + + /** + * Returns true if a clip exists in the list with a given name + * and starting frame number + */ + bool clipExistsByStart(const CString &name, int startFrame = 0) const; + + /** + * Returns true if a clip exists in the list with a given name + * and ending frame number + */ + bool clipExistsByEnd(const CString &name, int endFrame = 0) const; + + /** + * Clear the PET display + */ + void petClear() const; + + /** + * Returns the MailMan + */ + CMailMan *getMailMan() const; + + /** + * Gets the don't save container object + */ + CDontSaveFileItem *getDontSave() const; + + /** + * Returns a child of the Dont Save area of the project of the given class + */ + CTreeItem *getDontSaveChild(ClassDef *classDef) const; + + /** + * Returns the special hidden room container + */ + CRoomItem *getHiddenRoom() const; + + /** + * Scan the specified room for an item by name + */ + CTreeItem *findUnder(CTreeItem *parent, const CString &name) const; + + /** + * Finds a room by name + */ + CRoomItem *findRoomByName(const CString &name); + + /** + * Returns the music room instance from the game manager + */ + CMusicRoom *getMusicRoom() const; + + /** + * Set's the player's passenger class + */ + void setPassengerClass(int newClass); + + void setMovie14(int v); + + void fn10(int v1, int v2, int v3); + + /** + * Gets the duration of a specified clip in milliseconds + */ + int getClipDuration(const CString &name, int frameRate = 14) const; + + /** + * Returns the current system tick count + */ + uint32 getTickCount(); + + /** + * Adds an object to the mail list + */ + void addMail(int mailId); + + /** + * Sets the mail identifier for an object + */ + void setMailId(int mailId); + + /** + * Returns true if a mail with a specified Id exists + */ + bool mailExists(int id) const; + + /** + * Returns a specified mail, if one exists + */ + CGameObject *findMail(int id) const; + + /** + * Remove an object from the mail list + */ + void removeMail(int id, int v); + + /** + * Resets the Mail Man value + */ + void resetMail(); + + /** + * Locks the PET, disabling all input. Can be called multiple times + */ + void petLockInput(); + + /** + * Unlocks PET input + */ + void petUnlockInput(); + + void setState1C(bool flag); + void stateInc14(); + int stateGet14() const; + void stateSet24(); + int stateGet24() const; + void stateInc38(); + int stateGet38() const; + + /** + * Flag to quit the game + */ + void quitGame(); + + /** + * Set the frame rate for the currently loaded movie + */ + void setMovieFrameRate(double rate); + + /** + * Set up the text borders for the object + */ + void setTextBorder(const CString &str, int border = 0, int borderRight = 0); + + /** + * Sets whether the text will use borders + */ + void setTextHasBorders(bool hasBorders); + + /** + * Sets the bounds for a previously defined text area + */ + void setTextBounds(); + + /** + * Sets the color for the object's text + */ + void setTextColor(byte r, byte g, byte b); + + /** + * Sets the font number to use for text + */ + void setTextFontNumber(int fontNumber); + + /** + * Gets the width of the text contents + */ + int getTextWidth() const; + + /** + * Returns the text cursor + */ + CTextCursor *getTextCursor() const; + + /** + * Scroll text up + */ + void scrollTextUp(); + + /** + * Scroll text down + */ + void scrollTextDown(); +public: + bool _isMail; + int _id; + uint _roomFlags; + int _field60; + CursorId _cursorId; + bool _visible; +public: + /** + * Initializes statics + */ + static void init(); + + /** + * Deinitializes statics + */ + static void deinit(); +public: + CLASSDEF; + CGameObject(); + ~CGameObject(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Returns the clip list, if any, associated with the item + */ + virtual const CMovieClipList *getMovieClips() const { return &_movieClips; } + + /** + * Allows the item to draw itself + */ + virtual void draw(CScreenManager *screenManager); + + /** + * Gets the bounds occupied by the item + */ + virtual Rect getBounds() const; + + /** + * Called when the view changes + */ + virtual void viewChange(); + + /** + * Allows the item to draw itself + */ + void draw(CScreenManager *screenManager, const Rect &destRect, const Rect &srcRect); + + /** + * Allows the item to draw itself + */ + void draw(CScreenManager *screenManager, const Point &destPos); + + /** + * Allows the item to draw itself + */ + void draw(CScreenManager *screenManager, const Point &destPos, const Rect &srcRect); + + /** + * Returns true if the item is the PET control + */ + virtual bool isPet() const; + + /** + * Checks the passed point is validly in the object, + * with extra checking of object flags status + */ + bool checkPoint(const Point &pt, bool ignore40 = false, bool visibleOnly = false); + + /** + * Set the position of the object + */ + void setPosition(const Point &newPos); + + /** + * Change the object's status + */ + void playMovie(uint flags); + + /** + * Play the movie specified in _resource + */ + void playMovie(int startFrame, int endFrame, uint flags); + + /** + * Play the movie specified in _resource + */ + void playMovie(int startFrame, int endFrame, int initialFrame, uint flags); + + /** + * Returns true if the object has a currently active movie + */ + bool hasActiveMovie() const; + + /** + * Stops any movie currently playing for the object + */ + void stopMovie(); + + /** + * Get the current movie frame + */ + int getMovieFrame() const; + + /** + * Returns the object's frame number + */ + int getFrameNumber() const { return _frameNumber; } + + /** + * Loads a frame + */ + void loadFrame(int frameNumber); + + /** + * Load the surface + */ + void loadSurface(); + + /** + * Marks the area occupied by the object as dirty, requiring re-rendering + */ + void makeDirty(); + + /** + * Marks the area in the passed rect as dirty, and requiring re-rendering + */ + void makeDirty(const Rect &r); + + /** + * Sets whether the object is visible + */ + void setVisible(bool val); + + /** + * Return the player's passenger class + */ + int getPassengerClass() const; + + /** + * Return the player's previous passenger class + */ + int getPriorClass() const; + + /** + * Returns true if there's an attached surface which has a frame + * ready for display + */ + bool surfaceHasFrame() const; + + /** + * Finds an item in various system areas + */ + Found find(const CString &name, CGameObject **item, int findAreas); + + /** + * Returns a hidden object + */ + CGameObject *getHiddenObject(const CString &name) const; + + /** + * Sets up credits text + */ + void createCredits(); + + /** + * Support function for drag moving + */ + void dragMove(const Point &pt); + + /** + * Returns true if an item being dragged is a game object + */ + bool isObjectDragging() const; + + bool compareRoomFlags(int mode, uint flags1, uint flags2); + + /*--- CGameManager Methods ---*/ + + /** + * Return the current room + */ + CRoomItem *getRoom() const; + + /** + * Return the current node + */ + CNodeItem *getNode() const; + + /** + * Return the current room + */ + CViewItem *getView() const; + + /** + * Get the current room name + */ + CString getRoomName() const; + + /** + * Get the current node and room in the form "room.node" + */ + CString getRoomNodeName() const; + + /** + * Return the full Id of the current view in a + * room.node.view tuplet form + */ + CString getFullViewName(); + + /*--- CPetControl Methods ---*/ + + /** + * Returns the PET control + */ + CPetControl *getPetControl() const; + + /** + * Moves a specified item to the carry parcel + */ + void petAddToCarryParcel(CGameObject *obj); + + /** + * Add the item to the inventory + */ + void petAddToInventory(); + + CTreeItem *petContainerRemove(CGameObject *obj); + + /** + * Dismiss a bot + */ + bool petDismissBot(const CString &name); + + /** + * Is Doorbot or Bellbot present in the current view + */ + bool petDoorOrBellbotPresent() const; + + /** + * Display a message in the PET + */ + void petDisplayMessage(int unused, const CString &msg); + + /** + * Display a message in the PET + */ + void petDisplayMessage(const CString &msg); + + int petGetRooms1D0() const; + + /** + * Hide the PET + */ + void petHide(); + + /** + * Hides the text cursor in the current section, if applicable + */ + void petHideCursor(); + + /** + * Highlights a glyph in the currently active PET section + */ + void petHighlightGlyph(int id); + + /** + * Called when the status of an item in the inventory has changed + */ + void petInvChange(); + + /** + * Moves the item from it's original position to be under the hidden room + */ + void petMoveToHiddenRoom(); + + /** + * Gives the player a new assigned room in the specified passenger class + */ + void petReassignRoom(int passClassNum); + + /** + * Sets a new area in the PET + */ + void petSetArea(PetArea newArea) const; + + /** + * Set the remote target in the PET to this object + */ + void petSetRemoteTarget(); + + void petSetRooms1D0(int val); + void petSetRooms1D4(int v); + + + /** + * Show the PET + */ + void petShow(); + + /** + * Shows the text cursor in the current section, if applicable + */ + void petShowCursor(); + + /** + * Summon a bot + */ + void petOnSummonBot(const CString &name, int val); + + /*--- CStarControl Methods ---*/ + + /** + * Returns the star control + */ + CStarControl *getStarControl() const; + + void starFn1(int v); + void starFn2(); + + /*--- CTrueTalkManager Methods ---*/ + + /** + * Stop a conversation with the NPC + */ + void endTalking(CTrueTalkNPC *npc, bool viewFlag, CViewItem *view = nullptr); + + /** + * Start a conversation with the NPC + */ + void startTalking(CTrueTalkNPC *npc, uint id, CViewItem *view = nullptr); + + /** + * Start a conversation with the NPC + */ + void startTalking(const CString &name, uint id, CViewItem *view = nullptr); + + /** + * Sets a dial region for a given NPC + */ + void talkSetDialRegion(const CString &name, int dialNum, int regionNum); + + /** + * Gets a dial region for a given NPC + */ + int talkGetDIalRegion(const CString &name, int dialNum); + + /*--- CVideoSurface Methods ---*/ + + /** + * Signal a movie event for the given frame + */ + void movieEvent(int frameNumber); + + /** + * Signal a movie event at the end of all currently + * playing ranges + */ + void movieEvent(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GAME_OBJECT_H */ diff --git a/engines/titanic/core/game_object_desc_item.cpp b/engines/titanic/core/game_object_desc_item.cpp new file mode 100644 index 0000000000..409334c9d7 --- /dev/null +++ b/engines/titanic/core/game_object_desc_item.cpp @@ -0,0 +1,57 @@ +/* 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/core/game_object_desc_item.h" + +namespace Titanic { + +CGameObjectDescItem::CGameObjectDescItem(): CTreeItem() { +} + +void CGameObjectDescItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + _clipList.save(file, indent); + file->writeQuotedLine(_string1, indent); + file->writeQuotedLine(_string2, indent); + _list1.save(file, indent); + _list2.save(file, indent); + + CTreeItem::save(file, indent); +} + +void CGameObjectDescItem::load(SimpleFile *file) { + int val = file->readNumber(); + + if (val != 1) { + if (val) + _clipList.load(file); + + _string1 = file->readString(); + _string2 = file->readString(); + _list1.load(file); + _list1.load(file); + } + + CTreeItem::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/game_object_desc_item.h b/engines/titanic/core/game_object_desc_item.h new file mode 100644 index 0000000000..7bfecaf5a2 --- /dev/null +++ b/engines/titanic/core/game_object_desc_item.h @@ -0,0 +1,56 @@ +/* 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. + * + */ + +#ifndef TITANIC_GAME_OBJECT_DESK_ITEM_H +#define TITANIC_GAME_OBJECT_DESK_ITEM_H + +#include "titanic/support/movie_clip.h" +#include "titanic/core/tree_item.h" +#include "titanic/core/list.h" + +namespace Titanic { + +class CGameObjectDescItem : public CTreeItem { +protected: + CString _string1; + CString _string2; + List<ListItem> _list1; + List<ListItem> _list2; + CMovieClipList _clipList; +public: + CLASSDEF; + CGameObjectDescItem(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_GAME_OBJECT_DESK_ITEM_H */ diff --git a/engines/titanic/core/link_item.cpp b/engines/titanic/core/link_item.cpp new file mode 100644 index 0000000000..f77d081c61 --- /dev/null +++ b/engines/titanic/core/link_item.cpp @@ -0,0 +1,176 @@ +/* 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/core/link_item.h" +#include "titanic/core/node_item.h" +#include "titanic/core/project_item.h" +#include "titanic/core/view_item.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CLinkItem, CNamedItem); + +CLinkItem::CLinkItem() : CNamedItem() { + _roomNumber = -1; + _nodeNumber = -1; + _viewNumber = -1; + _linkMode = 0; + _cursorId = CURSOR_ARROW; + _name = "Link"; +} + +CString CLinkItem::formName() { + CViewItem *view = findView(); + CNodeItem *node = view->findNode(); + CRoomItem *room = node->findRoom(); + + CViewItem *destView = getDestView(); + CNodeItem *destNode = destView->findNode(); + CRoomItem *destRoom = destNode->findRoom(); + + switch (_linkMode) { + case 1: + return CString::format("_PANL,%d,%s,%s", node->_nodeNumber, + view->getName().c_str(), destView->getName().c_str()); + + case 2: + return CString::format("_PANR,%d,%s,%s", node->_nodeNumber, + view->getName().c_str(), destView->getName().c_str()); + + case 3: + return CString::format("_TRACK,%d,%s,%d,%s", + node->_nodeNumber, view->getName().c_str(), + destNode->_nodeNumber, destView->getName().c_str()); + + case 4: + return CString::format("_EXIT,%d,%d,%s,%d,%d,%s", + room->_roomNumber, node->_nodeNumber, view->getName().c_str(), + destRoom->_roomNumber, destNode->_nodeNumber, destView->getName().c_str()); + + default: + return getName().c_str(); + } +} + +void CLinkItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(2, indent); + file->writeQuotedLine("L", indent); + file->writeNumberLine(_cursorId, indent + 1); + file->writeNumberLine(_linkMode, indent + 1); + file->writeNumberLine(_roomNumber, indent + 1); + file->writeNumberLine(_nodeNumber, indent + 1); + file->writeNumberLine(_viewNumber, indent + 1); + + file->writeQuotedLine("Hotspot", indent + 1); + file->writeNumberLine(_bounds.left, indent + 2); + file->writeNumberLine(_bounds.top, indent + 2); + file->writeNumberLine(_bounds.right, indent + 2); + file->writeNumberLine(_bounds.bottom, indent + 2); + + CNamedItem::save(file, indent); +} + +void CLinkItem::load(SimpleFile *file) { + int val = file->readNumber(); + file->readBuffer(); + + switch (val) { + case 2: + _cursorId = (CursorId)file->readNumber(); + // Deliberate fall-through + + case 1: + _linkMode = file->readNumber(); + // Deliberate fall-through + + case 0: + _roomNumber = file->readNumber(); + _nodeNumber = file->readNumber(); + _viewNumber = file->readNumber(); + + file->readBuffer(); + _bounds.left = file->readNumber(); + _bounds.top = file->readNumber(); + _bounds.right = file->readNumber(); + _bounds.bottom = file->readNumber(); + break; + + default: + break; + } + + CNamedItem::load(file); + + if (val < 2) { + switch (_linkMode) { + case 2: + _cursorId = CURSOR_MOVE_LEFT; + break; + case 3: + _cursorId = CURSOR_MOVE_RIGHT; + break; + case 5: + _cursorId = CURSOR_MOVE_FORWARD; + break; + default: + _cursorId = CURSOR_MOVE_FORWARD2; + break; + } + } +} + +bool CLinkItem::connectsTo(CViewItem *destView) const { + CNodeItem *destNode = destView->findNode(); + CRoomItem *destRoom = destNode->findRoom(); + + return _viewNumber == destView->_viewNumber && + _nodeNumber == destNode->_nodeNumber && + _roomNumber == destRoom->_roomNumber; +} + +void CLinkItem::setDestination(int roomNumber, int nodeNumber, + int viewNumber, int linkMode) { + _roomNumber = roomNumber; + _nodeNumber = nodeNumber; + _viewNumber = viewNumber; + _linkMode = linkMode; + + _name = formName(); +} + +CViewItem *CLinkItem::getDestView() const { + return getRoot()->findView(_roomNumber, _nodeNumber, _viewNumber); +} + +CNodeItem *CLinkItem::getDestNode() const { + return getDestView()->findNode(); +} + +CRoomItem *CLinkItem::getDestRoom() const { + return getDestNode()->findRoom(); +} + +CMovieClip *CLinkItem::getClip() const { + return findRoom()->findClip(getName()); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/link_item.h b/engines/titanic/core/link_item.h new file mode 100644 index 0000000000..dd93e2a0bf --- /dev/null +++ b/engines/titanic/core/link_item.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. + * + */ + +#ifndef TITANIC_LINK_ITEM_H +#define TITANIC_LINK_ITEM_H + +#include "titanic/support/mouse_cursor.h" +#include "titanic/core/named_item.h" +#include "titanic/support/movie_clip.h" + +namespace Titanic { + +class CViewItem; +class CNodeItem; +class CRoomItem; + +class CLinkItem : public CNamedItem { + DECLARE_MESSAGE_MAP; +private: + /** + * Returns a new name for the link item, based on the + * current values for it's destination + */ + CString formName(); +protected: + int _roomNumber; + int _nodeNumber; + int _viewNumber; + int _linkMode; +public: + Rect _bounds; + CursorId _cursorId; +public: + CLASSDEF; + CLinkItem(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Returns true if the given item connects to another specified view + */ + virtual bool connectsTo(CViewItem *destView) const; + + /** + * Set the destination for the link item + */ + virtual void setDestination(int roomNumber, int nodeNumber, + int viewNumber, int linkMode); + + /** + * Get the destination view for the link item + */ + virtual CViewItem *getDestView() const; + + /** + * Get the destination node for the link item + */ + virtual CNodeItem *getDestNode() const; + + /** + * Get the destination view for the link item + */ + virtual CRoomItem *getDestRoom() const; + + /** + * Get the movie clip, if any, that's used when the link is used + */ + CMovieClip *getClip() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LINK_ITEM_H */ diff --git a/engines/titanic/core/list.cpp b/engines/titanic/core/list.cpp new file mode 100644 index 0000000000..8e90e9ff40 --- /dev/null +++ b/engines/titanic/core/list.cpp @@ -0,0 +1,35 @@ +/* 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/core/list.h" + +namespace Titanic { + +void ListItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); +} + +void ListItem::load(SimpleFile *file) { + file->readNumber(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/list.h b/engines/titanic/core/list.h new file mode 100644 index 0000000000..91a74adbdc --- /dev/null +++ b/engines/titanic/core/list.h @@ -0,0 +1,164 @@ +/* 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. + * + */ + +#ifndef TITANIC_LIST_H +#define TITANIC_LIST_H + +#include "common/scummsys.h" +#include "common/list.h" +#include "titanic/support/simple_file.h" +#include "titanic/core/saveable_object.h" + +namespace Titanic { + +/** + * Base list item class + */ +class ListItem: public CSaveableObject { +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +/** + * List item macro for managed pointers an item + */ +#define PTR_LIST_ITEM(T) class T##ListItem : public ListItem { \ + public: T *_item; \ + T##ListItem() : _item(nullptr) {} \ + T##ListItem(T *item) : _item(item) {} \ + virtual ~T##ListItem() { delete _item; } \ + } + +template<typename T> +class PtrListItem : public ListItem { +public: + T *_item; +public: + PtrListItem() : _item(nullptr) {} + PtrListItem(T *item) : _item(item) {} + virtual ~PtrListItem() { delete _item; } +}; + +template<typename T> +class List : public CSaveableObject, public Common::List<T *> { +public: + virtual ~List() { destroyContents(); } + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + + // Write out number of items + file->writeQuotedLine("L", indent); + file->writeNumberLine(Common::List<T *>::size(), indent); + + // Iterate through writing entries + typename Common::List<T *>::iterator i; + for (i = Common::List<T *>::begin(); i != Common::List<T *>::end(); ++i) { + ListItem *item = *i; + item->saveHeader(file, indent); + item->save(file, indent + 1); + item->saveFooter(file, indent); + } + + } + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file) { + file->readNumber(); + file->readBuffer(); + + Common::List<T *>::clear(); + uint count = file->readNumber(); + + for (uint idx = 0; idx < count; ++idx) { + // Validate the class start header + if (!file->IsClassStart()) + error("Unexpected class end"); + + // Get item's class name and use it to instantiate an item + CString className = file->readString(); + T *newItem = dynamic_cast<T *>(CSaveableObject::createInstance(className)); + if (!newItem) + error("Could not create instance of %s", className.c_str()); + + // Load the item's data and add it to the list + newItem->load(file); + Common::List<T *>::push_back(newItem); + + // Validate the class end footer + if (file->IsClassStart()) + error("Unexpected class start"); + } + } + + /** + * Clear the list and destroy any items in it + */ + void destroyContents() { + typename Common::List<T *>::iterator i; + for (i = Common::List<T *>::begin(); + i != Common::List<T *>::end(); ++i) { + CSaveableObject *obj = *i; + delete obj; + } + + Common::List<T *>::clear(); + } + + /** + * Add a new item to the list of the type the list contains + */ + T *add() { + T *item = new T(); + Common::List<T *>::push_back(item); + return item; + } + + bool contains(const T *item) const { + for (typename Common::List<T *>::const_iterator i = Common::List<T *>::begin(); + i != Common::List<T *>::end(); ++i) { + if (*i == item) + return true; + } + + return false; + } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_LIST_H */ diff --git a/engines/titanic/core/mail_man.cpp b/engines/titanic/core/mail_man.cpp new file mode 100644 index 0000000000..afe13bebad --- /dev/null +++ b/engines/titanic/core/mail_man.cpp @@ -0,0 +1,81 @@ +/* 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/core/mail_man.h" + +namespace Titanic { + +void CMailMan::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_value, indent); + CGameObject::save(file, indent); +} + +void CMailMan::load(SimpleFile *file) { + file->readNumber(); + _value = file->readNumber(); + CGameObject::load(file); +} + +CGameObject *CMailMan::getFirstObject() const { + return static_cast<CGameObject *>(getFirstChild()); +} + +CGameObject *CMailMan::getNextObject(CGameObject *prior) const { + if (!prior || prior->getParent() != this) + return nullptr; + + return static_cast<CGameObject *>(prior->getNextSibling()); +} + +void CMailMan::addMail(CGameObject *obj, int id) { + obj->detach(); + obj->addUnder(this); + setMailId(obj, id); +} + +void CMailMan::setMailId(CGameObject *obj, int id) { + obj->_id = id; + obj->_roomFlags = 0; + obj->_isMail = true; +} + +CGameObject *CMailMan::findMail(int id) const { + for (CGameObject *obj = getFirstObject(); obj; obj = getNextObject(obj)) { + if (obj->_isMail && obj->_id == id) + return obj; + } + + return nullptr; +} + +void CMailMan::removeMail(int id, int roomFlags) { + for (CGameObject *obj = getFirstObject(); obj; obj = getNextObject(obj)) { + if (obj->_isMail && obj->_id == id) { + obj->_isMail = false; + obj->_roomFlags = roomFlags; + break; + } + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/mail_man.h b/engines/titanic/core/mail_man.h new file mode 100644 index 0000000000..4c63cdfa13 --- /dev/null +++ b/engines/titanic/core/mail_man.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. + * + */ + +#ifndef TITANIC_MAIL_MAN_H +#define TITANIC_MAIL_MAN_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CMailMan : public CGameObject { +public: + int _value; +public: + CLASSDEF; + CMailMan() : CGameObject(), _value(1) {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Get the first game object stored in the PET + */ + CGameObject *getFirstObject() const; + + /** + * Get the next game object stored in the PET following + * the passed game object + */ + CGameObject *getNextObject(CGameObject *prior) const; + + /** + * Add an object to the mail list + */ + void addMail(CGameObject *obj, int id); + + /** + * Sets the mail identifier for an object + */ + static void setMailId(CGameObject *obj, int id); + + /** + * Scan the mail list for a specified item + */ + CGameObject *findMail(int id) const; + + /** + * Remove a mail item + */ + void removeMail(int id, int v); + + void resetValue() { _value = 0; } +}; + + +} // End of namespace Titanic + +#endif /* TITANIC_MAIL_MAN_H */ diff --git a/engines/titanic/core/message_target.cpp b/engines/titanic/core/message_target.cpp new file mode 100644 index 0000000000..4815d03973 --- /dev/null +++ b/engines/titanic/core/message_target.cpp @@ -0,0 +1,50 @@ +/* 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/core/message_target.h" + +namespace Titanic { + +const MSGMAP *CMessageTarget::getMessageMap() const { + return getThisMessageMap(); +} + +const MSGMAP *CMessageTarget::getThisMessageMap() { + static const MSGMAP_ENTRY _messageEntries[] = { + { (PMSG)nullptr, nullptr } + }; + + static const MSGMAP messageMap = { nullptr, &_messageEntries[0] }; + return &messageMap; +} + +void CMessageTarget::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + CSaveableObject::save(file, indent); +} + +void CMessageTarget::load(SimpleFile *file) { + file->readNumber(); + CSaveableObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/message_target.h b/engines/titanic/core/message_target.h new file mode 100644 index 0000000000..a52de591b3 --- /dev/null +++ b/engines/titanic/core/message_target.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. + * + */ + +#ifndef TITANIC_MESSAGE_TARGET_H +#define TITANIC_MESSAGE_TARGET_H + +#include "titanic/core/saveable_object.h" + +namespace Titanic { + +class CMessageTarget; +class CMessage; + +typedef bool (CMessageTarget::*PMSG)(CMessage *msg); + +struct MSGMAP_ENTRY { + PMSG _fn; + ClassDef *_class; +}; + +struct MSGMAP { + const MSGMAP *(* pFnGetBaseMap)(); + const MSGMAP_ENTRY *lpEntries; +}; + +#define DECLARE_MESSAGE_MAP \ +protected: \ + static const MSGMAP *getThisMessageMap(); \ + virtual const MSGMAP *getMessageMap() const + +#define BEGIN_MESSAGE_MAP(theClass, baseClass) \ + const MSGMAP *theClass::getMessageMap() const \ + { return getThisMessageMap(); } \ + const MSGMAP *theClass::getThisMessageMap() \ + { \ + typedef theClass ThisClass; \ + typedef baseClass TheBaseClass; \ + typedef bool (theClass::*FNPTR)(CMessage *msg); \ + static const MSGMAP_ENTRY _messageEntries[] = { + +#define ON_MESSAGE(msgClass) \ + { static_cast<PMSG>((FNPTR)&ThisClass::msgClass), C##msgClass::_type }, + +#define END_MESSAGE_MAP() \ + { (PMSG)nullptr, nullptr } \ + }; \ + static const MSGMAP messageMap = \ + { &TheBaseClass::getThisMessageMap, &_messageEntries[0] }; \ + return &messageMap; \ + } + +#define EMPTY_MESSAGE_MAP(theClass, baseClass) \ + const MSGMAP *theClass::getMessageMap() const \ + { return getThisMessageMap(); } \ + const MSGMAP *theClass::getThisMessageMap() \ + { \ + typedef baseClass TheBaseClass; \ + static const MSGMAP_ENTRY _messageEntries[] = { \ + { (PMSG)nullptr, nullptr } \ + }; \ + static const MSGMAP messageMap = \ + { &TheBaseClass::getThisMessageMap, &_messageEntries[0] }; \ + return &messageMap; \ + } \ + static const int DUMMY = 0 + +class CMessageTarget: public CSaveableObject { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MESSAGE_TARGET_H */ diff --git a/engines/titanic/core/multi_drop_target.cpp b/engines/titanic/core/multi_drop_target.cpp new file mode 100644 index 0000000000..f2998199b1 --- /dev/null +++ b/engines/titanic/core/multi_drop_target.cpp @@ -0,0 +1,43 @@ +/* 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/core/multi_drop_target.h" + +namespace Titanic { + +void CMultiDropTarget::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string5, indent); + file->writeQuotedLine(_string6, indent); + + CDropTarget::save(file, indent); +} + +void CMultiDropTarget::load(SimpleFile *file) { + file->readNumber(); + _string5 = file->readString(); + _string6 = file->readString(); + + CDropTarget::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/multi_drop_target.h b/engines/titanic/core/multi_drop_target.h new file mode 100644 index 0000000000..c004b9bece --- /dev/null +++ b/engines/titanic/core/multi_drop_target.h @@ -0,0 +1,51 @@ +/* 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. + * + */ + +#ifndef TITANIC_MULTI_DROP_TARGET_H +#define TITANIC_MULTI_DROP_TARGET_H + +#include "titanic/core/drop_target.h" + +namespace Titanic { + +class CMultiDropTarget : public CDropTarget { +public: + CString _string5; + CString _string6; +public: + CLASSDEF; + CMultiDropTarget() : CDropTarget(), _string5("1,2") {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CLICK_RESPONDER_H */ diff --git a/engines/titanic/core/named_item.cpp b/engines/titanic/core/named_item.cpp new file mode 100644 index 0000000000..6eafbf8c8b --- /dev/null +++ b/engines/titanic/core/named_item.cpp @@ -0,0 +1,92 @@ +/* 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/core/named_item.h" +#include "titanic/core/node_item.h" +#include "titanic/core/room_item.h" +#include "titanic/core/view_item.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CNamedItem, CTreeItem); + +CString CNamedItem::dumpItem(int indent) const { + CString result = CTreeItem::dumpItem(indent); + result += " " + _name; + + return result; +} + +void CNamedItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + file->writeQuotedLine(_name, indent); + + CTreeItem::save(file, indent); +} + +void CNamedItem::load(SimpleFile *file) { + int val = file->readNumber(); + if (!val) + _name = file->readString(); + + CTreeItem::load(file); +} + +int CNamedItem::compareTo(const CString &name, int maxLen) const { + if (maxLen) { + return getName().left(maxLen).compareToIgnoreCase(name); + } else { + return getName().compareToIgnoreCase(name); + } +} + +CViewItem *CNamedItem::findView() const { + for (CTreeItem *parent = getParent(); parent; parent = parent->getParent()) { + CViewItem *view = dynamic_cast<CViewItem *>(parent); + if (view) + return view; + } + + error("Couldn't find parent view"); +} + +CNodeItem *CNamedItem::findNode() const { + for (CTreeItem *parent = getParent(); parent; parent = parent->getParent()) { + CNodeItem *node = dynamic_cast<CNodeItem *>(parent); + if (node) + return node; + } + + error("Couldn't find parent node"); +} + +CRoomItem *CNamedItem::findRoom() const { + for (CTreeItem *parent = getParent(); parent; parent = parent->getParent()) { + CRoomItem *room = dynamic_cast<CRoomItem *>(parent); + if (room) + return room; + } + + error("Couldn't find parent node"); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/named_item.h b/engines/titanic/core/named_item.h new file mode 100644 index 0000000000..809cda1156 --- /dev/null +++ b/engines/titanic/core/named_item.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. + * + */ + +#ifndef TITANIC_NAMED_ITEM_H +#define TITANIC_NAMED_ITEM_H + +#include "titanic/core/tree_item.h" + +namespace Titanic { + +class CViewItem; +class CNodeItem; +class CRoomItem; + +class CNamedItem: public CTreeItem { + DECLARE_MESSAGE_MAP; +public: + CString _name; +public: + CLASSDEF; + + /** + * Dump the item + */ + virtual CString dumpItem(int indent) const; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Gets the name of the item, if any + */ + virtual const CString getName() const { return _name; } + + /** + * Compares the name of the item to a passed name + */ + virtual int compareTo(const CString &name, int maxLen) const; + + /** + * Find a parent node for the item + */ + virtual CViewItem *findView() const; + + /** + * Find a parent node for the item + */ + virtual CNodeItem *findNode() const; + + /** + * Find a parent room item for the item + */ + virtual CRoomItem *findRoom() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_NAMED_ITEM_H */ diff --git a/engines/titanic/core/node_item.cpp b/engines/titanic/core/node_item.cpp new file mode 100644 index 0000000000..1de065a49d --- /dev/null +++ b/engines/titanic/core/node_item.cpp @@ -0,0 +1,56 @@ +/* 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/core/node_item.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CNodeItem, CNamedItem); + +CNodeItem::CNodeItem() : CNamedItem(), _nodeNumber(0) { +} + +void CNodeItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + file->writeQuotedLine("N", indent); + file->writeNumberLine(_nodePos.x, indent + 1); + file->writeNumberLine(_nodePos.y, indent + 1); + + file->writeQuotedLine("N", indent); + file->writeNumberLine(_nodeNumber, indent + 1); + + CNamedItem::save(file, indent); +} + +void CNodeItem::load(SimpleFile *file) { + file->readNumber(); + file->readBuffer(); + _nodePos.x = file->readNumber(); + _nodePos.y = file->readNumber(); + + file->readBuffer(); + _nodeNumber = file->readNumber(); + + CNamedItem::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/node_item.h b/engines/titanic/core/node_item.h new file mode 100644 index 0000000000..8fda9464ec --- /dev/null +++ b/engines/titanic/core/node_item.h @@ -0,0 +1,52 @@ +/* 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. + * + */ + +#ifndef TITANIC_NODE_ITEM_H +#define TITANIC_NODE_ITEM_H + +#include "titanic/core/named_item.h" + +namespace Titanic { + +class CNodeItem : public CNamedItem { + DECLARE_MESSAGE_MAP; +public: + int _nodeNumber; + Point _nodePos; +public: + CLASSDEF; + CNodeItem(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FILE_ITEM_H */ diff --git a/engines/titanic/core/project_item.cpp b/engines/titanic/core/project_item.cpp new file mode 100644 index 0000000000..76293233b0 --- /dev/null +++ b/engines/titanic/core/project_item.cpp @@ -0,0 +1,549 @@ +/* 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 "common/file.h" +#include "common/savefile.h" +#include "graphics/scaler.h" +#include "graphics/thumbnail.h" +#include "titanic/game_manager.h" +#include "titanic/titanic.h" +#include "titanic/core/dont_save_file_item.h" +#include "titanic/core/node_item.h" +#include "titanic/core/project_item.h" +#include "titanic/core/view_item.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +#define CURRENT_SAVEGAME_VERSION 1 +#define MAX_SAVEGAME_SLOTS 99 +#define MINIMUM_SAVEGAME_VERSION 1 + +static const char *const SAVEGAME_STR = "TNIC"; +#define SAVEGAME_STR_SIZE 4 + +EMPTY_MESSAGE_MAP(CProjectItem, CFileItem); + +void CFileListItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + file->writeQuotedLine(_name, indent); + + ListItem::save(file, indent); +} + +void CFileListItem::load(SimpleFile *file) { + file->readNumber(); + _name = file->readString(); + + ListItem::load(file); +} + +/*------------------------------------------------------------------------*/ + +CProjectItem::CProjectItem() : _nextRoomNumber(0), _nextMessageNumber(0), + _nextObjectNumber(0), _gameManager(nullptr) { +} + +void CProjectItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(6, indent); + file->writeQuotedLine("Next Avail. Object Number", indent); + file->writeNumberLine(_nextObjectNumber, indent); + file->writeQuotedLine("Next Avail. Message Number", indent); + file->writeNumberLine(_nextMessageNumber, indent); + + file->writeQuotedLine("", indent); + _files.save(file, indent); + + file->writeQuotedLine("Next Avail. Room Number", indent); + file->writeNumberLine(_nextRoomNumber, indent); + + CTreeItem::save(file, indent); +} + +void CProjectItem::buildFilesList() { + _files.destroyContents(); + + CTreeItem *treeItem = getFirstChild(); + while (treeItem) { + if (treeItem->isFileItem()) { + CString name = static_cast<CFileItem *>(treeItem)->getFilename(); + _files.add()->_name = name; + } + + treeItem = getNextSibling(); + } +} + +void CProjectItem::load(SimpleFile *file) { + int val = file->readNumber(); + _files.destroyContents(); + int count; + + switch (val) { + case 1: + file->readBuffer(); + _nextRoomNumber = file->readNumber(); + // Deliberate fall-through + + case 0: + // Load the list of files + count = file->readNumber(); + for (int idx = 0; idx < count; ++idx) { + CString name = file->readString(); + _files.add()->_name = name; + } + break; + + case 6: + file->readBuffer(); + _nextObjectNumber = file->readNumber(); + // Deliberate fall-through + + case 5: + file->readBuffer(); + _nextMessageNumber = file->readNumber(); + // Deliberate fall-through + + case 4: + file->readBuffer(); + // Deliberate fall-through + + case 2: + case 3: + _files.load(file); + file->readBuffer(); + _nextRoomNumber = file->readNumber(); + break; + + default: + break; + } + + CTreeItem::load(file); +} + +CGameManager *CProjectItem::getGameManager() const { + return _gameManager; +} + +void CProjectItem::setGameManager(CGameManager *gameManager) { + if (!_gameManager) + _gameManager = gameManager; +} + +void CProjectItem::resetGameManager() { + _gameManager = nullptr; +} + +void CProjectItem::loadGame(int slotId) { + CompressedFile file; + + // Clear any existing project contents and call preload code + clear(); + preLoad(); + + // Open either an existing savegame slot or the new game template + if (slotId >= 0) { + Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading( + g_vm->generateSaveName(slotId)); + file.open(saveFile); + } else { + Common::File *newFile = new Common::File(); + if (!newFile->open("newgame.st")) + error("Could not open newgame.st"); + file.open(newFile); + } + + // Load the savegame header in + TitanicSavegameHeader header; + readSavegameHeader(&file, header); + delete header._thumbnail; + + // Load the contents in + CProjectItem *newProject = loadData(&file); + file.IsClassStart(); + getGameManager()->load(&file); + + file.close(); + + // Clear existing project + clear(); + + // Detach each item under the loaded project, and re-attach them + // to the existing project instance (this) + CTreeItem *item; + while ((item = newProject->getFirstChild()) != nullptr) { + item->detach(); + item->addUnder(this); + } + + // Loaded project instance is no longer needed + newProject->destroyAll(); + + // Post-load processing + postLoad(); +} + +void CProjectItem::saveGame(int slotId, const CString &desc) { + CompressedFile file; + Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving( + g_vm->generateSaveName(slotId), false); + file.open(saveFile); + + // Signal the game is being saved + preSave(); + + // Write out the savegame header + TitanicSavegameHeader header; + header._saveName = desc; + writeSavegameHeader(&file, header); + + // Save the contents out + saveData(&file, this); + + // Save the game manager data + _gameManager->save(&file); + + // Close the file and signal that the saving has finished + file.close(); + postSave(); +} + +void CProjectItem::clear() { + CTreeItem *item; + while ((item = getFirstChild()) != nullptr) + item->destroyAll(); +} + +CProjectItem *CProjectItem::loadData(SimpleFile *file) { + if (!file->IsClassStart()) + return nullptr; + + CProjectItem *root = nullptr; + CTreeItem *parent = nullptr; + CTreeItem *item = nullptr; + + do { + CString entryString = file->readString(); + + if (entryString == "ALONG") { + // Move along, nothing needed + } else if (entryString == "UP") { + // Move up + if (parent == nullptr || + (parent = parent->getParent()) == nullptr) + break; + } else if (entryString == "DOWN") { + // Move down + if (parent == nullptr) + parent = item; + else + parent = parent->getLastChild(); + } else { + // Create new class instance + item = dynamic_cast<CTreeItem *>(CSaveableObject::createInstance(entryString)); + assert(item); + + if (root) { + // Already created root project + item->addUnder(parent); + } else { + root = dynamic_cast<CProjectItem *>(item); + assert(root); + root->_filename = _filename; + } + + // Load the data for the item + item->load(file); + } + + file->IsClassStart(); + } while (file->IsClassStart()); + + return root; +} + +void CProjectItem::saveData(SimpleFile *file, CTreeItem *item) const { + while (item) { + item->saveHeader(file, 0); + item->save(file, 1); + item->saveFooter(file, 0); + + CTreeItem *child = item->getFirstChild(); + if (child) { + file->write("\n{\n", 3); + file->writeQuotedString("DOWN"); + file->write("\n}\n", 3); + saveData(file, child); + file->write("\n{\n", 3); + file->writeQuotedString("UP"); + } else { + file->write("\n{\n", 3); + file->writeQuotedString("ALONG"); + } + + file->write("\n}\n", 3); + item = item->getNextSibling(); + } +} + +void CProjectItem::preLoad() { + if (_gameManager) + _gameManager->preLoad(); +} + +void CProjectItem::postLoad() { + CGameManager *gameManager = getGameManager(); + if (gameManager) + gameManager->postLoad(this); + + CPetControl *petControl = getPetControl(); + if (petControl) + petControl->postLoad(); +} + +void CProjectItem::preSave() { + if (_gameManager) + _gameManager->preSave(this); +} + +void CProjectItem::postSave() { + if (_gameManager) + _gameManager->postSave(); +} + +CPetControl *CProjectItem::getPetControl() const { + CDontSaveFileItem *fileItem = getDontSaveFileItem(); + CTreeItem *treeItem; + + if (!fileItem || (treeItem = fileItem->getLastChild()) == nullptr) + return nullptr; + + while (treeItem) { + CPetControl *petControl = dynamic_cast<CPetControl *>(treeItem); + if (petControl) + return petControl; + + treeItem = treeItem->getPriorSibling(); + } + + return nullptr; +} + +CRoomItem *CProjectItem::findFirstRoom() const { + return dynamic_cast<CRoomItem *>(findChildInstance(CRoomItem::_type)); +} + +CTreeItem *CProjectItem::findChildInstance(ClassDef *classDef) const { + CTreeItem *treeItem = getFirstChild(); + if (treeItem == nullptr) + return nullptr; + + do { + CTreeItem *childItem = treeItem->getFirstChild(); + if (childItem) { + do { + if (childItem->isInstanceOf(classDef)) + return childItem; + } while ((childItem = childItem->getNextSibling()) != nullptr); + } + } while ((treeItem = treeItem->getNextSibling()) != nullptr); + + return nullptr; +} + +CRoomItem *CProjectItem::findNextRoom(CRoomItem *priorRoom) const { + return dynamic_cast<CRoomItem *>(findSiblingInstanceOf(CRoomItem::_type, priorRoom)); +} + +CTreeItem *CProjectItem::findSiblingInstanceOf(ClassDef *classDef, CTreeItem *startItem) const { + CTreeItem *treeItem = startItem->getParent()->getNextSibling(); + if (treeItem == nullptr) + return nullptr; + + return findChildInstance(classDef); +} + +CDontSaveFileItem *CProjectItem::getDontSaveFileItem() const { + for (CTreeItem *treeItem = getFirstChild(); treeItem; treeItem = treeItem->getNextSibling()) { + if (treeItem->isInstanceOf(CDontSaveFileItem::_type)) + return dynamic_cast<CDontSaveFileItem *>(treeItem); + } + + return nullptr; +} + +CRoomItem *CProjectItem::findHiddenRoom() { + return dynamic_cast<CRoomItem *>(findByName("HiddenRoom")); +} + +CViewItem *CProjectItem::findView(int roomNumber, int nodeNumber, int viewNumber) { + CTreeItem *treeItem = getFirstChild(); + CRoomItem *roomItem = nullptr; + + // Scan for the specified room + if (treeItem) { + do { + CTreeItem *childItem = treeItem->getFirstChild(); + CRoomItem *rItem = dynamic_cast<CRoomItem *>(childItem); + if (rItem && rItem->_roomNumber == roomNumber) { + roomItem = rItem; + break; + } + } while ((treeItem = treeItem->getNextSibling()) != nullptr); + } + if (!roomItem) + return nullptr; + + // Scan for the specified node within the room + CNodeItem *nodeItem = nullptr; + + CNodeItem *nItem = dynamic_cast<CNodeItem *>( + roomItem->findChildInstanceOf(CNodeItem::_type)); + for (; nItem && !nodeItem; nItem = dynamic_cast<CNodeItem *>( + findNextInstanceOf(CNodeItem::_type, nItem))) { + if (nItem->_nodeNumber == nodeNumber) + nodeItem = nItem; + } + if (!nodeItem) + return nullptr; + + // Scan for the specified view within the node + CViewItem *viewItem = dynamic_cast<CViewItem *>( + nodeItem->findChildInstanceOf(CViewItem::_type)); + for (; viewItem; viewItem = dynamic_cast<CViewItem *>( + findNextInstanceOf(CViewItem::_type, viewItem))) { + if (viewItem->_viewNumber == viewNumber) + return viewItem; + } + + return nullptr; +} + +SaveStateList CProjectItem::getSavegameList(const Common::String &target) { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::StringArray filenames; + Common::String saveDesc; + Common::String pattern = Common::String::format("%s.0??", target.c_str()); + TitanicSavegameHeader header; + + filenames = saveFileMan->listSavefiles(pattern); + sort(filenames.begin(), filenames.end()); // Sort to get the files in numerical order + + SaveStateList saveList; + for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { + const char *ext = strrchr(file->c_str(), '.'); + int slot = ext ? atoi(ext + 1) : -1; + + if (slot >= 0 && slot < MAX_SAVEGAME_SLOTS) { + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); + + if (in) { + SimpleFile f; + f.open(in); + if (!readSavegameHeader(&f, header)) + continue; + + saveList.push_back(SaveStateDescriptor(slot, header._saveName)); + + header._thumbnail->free(); + delete header._thumbnail; + delete in; + } + } + } + + return saveList; +} + +bool CProjectItem::readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header) { + char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; + header._thumbnail = nullptr; + + // Validate the header Id + file->unsafeRead(saveIdentBuffer, SAVEGAME_STR_SIZE + 1); + if (strncmp(saveIdentBuffer, SAVEGAME_STR, SAVEGAME_STR_SIZE)) { + file->seek(-SAVEGAME_STR_SIZE, SEEK_CUR); + header._saveName = "Unnamed"; + return true; + } + + header._version = file->readByte(); + if (header._version < MINIMUM_SAVEGAME_VERSION || header._version > CURRENT_SAVEGAME_VERSION) + return false; + + // Read in the string + header._saveName.clear(); + char ch; + while ((ch = (char)file->readByte()) != '\0') header._saveName += ch; + + // Get the thumbnail + header._thumbnail = Graphics::loadThumbnail(*file); + if (!header._thumbnail) + return false; + + // Read in save date/time + header._year = file->readUint16LE(); + header._month = file->readUint16LE(); + header._day = file->readUint16LE(); + header._hour = file->readUint16LE(); + header._minute = file->readUint16LE(); + header._totalFrames = file->readUint32LE(); + + return true; +} + +void CProjectItem::writeSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header) { + // Write out a savegame header + file->write(SAVEGAME_STR, SAVEGAME_STR_SIZE + 1); + + file->writeByte(CURRENT_SAVEGAME_VERSION); + + // Write savegame name + file->write(header._saveName.c_str(), header._saveName.size()); + file->writeByte('\0'); + + // Create a thumbnail of the screen and save it out + Graphics::Surface *thumb = createThumbnail(); + Graphics::saveThumbnail(*file, *thumb); + thumb->free(); + delete thumb; + + // Write out the save date/time + TimeDate td; + g_system->getTimeAndDate(td); + file->writeUint16LE(td.tm_year + 1900); + file->writeUint16LE(td.tm_mon + 1); + file->writeUint16LE(td.tm_mday); + file->writeUint16LE(td.tm_hour); + file->writeUint16LE(td.tm_min); + file->writeUint32LE(g_vm->_events->getFrameCounter()); +} + +Graphics::Surface *CProjectItem::createThumbnail() { + Graphics::Surface *thumb = new Graphics::Surface(); + + ::createThumbnailFromScreen(thumb); + return thumb; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/project_item.h b/engines/titanic/core/project_item.h new file mode 100644 index 0000000000..473ffd9556 --- /dev/null +++ b/engines/titanic/core/project_item.h @@ -0,0 +1,234 @@ +/* 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. + * + */ + +#ifndef TITANIC_PROJECT_ITEM_H +#define TITANIC_PROJECT_ITEM_H + +#include "common/scummsys.h" +#include "common/str.h" +#include "engines/savestate.h" +#include "graphics/surface.h" +#include "titanic/support/simple_file.h" +#include "titanic/core/dont_save_file_item.h" +#include "titanic/core/file_item.h" +#include "titanic/core/list.h" +#include "titanic/core/room_item.h" + +namespace Titanic { + +struct TitanicSavegameHeader { + uint8 _version; + CString _saveName; + Graphics::Surface *_thumbnail; + int _year, _month, _day; + int _hour, _minute; + int _totalFrames; +}; + + +class CGameManager; +class CPetControl; +class CViewItem; + +/** + * File list item + */ +class CFileListItem : public ListItem { +public: + CString _name; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +/** + * Filename list + */ +class CFileList: public List<CFileListItem> { +}; + +class CProjectItem : public CFileItem { + DECLARE_MESSAGE_MAP; +private: + CString _filename; + CFileList _files; + int _nextRoomNumber; + int _nextMessageNumber; + int _nextObjectNumber; + CGameManager *_gameManager; + + /** + * Called during save, iterates through the children to do some stuff + */ + void buildFilesList(); + + /** + * Called at the beginning of loading a game + */ + void preLoad(); + + /** + * Does post-loading processing + */ + void postLoad(); + + /** + * Called when a game is about to be saved + */ + void preSave(); + + /** + * Called when a game has finished being saved + */ + void postSave(); + + /** + * Finds the first child instance of a given class type + */ + CTreeItem *findChildInstance(ClassDef *classDef) const; + + /** + * Finds the next sibling occurance of a given class type + */ + CTreeItem *findSiblingInstanceOf(ClassDef *classDef, CTreeItem *startItem) const; +private: + /** + * Load project data from the passed file + */ + CProjectItem *loadData(SimpleFile *file); + + /** + * Save project data to the passed file + */ + void saveData(SimpleFile *file, CTreeItem *item) const; + + /** + * Creates a thumbnail for the current on-screen contents + */ + static Graphics::Surface *createThumbnail(); +public: + /** + * Load a list of savegames + */ + static SaveStateList getSavegameList(const Common::String &target); + + /** + * Write out the header information for a savegame + */ + static void writeSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header); + + /** + * Read in the header information for a savegame + */ + static bool readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header); +public: + CLASSDEF; + CProjectItem(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Get the game manager for the project + */ + virtual CGameManager *getGameManager() const; + + /** + * Sets the game manager for the project, if not already set + */ + void setGameManager(CGameManager *gameManager); + + /** + * Get a reference to the PET control + */ + CPetControl *getPetControl() const; + + /** + * Resets the game manager field + */ + void resetGameManager(); + + /** + * Load the entire project data for a given slot Id + */ + void loadGame(int slotId); + + /** + * Save the entire project data to a given savegame slot + */ + void saveGame(int slotId, const CString &desc); + + /** + * Clear any currently loaded project + */ + void clear(); + + /** + * Set the proejct's name + */ + void setFilename(const CString &name) { _filename = name; } + + /** + * Returns a reference to the first room item in the project + */ + CRoomItem *findFirstRoom() const; + + /** + * Returns a reference to the next room following the specified room + */ + CRoomItem *findNextRoom(CRoomItem *priorRoom) const; + + /** + * Returns the don't save file item, if it exists in the project + */ + CDontSaveFileItem *getDontSaveFileItem() const; + + /** + * Finds the hidden room node of the project + */ + CRoomItem *findHiddenRoom(); + + /** + * Finds a view + */ + CViewItem *findView(int roomNumber, int nodeNumber, int viewNumber); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PROJECT_ITEM_H */ diff --git a/engines/titanic/core/resource_key.cpp b/engines/titanic/core/resource_key.cpp new file mode 100644 index 0000000000..3b390af2d4 --- /dev/null +++ b/engines/titanic/core/resource_key.cpp @@ -0,0 +1,89 @@ +/* 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 "common/file.h" +#include "titanic/titanic.h" +#include "titanic/support/simple_file.h" +#include "titanic/core/resource_key.h" + +namespace Titanic { + +void CResourceKey::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine("Resource Key...", indent); + file->writeQuotedLine(_key, indent); + + CSaveableObject::save(file, indent); +} + +void CResourceKey::load(SimpleFile *file) { + int val = file->readNumber(); + + if (val == 0 || val == 1) { + file->readBuffer(); + CString str = file->readString(); + setValue(str); + } + + CSaveableObject::load(file); +} + +void CResourceKey::setValue(const CString &name) { + CString nameStr = name; + nameStr.toLowercase(); + _key = nameStr; + + _value = nameStr; + int idx = _value.lastIndexOf('\\'); + if (idx >= 0) + _value = _value.mid(idx + 1); +} + +CString CResourceKey::exists() const { + CString name = _key; + + // Check for a resource being specified within an ST container + int idx = name.indexOf('#'); + if (idx >= 0) { + name = name.left(idx); + name += ".st"; + } + + // The original did tests for the file in the different + // asset paths, which aren't needed in ScummVM + Common::File f; + return f.exists(name) ? name : CString(); +} + +bool CResourceKey::scanForFile() const { + return g_vm->_filesManager->scanForFile(_value); +} + +FileType CResourceKey::fileTypeSuffix() const { + return _value.fileTypeSuffix(); +} + +ImageType CResourceKey::imageTypeSuffix() const { + return _value.imageTypeSuffix(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/resource_key.h b/engines/titanic/core/resource_key.h new file mode 100644 index 0000000000..27b23ed1e7 --- /dev/null +++ b/engines/titanic/core/resource_key.h @@ -0,0 +1,81 @@ +/* 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. + * + */ + +#ifndef TITANIC_RESOURCE_KEY_H +#define TITANIC_RESOURCE_KEY_H + +#include "titanic/support/string.h" +#include "titanic/core/saveable_object.h" + +namespace Titanic { + +class CResourceKey: public CSaveableObject { +private: + CString _key; + CString _value; + + void setValue(const CString &name); +public: + CLASSDEF; + CResourceKey() {} + CResourceKey(const CString &name) { setValue(name); } + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Return the key + */ + const CString &getString() const { return _key; } + + /** + * Checks whether a file for the given key exists, + * and returns it's filename if it does + */ + CString exists() const; + + /** + * Scans for a file with a matching name + */ + bool scanForFile() const; + + /** + * Returns the type of the resource based on it's extension + */ + FileType fileTypeSuffix() const; + + /** + * Returns the type of the resource based on it's extension + */ + ImageType imageTypeSuffix() const; +}; + +} // End of namespace Titanic + +#endif /* TITANIC_RESOURCE_KEY_H */ diff --git a/engines/titanic/core/room_item.cpp b/engines/titanic/core/room_item.cpp new file mode 100644 index 0000000000..541a8e1a9e --- /dev/null +++ b/engines/titanic/core/room_item.cpp @@ -0,0 +1,198 @@ +/* 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/core/room_item.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CRoomItem, CNamedItem); + +CRoomItem::CRoomItem() : CNamedItem(), _roomNumber(0), + _roomDimensionX(0.0), _roomDimensionY(0.0) { +} + +void CRoomItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(3, indent); + file->writeQuotedLine("Exit Movies", indent); + _exitMovieKey.save(file, indent); + + file->writeQuotedLine("Room dimensions x 1000", indent); + file->writeNumberLine(_roomDimensionX * 1000.0, indent + 1); + file->writeNumberLine(_roomDimensionY * 1000.0, indent + 1); + + file->writeQuotedLine("Transition Movie", indent); + _transitionMovieKey.save(file, indent); + + file->writeQuotedLine("Movie Clip list", indent); + _clipList.save(file, indent + 1); + + file->writeQuotedLine("Room Rect", indent); + file->writeNumberLine(_roomRect.left, indent + 1); + file->writeNumberLine(_roomRect.top, indent + 1); + file->writeNumberLine(_roomRect.right, indent + 1); + file->writeNumberLine(_roomRect.bottom, indent + 1); + + file->writeQuotedLine("Room Number", indent); + file->writeNumberLine(_roomNumber, indent); + + CNamedItem::save(file, indent); +} + +void CRoomItem::load(SimpleFile *file) { + int val = file->readNumber(); + + switch (val) { + case 3: + // Read exit movie + file->readBuffer(); + _exitMovieKey.load(file); + // Deliberate fall-through + + case 2: + // Read room dimensions + file->readBuffer(); + _roomDimensionX = (double)file->readNumber() / 1000.0; + _roomDimensionY = (double)file->readNumber() / 1000.0; + // Deliberate fall-through + + case 1: + // Read transition movie key and clip list + file->readBuffer(); + _transitionMovieKey.load(file); + + file->readBuffer(); + _clipList.load(file); + postLoad(); + // Deliberate fall-through + + case 0: + // Read room rect + file->readBuffer(); + _roomRect.left = file->readNumber(); + _roomRect.top = file->readNumber(); + _roomRect.right = file->readNumber(); + _roomRect.bottom = file->readNumber(); + file->readBuffer(); + _roomNumber = file->readNumber(); + break; + + default: + break; + } + + CNamedItem::load(file); +} + +void CRoomItem::postLoad() { + if (!_exitMovieKey.exists().empty()) + return; + + CString name = _transitionMovieKey.exists(); + if (name.right(7) == "nav.avi") { + _exitMovieKey = CResourceKey(name.left(name.size() - 7) + "exit.avi"); + } +} + +void CRoomItem::calcNodePosition(const Point &nodePos, double &xVal, double &yVal) const { + xVal = yVal = 0.0; + + if (_roomDimensionX >= 0.0 && _roomDimensionY >= 0.0) { + xVal = _roomRect.width() / _roomDimensionX; + yVal = _roomRect.height() / _roomDimensionY; + + xVal = (nodePos.x - _roomRect.left) / xVal; + yVal = (nodePos.y - _roomRect.top) / yVal; + } +} + +int CRoomItem::getScriptId() const { + CString name = getName(); + if (name == "1stClassLobby") + return 130; + else if (name == "1stClassRestaurant") + return 132; + else if (name == "1stClassState") + return 131; + else if (name == "2ndClassLobby") + return 128; + else if (name == "Bar") + return 112; + else if (name == "BottomOfWell") + return 108; + else if (name == "Bridge") + return 121; + else if (name == "Dome") + return 122; + else if (name == "Home") + return 100; + else if (name == "Lift") + return 103; + else if (name == "MusicRoom") + return 117; + else if (name == "MusicRoomLobby") + return 118; + else if (name == "ParrotLobby") + return 111; + else if (name == "Pellerator") + return 104; + else if (name == "PromenadeDeck") + return 114; + else if (name == "SculptureChamber") + return 116; + else if (name == "secClassState") + return 129; + else if (name == "ServiceElevator") + return 102; + else if (name == "SGTLeisure") + return 125; + else if (name == "SGTLittleLift") + return 105; + else if (name == "SgtLobby") + return 124; + else if (name == "SGTState") + return 126; + else if (name == "Titania") + return 123; + else if (name == "TopOfWell") + return 107; + else if (name == "EmbLobby" || name == "MoonEmbLobby") + return 110; + else if (name == "CreatorsChamber" || name == "CreatorsChamberOn") + return 113; + else if (name == "Arboretum" || name == "FrozenArboretum") + return 115; + else if (name == "BilgeRoom" || name == "BilgeRoomWith") + return 101; + + return 0; +} + +CResourceKey CRoomItem::getTransitionMovieKey() { + _transitionMovieKey.scanForFile(); + return _transitionMovieKey; +} + +CResourceKey CRoomItem::getExitMovieKey() { + return _exitMovieKey; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/room_item.h b/engines/titanic/core/room_item.h new file mode 100644 index 0000000000..cb343a15d2 --- /dev/null +++ b/engines/titanic/core/room_item.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. + * + */ + +#ifndef TITANIC_ROOM_ITEM_H +#define TITANIC_ROOM_ITEM_H + +#include "titanic/support/rect.h" +#include "titanic/core/list.h" +#include "titanic/support/movie_clip.h" +#include "titanic/core/named_item.h" +#include "titanic/core/resource_key.h" + +namespace Titanic { + +class CRoomItem : public CNamedItem { + DECLARE_MESSAGE_MAP; +private: + /** + * Handles post-load processing + */ + void postLoad(); +public: + Rect _roomRect; + CMovieClipList _clipList; + int _roomNumber; + CResourceKey _transitionMovieKey; + CResourceKey _exitMovieKey; + double _roomDimensionX, _roomDimensionY; +public: + CLASSDEF; + CRoomItem(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Return a movie clip for the room by name + */ + CMovieClip *findClip(const CString &name) { return _clipList.findByName(name); } + + /** + * Calculates the positioning of a node within the overall room + */ + void calcNodePosition(const Point &nodePos, double &xVal, double &yVal) const; + + /** + * Get the TrueTalk script Id associated with the room + */ + int getScriptId() const; + + CResourceKey getTransitionMovieKey(); + + CResourceKey getExitMovieKey(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_ROOM_ITEM_H */ diff --git a/engines/titanic/core/saveable_object.cpp b/engines/titanic/core/saveable_object.cpp new file mode 100644 index 0000000000..62cee47045 --- /dev/null +++ b/engines/titanic/core/saveable_object.cpp @@ -0,0 +1,1642 @@ +/* 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/carry/arm.h" +#include "titanic/carry/auditory_centre.h" +#include "titanic/carry/bowl_ear.h" +#include "titanic/carry/brain.h" +#include "titanic/carry/bridge_piece.h" +#include "titanic/carry/carry.h" +#include "titanic/carry/carry_parrot.h" +#include "titanic/carry/central_core.h" +#include "titanic/carry/chicken.h" +#include "titanic/carry/crushed_tv.h" +#include "titanic/carry/eye.h" +#include "titanic/carry/feathers.h" +#include "titanic/carry/fruit.h" +#include "titanic/carry/glass.h" +#include "titanic/carry/hammer.h" +#include "titanic/carry/head_piece.h" +#include "titanic/carry/hose.h" +#include "titanic/carry/hose_end.h" +#include "titanic/carry/key.h" +#include "titanic/carry/liftbot_head.h" +#include "titanic/carry/long_stick.h" +#include "titanic/carry/magazine.h" +#include "titanic/carry/maitred_left_arm.h" +#include "titanic/carry/maitred_right_arm.h" +#include "titanic/carry/mouth.h" +#include "titanic/carry/napkin.h" +#include "titanic/carry/nose.h" +#include "titanic/carry/note.h" +#include "titanic/carry/parcel.h" +#include "titanic/carry/perch.h" +#include "titanic/carry/phonograph_cylinder.h" +#include "titanic/carry/phonograph_ear.h" +#include "titanic/carry/photograph.h" +#include "titanic/carry/plug_in.h" +#include "titanic/carry/speech_centre.h" +#include "titanic/carry/sweets.h" +#include "titanic/carry/vision_centre.h" + +#include "titanic/core/saveable_object.h" +#include "titanic/core/background.h" +#include "titanic/core/click_responder.h" +#include "titanic/core/dont_save_file_item.h" +#include "titanic/core/drop_target.h" +#include "titanic/core/file_item.h" +#include "titanic/core/game_object.h" +#include "titanic/core/game_object_desc_item.h" +#include "titanic/core/link_item.h" +#include "titanic/core/list.h" +#include "titanic/core/mail_man.h" +#include "titanic/core/message_target.h" +#include "titanic/support/movie_clip.h" +#include "titanic/core/multi_drop_target.h" +#include "titanic/core/node_item.h" +#include "titanic/core/project_item.h" +#include "titanic/core/room_item.h" +#include "titanic/core/saveable_object.h" +#include "titanic/core/static_image.h" +#include "titanic/core/turn_on_object.h" +#include "titanic/core/turn_on_play_sound.h" +#include "titanic/core/turn_on_turn_off.h" +#include "titanic/core/tree_item.h" +#include "titanic/core/view_item.h" + +#include "titanic/game/announce.h" +#include "titanic/game/annoy_barbot.h" +#include "titanic/game/arb_background.h" +#include "titanic/game/arboretum_gate.h" +#include "titanic/game/auto_animate.h" +#include "titanic/game/bar_bell.h" +#include "titanic/game/bar_menu.h" +#include "titanic/game/bar_menu_button.h" +#include "titanic/game/belbot_get_light.h" +#include "titanic/game/bilge_succubus.h" +#include "titanic/game/bomb.h" +#include "titanic/game/bottom_of_well_monitor.h" +#include "titanic/game/bowl_unlocker.h" +#include "titanic/game/brain_slot.h" +#include "titanic/game/bridge_door.h" +#include "titanic/game/bridge_view.h" +#include "titanic/game/broken_pell_base.h" +#include "titanic/game/broken_pellerator.h" +#include "titanic/game/broken_pellerator_froz.h" +#include "titanic/game/cage.h" +#include "titanic/game/call_pellerator.h" +#include "titanic/game/captains_wheel.h" +#include "titanic/game/cdrom.h" +#include "titanic/game/cdrom_computer.h" +#include "titanic/game/cdrom_tray.h" +#include "titanic/game/cell_point_button.h" +#include "titanic/game/chev_code.h" +#include "titanic/game/chev_panel.h" +#include "titanic/game/chicken_cooler.h" +#include "titanic/game/chicken_dispensor.h" +#include "titanic/game/close_broken_pel.h" +#include "titanic/game/computer.h" +#include "titanic/game/computer_screen.h" +#include "titanic/game/code_wheel.h" +#include "titanic/game/cookie.h" +#include "titanic/game/credits.h" +#include "titanic/game/credits_button.h" +#include "titanic/game/dead_area.h" +#include "titanic/game/desk_click_responder.h" +#include "titanic/game/doorbot_elevator_handler.h" +#include "titanic/game/doorbot_home_handler.h" +#include "titanic/game/ear_sweet_bowl.h" +#include "titanic/game/eject_phonograph_button.h" +#include "titanic/game/elevator_action_area.h" +#include "titanic/game/emma_control.h" +#include "titanic/game/empty_nut_bowl.h" +#include "titanic/game/end_credit_text.h" +#include "titanic/game/end_credits.h" +#include "titanic/game/end_explode_ship.h" +#include "titanic/game/end_game_credits.h" +#include "titanic/game/end_sequence_control.h" +#include "titanic/game/fan.h" +#include "titanic/game/fan_control.h" +#include "titanic/game/fan_decrease.h" +#include "titanic/game/fan_increase.h" +#include "titanic/game/fan_noises.h" +#include "titanic/game/floor_indicator.h" +#include "titanic/game/games_console.h" +#include "titanic/game/get_lift_eye2.h" +#include "titanic/game/glass_smasher.h" +#include "titanic/game/hammer_clip.h" +#include "titanic/game/hammer_dispensor.h" +#include "titanic/game/hammer_dispensor_button.h" +#include "titanic/game/head_slot.h" +#include "titanic/game/head_smash_event.h" +#include "titanic/game/head_smash_lever.h" +#include "titanic/game/head_spinner.h" +#include "titanic/game/idle_summoner.h" +#include "titanic/game/leave_sec_class_state.h" +#include "titanic/game/lemon_dispensor.h" +#include "titanic/game/light.h" +#include "titanic/game/light_switch.h" +#include "titanic/game/little_lift_button.h" +#include "titanic/game/long_stick_dispenser.h" +#include "titanic/game/missiveomat.h" +#include "titanic/game/missiveomat_button.h" +#include "titanic/game/movie_tester.h" +#include "titanic/game/musical_instrument.h" +#include "titanic/game/music_console_button.h" +#include "titanic/game/music_room_phonograph.h" +#include "titanic/game/music_room_stop_phonograph_button.h" +#include "titanic/game/music_system_lock.h" +#include "titanic/game/nav_helmet.h" +#include "titanic/game/navigation_computer.h" +#include "titanic/game/no_nut_bowl.h" +#include "titanic/game/nose_holder.h" +#include "titanic/game/null_port_hole.h" +#include "titanic/game/nut_replacer.h" +#include "titanic/game/pet_disabler.h" +#include "titanic/game/phonograph.h" +#include "titanic/game/phonograph_lid.h" +#include "titanic/game/play_music_button.h" +#include "titanic/game/play_on_act.h" +#include "titanic/game/port_hole.h" +#include "titanic/game/record_phonograph_button.h" +#include "titanic/game/replacement_ear.h" +#include "titanic/game/reserved_table.h" +#include "titanic/game/restaurant_cylinder_holder.h" +#include "titanic/game/restaurant_phonograph.h" +#include "titanic/game/sauce_dispensor.h" +#include "titanic/game/search_point.h" +#include "titanic/game/season_background.h" +#include "titanic/game/season_barrel.h" +#include "titanic/game/seasonal_adjustment.h" +#include "titanic/game/service_elevator_window.h" +#include "titanic/game/ship_setting.h" +#include "titanic/game/ship_setting_button.h" +#include "titanic/game/show_cell_points.h" +#include "titanic/game/speech_dispensor.h" +#include "titanic/game/splash_animation.h" +#include "titanic/game/starling_puret.h" +#include "titanic/game/start_action.h" +#include "titanic/game/stop_phonograph_button.h" +#include "titanic/game/sub_glass.h" +#include "titanic/game/sub_wrapper.h" +#include "titanic/game/sweet_bowl.h" +#include "titanic/game/television.h" +#include "titanic/game/third_class_canal.h" +#include "titanic/game/throw_tv_down_well.h" +#include "titanic/game/titania_still_control.h" +#include "titanic/game/tow_parrot_nav.h" +#include "titanic/game/up_lighter.h" +#include "titanic/game/useless_lever.h" +#include "titanic/game/volume_control.h" +#include "titanic/game/wheel_button.h" +#include "titanic/game/wheel_hotspot.h" +#include "titanic/game/wheel_spin.h" +#include "titanic/game/wheel_spin_horn.h" +#include "titanic/game/gondolier/gondolier_base.h" +#include "titanic/game/gondolier/gondolier_chest.h" +#include "titanic/game/gondolier/gondolier_face.h" +#include "titanic/game/gondolier/gondolier_mixer.h" +#include "titanic/game/gondolier/gondolier_slider.h" +#include "titanic/game/maitred/maitred_arm_holder.h" +#include "titanic/game/maitred/maitred_body.h" +#include "titanic/game/maitred/maitred_legs.h" +#include "titanic/game/maitred/maitred_prod_receptor.h" +#include "titanic/game/parrot/parrot_lobby_controller.h" +#include "titanic/game/parrot/parrot_lobby_link_updater.h" +#include "titanic/game/parrot/parrot_lobby_object.h" +#include "titanic/game/parrot/parrot_lobby_view_object.h" +#include "titanic/game/parrot/parrot_loser.h" +#include "titanic/game/parrot/parrot_nut_bowl_actor.h" +#include "titanic/game/parrot/parrot_nut_eater.h" +#include "titanic/game/parrot/parrot_perch_holder.h" +#include "titanic/game/parrot/parrot_succubus.h" +#include "titanic/game/parrot/parrot_trigger.h" +#include "titanic/game/parrot/player_meets_parrot.h" +#include "titanic/game/pet/pet.h" +#include "titanic/game/pet/pet_class1.h" +#include "titanic/game/pet/pet_class2.h" +#include "titanic/game/pet/pet_class3.h" +#include "titanic/game/pet/pet_lift.h" +#include "titanic/game/pet/pet_monitor.h" +#include "titanic/game/pet/pet_pellerator.h" +#include "titanic/game/pet/pet_position.h" +#include "titanic/game/pet/pet_sentinal.h" +#include "titanic/game/pet/pet_sounds.h" +#include "titanic/game/pet/pet_transition.h" +#include "titanic/game/pet/pet_transport.h" +#include "titanic/game/pickup/pick_up.h" +#include "titanic/game/pickup/pick_up_bar_glass.h" +#include "titanic/game/pickup/pick_up_hose.h" +#include "titanic/game/pickup/pick_up_lemon.h" +#include "titanic/game/pickup/pick_up_speech_centre.h" +#include "titanic/game/pickup/pick_up_vis_centre.h" +#include "titanic/game/placeholder/bar_shelf_vis_centre.h" +#include "titanic/game/placeholder/lemon_on_bar.h" +#include "titanic/game/placeholder/place_holder_item.h" +#include "titanic/game/placeholder/tv_on_bar.h" +#include "titanic/game/sgt/armchair.h" +#include "titanic/game/sgt/basin.h" +#include "titanic/game/sgt/bedfoot.h" +#include "titanic/game/sgt/bedhead.h" +#include "titanic/game/sgt/chest_of_drawers.h" +#include "titanic/game/sgt/desk.h" +#include "titanic/game/sgt/deskchair.h" +#include "titanic/game/sgt/drawer.h" +#include "titanic/game/sgt/sgt_doors.h" +#include "titanic/game/sgt/sgt_nav.h" +#include "titanic/game/sgt/sgt_navigation.h" +#include "titanic/game/sgt/sgt_restaurant_doors.h" +#include "titanic/game/sgt/sgt_state_control.h" +#include "titanic/game/sgt/sgt_state_room.h" +#include "titanic/game/sgt/sgt_tv.h" +#include "titanic/game/sgt/sgt_upper_doors_sound.h" +#include "titanic/game/sgt/toilet.h" +#include "titanic/game/sgt/vase.h" +#include "titanic/game/sgt/washstand.h" +#include "titanic/game/transport/gondolier.h" +#include "titanic/game/transport/lift.h" +#include "titanic/game/transport/lift_indicator.h" +#include "titanic/game/transport/pellerator.h" +#include "titanic/game/transport/service_elevator.h" +#include "titanic/game/transport/transport.h" +#include "titanic/gfx/act_button.h" +#include "titanic/gfx/changes_season_button.h" +#include "titanic/gfx/chev_left_off.h" +#include "titanic/gfx/chev_left_on.h" +#include "titanic/gfx/chev_right_off.h" +#include "titanic/gfx/chev_right_on.h" +#include "titanic/gfx/chev_send_rec_switch.h" +#include "titanic/gfx/chev_switch.h" +#include "titanic/gfx/edit_control.h" +#include "titanic/gfx/elevator_button.h" +#include "titanic/gfx/get_from_succ.h" +#include "titanic/gfx/helmet_on_off.h" +#include "titanic/gfx/home_photo.h" +#include "titanic/gfx/icon_nav_action.h" +#include "titanic/gfx/icon_nav_butt.h" +#include "titanic/gfx/icon_nav_down.h" +#include "titanic/gfx/icon_nav_image.h" +#include "titanic/gfx/icon_nav_left.h" +#include "titanic/gfx/icon_nav_receive.h" +#include "titanic/gfx/icon_nav_right.h" +#include "titanic/gfx/icon_nav_send.h" +#include "titanic/gfx/icon_nav_up.h" +#include "titanic/gfx/keybrd_butt.h" +#include "titanic/gfx/move_object_button.h" +#include "titanic/gfx/music_control.h" +#include "titanic/gfx/music_slider_pitch.h" +#include "titanic/gfx/music_slider_speed.h" +#include "titanic/gfx/music_switch.h" +#include "titanic/gfx/music_switch_inversion.h" +#include "titanic/gfx/music_switch_reverse.h" +#include "titanic/gfx/music_voice_mute.h" +#include "titanic/gfx/send_to_succ.h" +#include "titanic/gfx/sgt_selector.h" +#include "titanic/gfx/slider_button.h" +#include "titanic/gfx/small_chev_left_off.h" +#include "titanic/gfx/small_chev_left_on.h" +#include "titanic/gfx/small_chev_right_off.h" +#include "titanic/gfx/small_chev_right_on.h" +#include "titanic/gfx/status_change_button.h" +#include "titanic/gfx/st_button.h" +#include "titanic/gfx/toggle_button.h" +#include "titanic/gfx/text_down.h" +#include "titanic/gfx/text_skrew.h" +#include "titanic/gfx/text_up.h" +#include "titanic/gfx/toggle_switch.h" + +#include "titanic/messages/messages.h" +#include "titanic/messages/auto_sound_event.h" +#include "titanic/messages/bilge_auto_sound_event.h" +#include "titanic/messages/bilge_dispensor_event.h" +#include "titanic/messages/door_auto_sound_event.h" +#include "titanic/messages/mouse_messages.h" +#include "titanic/messages/pet_messages.h" +#include "titanic/messages/service_elevator_door.h" + +#include "titanic/moves/enter_bomb_room.h" +#include "titanic/moves/enter_bridge.h" +#include "titanic/moves/enter_exit_first_class_state.h" +#include "titanic/moves/enter_exit_mini_lift.h" +#include "titanic/moves/enter_exit_sec_class_mini_lift.h" +#include "titanic/moves/enter_exit_view.h" +#include "titanic/moves/enter_sec_class_state.h" +#include "titanic/moves/exit_arboretum.h" +#include "titanic/moves/exit_bridge.h" +#include "titanic/moves/exit_lift.h" +#include "titanic/moves/exit_pellerator.h" +#include "titanic/moves/exit_state_room.h" +#include "titanic/moves/exit_tiania.h" +#include "titanic/moves/move_player_in_parrot_room.h" +#include "titanic/moves/move_player_to.h" +#include "titanic/moves/move_player_to_from.h" +#include "titanic/moves/multi_move.h" +#include "titanic/moves/pan_from_pel.h" +#include "titanic/moves/restaurant_pan_handler.h" +#include "titanic/moves/restricted_move.h" +#include "titanic/moves/scraliontis_table.h" +#include "titanic/moves/trip_down_canal.h" + +#include "titanic/npcs/barbot.h" +#include "titanic/npcs/bellbot.h" +#include "titanic/npcs/callbot.h" +#include "titanic/npcs/deskbot.h" +#include "titanic/npcs/doorbot.h" +#include "titanic/npcs/liftbot.h" +#include "titanic/npcs/maitre_d.h" +#include "titanic/npcs/mobile.h" +#include "titanic/npcs/parrot.h" +#include "titanic/npcs/starlings.h" +#include "titanic/npcs/succubus.h" +#include "titanic/npcs/summon_bots.h" +#include "titanic/npcs/titania.h" +#include "titanic/npcs/true_talk_npc.h" + +#include "titanic/pet_control/pet_control.h" +#include "titanic/pet_control/pet_drag_chev.h" +#include "titanic/pet_control/pet_graphic.h" +#include "titanic/pet_control/pet_graphic2.h" +#include "titanic/pet_control/pet_leaf.h" +#include "titanic/pet_control/pet_mode_off.h" +#include "titanic/pet_control/pet_mode_on.h" +#include "titanic/pet_control/pet_mode_panel.h" +#include "titanic/pet_control/pet_pannel1.h" +#include "titanic/pet_control/pet_pannel2.h" +#include "titanic/pet_control/pet_pannel3.h" + +#include "titanic/sound/auto_music_player.h" +#include "titanic/sound/auto_music_player_base.h" +#include "titanic/sound/auto_sound_player.h" +#include "titanic/sound/auto_sound_player_adsr.h" +#include "titanic/sound/background_sound_maker.h" +#include "titanic/sound/bird_song.h" +#include "titanic/sound/dome_from_top_of_well.h" +#include "titanic/sound/gondolier_song.h" +#include "titanic/sound/enter_view_toggles_other_music.h" +#include "titanic/sound/music_player.h" +#include "titanic/sound/node_auto_sound_player.h" +#include "titanic/sound/restricted_auto_music_player.h" +#include "titanic/sound/room_auto_sound_player.h" +#include "titanic/sound/room_trigger_auto_music_player.h" +#include "titanic/sound/season_noises.h" +#include "titanic/sound/seasonal_music_player.h" +#include "titanic/sound/titania_speech.h" +#include "titanic/sound/trigger_auto_music_player.h" +#include "titanic/sound/view_auto_sound_player.h" +#include "titanic/sound/view_toggles_other_music.h" +#include "titanic/sound/water_lapping_sounds.h" + +#include "titanic/star_control/star_control.h" +#include "titanic/support/time_event_info.h" + +namespace Titanic { + +CSaveableObject *ClassDef::create() { + return new CSaveableObject(); +} + +/*------------------------------------------------------------------------*/ + +Common::HashMap<Common::String, CSaveableObject::CreateFunction> * + CSaveableObject::_classList = nullptr; +Common::List<ClassDef *> *CSaveableObject::_classDefs; + +#define DEFFN(T) CSaveableObject *Function##T() { return new T(); } \ + ClassDef *T::_type +#define ADDFN(CHILD, PARENT) \ + CHILD::_type = new TypeTemplate<CHILD>(#CHILD, PARENT::_type); \ + (*_classList)[#CHILD] = Function##CHILD + +DEFFN(CArm); +DEFFN(CAuditoryCentre); +DEFFN(CBowlEar); +DEFFN(CBrain); +DEFFN(CBridgePiece); +DEFFN(CCarry); +DEFFN(CCarryParrot); +DEFFN(CCentralCore); +DEFFN(CChicken); +DEFFN(CCrushedTV); +DEFFN(CEar); +DEFFN(CEye); +DEFFN(CFeathers); +DEFFN(CFruit); +DEFFN(CGlass); +DEFFN(CHammer); +DEFFN(CHeadPiece); +DEFFN(CHose); +DEFFN(CHoseEnd); +DEFFN(CKey); +DEFFN(CLiftbotHead); +DEFFN(CLongStick); +DEFFN(CMagazine); +DEFFN(CMaitreDLeftArm); +DEFFN(CMaitreDRightArm); +DEFFN(CMouth); +DEFFN(CNapkin); +DEFFN(CNose); +DEFFN(CNote); +DEFFN(CParcel); +DEFFN(CPerch); +DEFFN(CPhonographCylinder); +DEFFN(CPhonographEar); +DEFFN(CPhotograph); +DEFFN(CPlugIn); +DEFFN(CSpeechCentre); +DEFFN(CSweets); +DEFFN(CVisionCentre); + +DEFFN(CBackground); +DEFFN(CClickResponder); +DEFFN(CDontSaveFileItem); +DEFFN(CDropTarget); +DEFFN(CFileItem); +DEFFN(CFileListItem); +DEFFN(CGameObject); +DEFFN(CGameObjectDescItem); +DEFFN(CLinkItem); +DEFFN(ListItem); +DEFFN(CMailMan); +DEFFN(CMessageTarget); +DEFFN(CMovieClip); +DEFFN(CMultiDropTarget); +DEFFN(CNamedItem); +DEFFN(CNodeItem); +DEFFN(CProjectItem); +DEFFN(CResourceKey); +DEFFN(CRoomItem); +DEFFN(CSaveableObject); +DEFFN(CStaticImage); +DEFFN(CTurnOnObject); +DEFFN(CTurnOnPlaySound); +DEFFN(CTurnOnTurnOff); +DEFFN(CTreeItem); +DEFFN(CViewItem); + +DEFFN(CAnnounce); +DEFFN(CAnnoyBarbot); +DEFFN(CArbBackground); +DEFFN(CArboretumGate); +DEFFN(CAutoAnimate); +DEFFN(CBarBell); +DEFFN(CBarMenu); +DEFFN(CBarMenuButton); +DEFFN(CBelbotGetLight); +DEFFN(CBilgeSuccUBus); +DEFFN(CBomb); +DEFFN(CBottomOfWellMonitor); +DEFFN(CBowlUnlocker); +DEFFN(CBrainSlot); +DEFFN(CBridgeDoor); +DEFFN(CBridgeView); +DEFFN(CBrokenPellBase); +DEFFN(CBrokenPellerator); +DEFFN(CBrokenPelleratorFroz); +DEFFN(CCage); +DEFFN(CCallPellerator); +DEFFN(CCaptainsWheel); +DEFFN(CCDROM); +DEFFN(CCDROMComputer); +DEFFN(CCDROMTray); +DEFFN(CCellPointButton); +DEFFN(CChevCode); +DEFFN(CChevPanel); +DEFFN(CChickenCooler); +DEFFN(CChickenDispensor); +DEFFN(CCloseBrokenPel); +DEFFN(CodeWheel); +DEFFN(CComputer); +DEFFN(CComputerScreen); +DEFFN(CCookie); +DEFFN(CCredits); +DEFFN(CCreditsButton); +DEFFN(CDeadArea); +DEFFN(CDeskClickResponder); +DEFFN(CDoorbotElevatorHandler); +DEFFN(CDoorbotHomeHandler); +DEFFN(CEarSweetBowl); +DEFFN(CEjectPhonographButton); +DEFFN(CElevatorActionArea); +DEFFN(CEmmaControl); +DEFFN(CEmptyNutBowl); +DEFFN(CEndCreditText); +DEFFN(CEndCredits); +DEFFN(CEndExplodeShip); +DEFFN(CEndGameCredits); +DEFFN(CEndSequenceControl); +DEFFN(CFan); +DEFFN(CFanControl); +DEFFN(CFanDecrease); +DEFFN(CFanIncrease); +DEFFN(CFanNoises); +DEFFN(CFloorIndicator); +DEFFN(CGamesConsole); +DEFFN(CGetLiftEye2); +DEFFN(CGlassSmasher); +DEFFN(CHammerClip); +DEFFN(CHammerDispensor); +DEFFN(CHammerDispensorButton); +DEFFN(CHeadSlot); +DEFFN(CHeadSmashEvent); +DEFFN(CHeadSmashLever); +DEFFN(CHeadSpinner); +DEFFN(CIdleSummoner); +DEFFN(CLeaveSecClassState); +DEFFN(CLemonDispensor); +DEFFN(CLight); +DEFFN(CLightSwitch); +DEFFN(CLittleLiftButton); +DEFFN(CLongStickDispenser); +DEFFN(CMissiveOMat); +DEFFN(CMissiveOMatButton); +DEFFN(CMovieTester); +DEFFN(CMusicalInstrument); +DEFFN(CMusicConsoleButton); +DEFFN(CMusicRoomPhonograph); +DEFFN(CMusicRoomStopPhonographButton); +DEFFN(CMusicSystemLock); +DEFFN(CNavHelmet); +DEFFN(CNavigationComputer); +DEFFN(CNoNutBowl); +DEFFN(CNoseHolder); +DEFFN(CNullPortHole); +DEFFN(CNutReplacer); +DEFFN(CPetDisabler); +DEFFN(CPhonograph); +DEFFN(CPhonographLid); +DEFFN(CPlayMusicButton); +DEFFN(CPlayOnAct); +DEFFN(CPortHole); +DEFFN(CRecordPhonographButton); +DEFFN(CReplacementEar); +DEFFN(CReservedTable); +DEFFN(CRestaurantCylinderHolder); +DEFFN(CRestaurantPhonograph); +DEFFN(CSauceDispensor); +DEFFN(CSearchPoint); +DEFFN(CSeasonBackground); +DEFFN(CSeasonBarrel); +DEFFN(CSeasonalAdjustment); +DEFFN(CServiceElevatorWindow); +DEFFN(CShipSetting); +DEFFN(CShipSettingButton); +DEFFN(CShowCellpoints); +DEFFN(CSpeechDispensor); +DEFFN(CSplashAnimation); +DEFFN(CStarlingPuret); +DEFFN(CStartAction); +DEFFN(CStopPhonographButton); +DEFFN(CSUBGlass); +DEFFN(CSUBWrapper); +DEFFN(CSweetBowl); +DEFFN(CTelevision); +DEFFN(CThirdClassCanal); +DEFFN(CThrowTVDownWell); +DEFFN(CTitaniaStillControl); +DEFFN(CTOWParrotNav); +DEFFN(CUpLighter); +DEFFN(CUselessLever); +DEFFN(CVolumeControl); +DEFFN(CWheelButton); +DEFFN(CWheelHotSpot); +DEFFN(CWheelSpin); +DEFFN(CWheelSpinHorn); +DEFFN(CGondolierBase); +DEFFN(CGondolierChest); +DEFFN(CGondolierFace); +DEFFN(CGondolierMixer); +DEFFN(CGondolierSlider); +DEFFN(CMaitreDArmHolder); +DEFFN(CMaitreDBody); +DEFFN(CMaitreDLegs); +DEFFN(CMaitreDProdReceptor); +DEFFN(CParrotLobbyController); +DEFFN(CParrotLobbyLinkUpdater); +DEFFN(CParrotLobbyObject); +DEFFN(CParrotLobbyViewObject); +DEFFN(CParrotLoser); +DEFFN(CParrotNutBowlActor); +DEFFN(CParrotNutEater); +DEFFN(CParrotPerchHolder); +DEFFN(CParrotSuccUBus); +DEFFN(CParrotTrigger); +DEFFN(CPlayerMeetsParrot); +DEFFN(CPET); +DEFFN(CPETClass1); +DEFFN(CPETClass2); +DEFFN(CPETClass3); +DEFFN(CPetControl); +DEFFN(CPetDragChev); +DEFFN(CPetGraphic); +DEFFN(CPetGraphic2); +DEFFN(PETLeaf); +DEFFN(CPETLift); +DEFFN(CPETMonitor); +DEFFN(CPETPellerator); +DEFFN(CPETPosition); +DEFFN(CPETSentinal); +DEFFN(CPETSounds); +DEFFN(CPETTransition); +DEFFN(CPETTransport); +DEFFN(CPickUp); +DEFFN(CPickUpBarGlass); +DEFFN(CPickUpHose); +DEFFN(CPickUpLemon); +DEFFN(CPickUpSpeechCentre); +DEFFN(CPickUpVisCentre); +DEFFN(CBarShelfVisCentre); +DEFFN(CLemonOnBar); +DEFFN(CPlaceHolderItem); +DEFFN(CTVOnBar); +DEFFN(CArmchair); +DEFFN(CBasin); +DEFFN(CBedfoot); +DEFFN(CBedhead); +DEFFN(CChestOfDrawers); +DEFFN(CDesk); +DEFFN(CDeskchair); +DEFFN(CDrawer); +DEFFN(CSGTDoors); +DEFFN(SGTNav); +DEFFN(CSGTNavigation); +DEFFN(CSGTRestaurantDoors); +DEFFN(CSGTStateControl); +DEFFN(CSGTStateRoom); +DEFFN(CSGTTV); +DEFFN(CSGTUpperDoorsSound); +DEFFN(CToilet); +DEFFN(CVase); +DEFFN(CWashstand); + +DEFFN(CGondolier); +DEFFN(CLift); +DEFFN(CLiftindicator); +DEFFN(CPellerator); +DEFFN(CServiceElevator); +DEFFN(CTransport); + +DEFFN(CActButton); +DEFFN(CChangesSeasonButton); +DEFFN(CChevLeftOff); +DEFFN(CChevLeftOn); +DEFFN(CChevRightOff); +DEFFN(CChevRightOn); +DEFFN(CChevSendRecSwitch); +DEFFN(CChevSwitch); +DEFFN(CEditControl); +DEFFN(CElevatorButton); +DEFFN(CGetFromSucc); +DEFFN(CHelmetOnOff); +DEFFN(CHomePhoto); +DEFFN(CIconNavAction); +DEFFN(CIconNavButt); +DEFFN(CIconNavDown); +DEFFN(CIconNavImage); +DEFFN(CIconNavLeft); +DEFFN(CIconNavReceive); +DEFFN(CIconNavRight); +DEFFN(CIconNavSend); +DEFFN(CIconNavUp); +DEFFN(CKeybrdButt); +DEFFN(CMoveObjectButton); +DEFFN(CMusicControl); +DEFFN(CMusicSlider); +DEFFN(CMusicSliderPitch); +DEFFN(CMusicSliderSpeed); +DEFFN(CMusicSwitch); +DEFFN(CMusicSwitchInversion); +DEFFN(CMusicSwitchReverse); +DEFFN(CMusicVoiceMute); +DEFFN(CPetModeOff); +DEFFN(CPetModeOn); +DEFFN(CPetModePanel); +DEFFN(CPetPannel1); +DEFFN(CPetPannel2); +DEFFN(CPetPannel3); +DEFFN(CSendToSucc); +DEFFN(CSGTSelector); +DEFFN(CSliderButton); +DEFFN(CSmallChevLeftOff); +DEFFN(CSmallChevLeftOn); +DEFFN(CSmallChevRightOff); +DEFFN(CSmallChevRightOn); +DEFFN(CStatusChangeButton); +DEFFN(CSTButton); +DEFFN(CTextDown); +DEFFN(CTextSkrew); +DEFFN(CTextUp); +DEFFN(CToggleButton); +DEFFN(CToggleSwitch); + +DEFFN(CActMsg); +DEFFN(CActivationmsg); +DEFFN(CAddHeadPieceMsg); +DEFFN(CAnimateMaitreDMsg); +DEFFN(CArboretumGateMsg); +DEFFN(CArmPickedUpFromTableMsg); +DEFFN(CAutoSoundEvent); +DEFFN(CBilgeAutoSoundEvent); +DEFFN(CBilgeDispensorEvent); +DEFFN(CBodyInBilgeRoomMsg); +DEFFN(CBowlStateChange); +DEFFN(CCarryObjectArrivedMsg); +DEFFN(CChangeMusicMsg); +DEFFN(CChangeSeasonMsg); +DEFFN(CCheckAllPossibleCodes); +DEFFN(CCheckChevCode); +DEFFN(CChildDragEndMsg); +DEFFN(CChildDragMoveMsg); +DEFFN(CChildDragStartMsg); +DEFFN(CClearChevPanelBits); +DEFFN(CCorrectMusicPlayedMsg); +DEFFN(CCreateMusicPlayerMsg); +DEFFN(CCylinderHolderReadyMsg); +DEFFN(CDeactivationMsg); +DEFFN(CDeliverCCarryMsg); +DEFFN(CDisableMaitreDProdReceptor); +DEFFN(CDismissBotMsg); +DEFFN(CDoffNavHelmet); +DEFFN(CDonNavHelmet); +DEFFN(CDoorAutoSoundEvent); +DEFFN(CDoorbotNeededInElevatorMsg); +DEFFN(CDoorbotNeededInHomeMsg); +DEFFN(CDropObjectMsg); +DEFFN(CDropZoneGotObjectMsg); +DEFFN(CDropZoneLostObjectMsg); +DEFFN(CEditControlMsg); +DEFFN(CEnterNodeMsg); +DEFFN(CEnterRoomMsg); +DEFFN(CEnterViewMsg); +DEFFN(CEjectCylinderMsg); +DEFFN(CErasePhonographCylinderMsg); +DEFFN(CFrameMsg); +DEFFN(CFreshenCookieMsg); +DEFFN(CGetChevClassBits); +DEFFN(CGetChevClassNum); +DEFFN(CGetChevCodeFromRoomNameMsg); +DEFFN(CGetChevFloorBits); +DEFFN(CGetChevFloorNum); +DEFFN(CGetChevLiftBits); +DEFFN(CGetChevLiftNum); +DEFFN(CGetChevRoomBits); +DEFFN(CGetChevRoomNum); +DEFFN(CHoseConnectedMsg); +DEFFN(CInitializeAnimMsg); +DEFFN(CIsEarBowlPuzzleDone); +DEFFN(CIsHookedOnMsg); +DEFFN(CIsParrotPresentMsg); +DEFFN(CKeyCharMsg); +DEFFN(CLeaveNodeMsg); +DEFFN(CLeaveRoomMsg); +DEFFN(CLeaveViewMsg); +DEFFN(CLemonFallsFromTreeMsg); +DEFFN(CLightsMsg); +DEFFN(CLoadSuccessMsg); +DEFFN(CLockPhonographMsg); +DEFFN(CMaitreDDefeatedMsg); +DEFFN(CMaitreDHappyMsg); +DEFFN(CMessage); +DEFFN(CMissiveOMatActionMsg); +DEFFN(CMouseMsg); +DEFFN(CMouseMoveMsg); +DEFFN(CMouseButtonMsg); +DEFFN(CMouseButtonDownMsg); +DEFFN(CMouseButtonUpMsg); +DEFFN(CMouseDoubleClickMsg); +DEFFN(CMouseDragMsg); +DEFFN(CMouseDragStartMsg); +DEFFN(CMouseDragMoveMsg); +DEFFN(CMouseDragEndMsg); +DEFFN(CMoveToStartPosMsg); +DEFFN(CMovieEndMsg); +DEFFN(CMovieFrameMsg); +DEFFN(CMusicHasStartedMsg); +DEFFN(CMusicHasStoppedMsg); +DEFFN(CMusicSettingChangedMsg); +DEFFN(CNPCPlayAnimationMsg); +DEFFN(CNPCPlayIdleAnimationMsg); +DEFFN(CNPCPlayTalkingAnimationMsg); +DEFFN(CNPCQueueIdleAnimMsg); +DEFFN(CNutPuzzleMsg); +DEFFN(COnSummonBotMsg); +DEFFN(COpeningCreditsMsg); +DEFFN(CPETDeliverMsg); +DEFFN(CPETGainedObjectMsg); +DEFFN(CPETHelmetOnOffMsg); +DEFFN(CPETKeyboardOnOffMsg); +DEFFN(CPETLostObjectMsg); +DEFFN(CPETObjectSelectedMsg); +DEFFN(CPETObjectStateMsg); +DEFFN(CPETPhotoOnOffMsg); +DEFFN(CPETPlaySoundMsg); +DEFFN(CPETReceiveMsg); +DEFFN(CPETSetStarDestinationMsg); +DEFFN(CPETStarFieldLockMsg); +DEFFN(CPETStereoFieldOnOffMsg); +DEFFN(CPETTargetMsg); +DEFFN(CPETUpMsg); +DEFFN(CPETDownMsg); +DEFFN(CPETLeftMsg); +DEFFN(CPETRightMsg); +DEFFN(CPETActivateMsg); +DEFFN(CPanningAwayFromParrotMsg); +DEFFN(CParrotSpeakMsg); +DEFFN(CParrotTriesChickenMsg); +DEFFN(CPassOnDragStartMsg); +DEFFN(CPhonographPlayMsg); +DEFFN(CPhonographReadyToPlayMsg); +DEFFN(CPhonographRecordMsg); +DEFFN(CPhonographStopMsg); +DEFFN(CPlayRangeMsg); +DEFFN(CPlayerTriesRestaurantTableMsg); +DEFFN(CPreEnterNodeMsg); +DEFFN(CPreEnterRoomMsg); +DEFFN(CPreEnterViewMsg); +DEFFN(CPreSaveMsg); +DEFFN(CProdMaitreDMsg); +DEFFN(CPumpingMsg); +DEFFN(CPutBotBackInHisBoxMsg); +DEFFN(CPutParrotBackMsg); +DEFFN(CPuzzleSolvedMsg); +DEFFN(CQueryCylinderHolderMsg); +DEFFN(CQueryCylinderMsg); +DEFFN(CQueryCylinderNameMsg); +DEFFN(CQueryCylinderTypeMsg); +DEFFN(CQueryMusicControlSettingMsg); +DEFFN(CQueryPhonographState); +DEFFN(CRecordOntoCylinderMsg); +DEFFN(CRemoveFromGameMsg); +DEFFN(CReplaceBowlAndNutsMsg); +DEFFN(CRestaurantMusicChanged); +DEFFN(CSendCCarryMsg); +DEFFN(CSenseWorkingMsg); +DEFFN(CServiceElevatorDoor); +DEFFN(CServiceElevatorFloorChangeMsg); +DEFFN(CServiceElevatorFloorRequestMsg); +DEFFN(CServiceElevatorMsg); +DEFFN(CSetChevButtonImageMsg); +DEFFN(CSetChevClassBits); +DEFFN(CSetChevFloorBits); +DEFFN(CSetChevLiftBits); +DEFFN(CSetChevPanelBitMsg); +DEFFN(CSetChevPanelButtonsMsg); +DEFFN(CSetChevRoomBits); +DEFFN(CSetFrameMsg); +DEFFN(CSetMusicControlsMsg); +DEFFN(CSetVarMsg); +DEFFN(CSetVolumeMsg); +DEFFN(CShipSettingMsg); +DEFFN(CShowTextMsg); +DEFFN(CSignalObject); +DEFFN(CSpeechFallsFromTreeMsg); +DEFFN(CStartMusicMsg); +DEFFN(CStatusChangeMsg); +DEFFN(CStopMusicMsg); +DEFFN(CSubAcceptCCarryMsg); +DEFFN(CSubDeliverCCarryMsg); +DEFFN(CSubSendCCarryMsg); +DEFFN(CSUBTransition); +DEFFN(CSubTurnOffMsg); +DEFFN(CSubTurnOnMsg); +DEFFN(CSummonBotMsg); +DEFFN(CSummonBotQueryMsg); +DEFFN(CTakeHeadPieceMsg); +DEFFN(CTextInputMsg); +DEFFN(CTimeDilationMsg); +DEFFN(CTimeMsg); +DEFFN(CTimerMsg); +DEFFN(CTitleSequenceEndedMsg); +DEFFN(CTransitMsg); +DEFFN(CTranslateObjectMsg); +DEFFN(CTransportMsg); +DEFFN(CTriggerAutoMusicPlayerMsg); +DEFFN(CTriggerNPCEvent); +DEFFN(CTrueTalkGetAnimSetMsg); +DEFFN(CTrueTalkGetAssetDetailsMsg); +DEFFN(CTrueTalkGetStateValueMsg); +DEFFN(CTrueTalkNotifySpeechEndedMsg); +DEFFN(CTrueTalkNotifySpeechStartedMsg); +DEFFN(CTrueTalkQueueUpAnimSetMsg); +DEFFN(CTrueTalkSelfQueueAnimSetMsg); +DEFFN(CTrueTalkTriggerActionMsg); +DEFFN(CTurnOff); +DEFFN(CTurnOn); +DEFFN(CUse); +DEFFN(CUseWithCharMsg); +DEFFN(CUseWithOtherMsg); +DEFFN(CVirtualKeyCharMsg); +DEFFN(CVisibleMsg); + +DEFFN(CEnterBombRoom); +DEFFN(CEnterBridge); +DEFFN(CEnterExitFirstClassState); +DEFFN(CEnterExitMiniLift); +DEFFN(CEnterExitSecClassMiniLift); +DEFFN(CEnterExitView); +DEFFN(CEnterSecClassState); +DEFFN(CExitArboretum); +DEFFN(CExitBridge); +DEFFN(CExitLift); +DEFFN(CExitPellerator); +DEFFN(CExitStateRoom); +DEFFN(CExitTiania); +DEFFN(CMovePlayerInParrotRoom); +DEFFN(CMovePlayerTo); +DEFFN(CMovePlayerToFrom); +DEFFN(CMultiMove); +DEFFN(CPanFromPel); +DEFFN(CRestaurantPanHandler); +DEFFN(CScraliontisTable); +DEFFN(CRestrictedMove); +DEFFN(CTripDownCanal); + +DEFFN(CBarbot); +DEFFN(CBellBot); +DEFFN(CCallBot); +DEFFN(CCharacter); +DEFFN(CDeskbot); +DEFFN(CDoorbot); +DEFFN(CLiftBot); +DEFFN(CMaitreD); +DEFFN(CMobile); +DEFFN(CParrot); +DEFFN(CRobotController); +DEFFN(CStarlings); +DEFFN(CSummonBots); +DEFFN(CSuccUBus); +DEFFN(CTitania); +DEFFN(CTrueTalkNPC); +DEFFN(CAutoMusicPlayer); +DEFFN(CAutoMusicPlayerBase); +DEFFN(CAutoSoundPlayer); +DEFFN(CAutoSoundPlayerADSR); +DEFFN(CBackgroundSoundMaker); +DEFFN(CBirdSong); +DEFFN(CDomeFromTopOfWell); +DEFFN(CEnterViewTogglesOtherMusic); +DEFFN(CGondolierSong); +DEFFN(CMusicPlayer); +DEFFN(CNodeAutoSoundPlayer); +DEFFN(CRestrictedAutoMusicPlayer); +DEFFN(CRoomAutoSoundPlayer); +DEFFN(CRoomTriggerAutoMusicPlayer); +DEFFN(CSeasonNoises); +DEFFN(CSeasonalMusicPlayer); +DEFFN(CTitaniaSpeech); +DEFFN(CTriggerAutoMusicPlayer); +DEFFN(CViewAutoSoundPlayer); +DEFFN(CViewTogglesOtherMusic); +DEFFN(CWaterLappingSounds); +DEFFN(CStarControl); +DEFFN(CTimeEventInfo); + +void CSaveableObject::initClassList() { + _classDefs = new Common::List<ClassDef *>(); + _classList = new Common::HashMap<Common::String, CreateFunction>(); + ADDFN(CArm, CCarry); + ADDFN(CAuditoryCentre, CBrain); + ADDFN(CBowlEar, CEar); + ADDFN(CBrain, CCarry); + ADDFN(CBridgePiece, CCarry); + ADDFN(CCarry, CGameObject); + ADDFN(CCarryParrot, CCarry); + ADDFN(CCentralCore, CBrain); + ADDFN(CChicken, CCarry); + ADDFN(CCrushedTV, CCarry); + ADDFN(CEar, CHeadPiece); + ADDFN(CEye, CHeadPiece); + ADDFN(CFeathers, CCarry); + ADDFN(CFruit, CCarry); + ADDFN(CGlass, CCarry); + ADDFN(CHammer, CCarry); + ADDFN(CHeadPiece, CCarry); + ADDFN(CHose, CCarry); + ADDFN(CHoseEnd, CHose); + ADDFN(CKey, CCarry); + ADDFN(CLiftbotHead, CCarry); + ADDFN(CLongStick, CCarry); + ADDFN(CMagazine, CCarry); + ADDFN(CMaitreDLeftArm, CArm); + ADDFN(CMaitreDRightArm, CArm); + ADDFN(CMouth, CHeadPiece); + ADDFN(CNapkin, CCarry); + ADDFN(CNose, CHeadPiece); + ADDFN(CNote, CCarry); + ADDFN(CParcel, CCarry); + ADDFN(CPerch, CCentralCore); + ADDFN(CPhonographCylinder, CCarry); + ADDFN(CPhonographEar, CEar); + ADDFN(CPhotograph, CCarry); + ADDFN(CPlugIn, CCarry); + ADDFN(CSpeechCentre, CBrain); + ADDFN(CSweets, CCarry); + ADDFN(CVisionCentre, CBrain); + + ADDFN(CBackground, CGameObject); + ADDFN(CClickResponder, CGameObject); + ADDFN(CDontSaveFileItem, CFileItem); + ADDFN(CDropTarget, CGameObject); + ADDFN(CFileItem, CTreeItem); + ADDFN(CFileListItem, ListItem); + ADDFN(CGameObject, CNamedItem); + ADDFN(CGameObjectDescItem, CTreeItem); + ADDFN(CLinkItem, CNamedItem); + ADDFN(ListItem, CSaveableObject); + ADDFN(CMessageTarget, CSaveableObject); + ADDFN(CMailMan, CGameObject); + ADDFN(CMovieClip, ListItem); + ADDFN(CMultiDropTarget, CDropTarget); + ADDFN(CNamedItem, CTreeItem); + ADDFN(CNodeItem, CNamedItem); + ADDFN(CProjectItem, CFileItem); + ADDFN(CResourceKey, CSaveableObject); + ADDFN(CRoomItem, CNamedItem); + ADDFN(CSaveableObject, CSaveableObject); + ADDFN(CStaticImage, CGameObject); + ADDFN(CTurnOnObject, CBackground); + ADDFN(CTreeItem, CMessageTarget); + ADDFN(CTurnOnPlaySound, CTurnOnObject); + ADDFN(CTurnOnTurnOff, CBackground); + ADDFN(CViewItem, CNamedItem); + + ADDFN(CAnnounce, CGameObject); + ADDFN(CAnnoyBarbot, CGameObject); + ADDFN(CArbBackground, CBackground); + ADDFN(CArboretumGate, CBackground); + ADDFN(CAutoAnimate, CBackground); + ADDFN(CBarBell, CGameObject); + ADDFN(CBarMenu, CGameObject); + ADDFN(CBarMenuButton, CGameObject); + ADDFN(CBelbotGetLight, CGameObject); + ADDFN(CBilgeSuccUBus, CSuccUBus); + ADDFN(CBomb, CBackground); + ADDFN(CBottomOfWellMonitor, CGameObject); + ADDFN(CBowlUnlocker, CGameObject); + ADDFN(CBrainSlot, CGameObject); + ADDFN(CBridgeDoor, CGameObject); + ADDFN(CBridgeView, CBackground); + ADDFN(CBrokenPellBase, CBackground); + ADDFN(CBrokenPellerator, CBrokenPellBase); + ADDFN(CBrokenPelleratorFroz, CBrokenPellBase); + ADDFN(CCage, CBackground); + ADDFN(CCallPellerator, CGameObject); + ADDFN(CCaptainsWheel, CBackground); + ADDFN(CCDROM, CGameObject); + ADDFN(CCDROMComputer, CGameObject); + ADDFN(CCDROMTray, CGameObject); + ADDFN(CCellPointButton, CBackground); + ADDFN(CChevCode, CGameObject); + ADDFN(CChevPanel, CGameObject); + ADDFN(CChickenCooler, CGameObject); + ADDFN(CChickenDispensor, CBackground); + ADDFN(CodeWheel, CBomb); + ADDFN(CCloseBrokenPel, CBackground); + ADDFN(CComputer, CBackground); + ADDFN(CComputerScreen, CGameObject); + ADDFN(CCookie, CGameObject); + ADDFN(CCredits, CGameObject); + ADDFN(CCreditsButton, CBackground); + ADDFN(CDeadArea, CGameObject); + ADDFN(CDeskClickResponder, CClickResponder); + ADDFN(CDoorbotElevatorHandler, CGameObject); + ADDFN(CDoorbotHomeHandler, CGameObject); + ADDFN(CDropTarget, CGameObject); + ADDFN(CEarSweetBowl, CSweetBowl); + ADDFN(CEjectPhonographButton, CBackground); + ADDFN(CElevatorActionArea, CGameObject); + ADDFN(CEmmaControl, CBackground); + ADDFN(CEmptyNutBowl, CGameObject); + ADDFN(CEndCreditText, CGameObject); + ADDFN(CEndCredits, CGameObject); + ADDFN(CEndExplodeShip, CGameObject); + ADDFN(CEndGameCredits, CGameObject); + ADDFN(CEndSequenceControl, CGameObject); + ADDFN(CFan, CGameObject); + ADDFN(CFanControl, CGameObject); + ADDFN(CFanDecrease, CGameObject); + ADDFN(CFanIncrease, CGameObject); + ADDFN(CFanNoises, CGameObject); + ADDFN(CFloorIndicator, CGameObject); + ADDFN(CGamesConsole, CBackground); + ADDFN(CGetLiftEye2, CGameObject); + ADDFN(CGlassSmasher, CGameObject); + ADDFN(CHammerClip, CGameObject); + ADDFN(CHammerDispensor, CBackground); + ADDFN(CHammerDispensorButton, CStartAction); + ADDFN(CHeadSlot, CGameObject); + ADDFN(CHeadSmashEvent, CBackground); + ADDFN(CHeadSmashLever, CBackground); + ADDFN(CHeadSpinner, CGameObject); + ADDFN(CIdleSummoner, CGameObject); + ADDFN(CLeaveSecClassState, CGameObject); + ADDFN(CLemonDispensor, CBackground); + ADDFN(CLight, CBackground); + ADDFN(CLightSwitch, CBackground); + ADDFN(CLittleLiftButton, CBackground); + ADDFN(CLongStickDispenser, CGameObject); + ADDFN(CMissiveOMat, CGameObject); + ADDFN(CMissiveOMatButton, CEditControl); + ADDFN(CMovieTester, CGameObject); + ADDFN(CMusicalInstrument, CBackground); + ADDFN(CMusicConsoleButton, CMusicPlayer); + ADDFN(CMusicRoomPhonograph, CRestaurantPhonograph); + ADDFN(CMusicRoomStopPhonographButton, CEjectPhonographButton); + ADDFN(CMusicSystemLock, CDropTarget); + ADDFN(CNavHelmet, CGameObject); + ADDFN(CNavigationComputer, CGameObject); + ADDFN(CNoNutBowl, CBackground); + ADDFN(CNoseHolder, CDropTarget); + ADDFN(CNullPortHole, CClickResponder); + ADDFN(CNutReplacer, CGameObject); + ADDFN(CPetDisabler, CGameObject); + ADDFN(CPhonograph, CMusicPlayer); + ADDFN(CPhonographLid, CGameObject); + ADDFN(CPlayMusicButton, CBackground); + ADDFN(CPlayOnAct, CBackground); + ADDFN(CPortHole, CGameObject); + ADDFN(CRecordPhonographButton, CBackground); + ADDFN(CReplacementEar, CBackground); + ADDFN(CReservedTable, CGameObject); + ADDFN(CRestaurantCylinderHolder, CDropTarget); + ADDFN(CRestaurantPhonograph, CPhonograph); + ADDFN(CSauceDispensor, CBackground); + ADDFN(CSearchPoint, CGameObject); + ADDFN(CSeasonBackground, CBackground); + ADDFN(CSeasonBarrel, CBackground); + ADDFN(CSeasonalAdjustment, CBackground); + ADDFN(CServiceElevatorWindow, CBackground); + ADDFN(CShipSetting, CBackground); + ADDFN(CShipSettingButton, CGameObject); + ADDFN(CShowCellpoints, CGameObject); + ADDFN(CSpeechDispensor, CBackground); + ADDFN(CSplashAnimation, CGameObject); + ADDFN(CStarlingPuret, CGameObject); + ADDFN(CStartAction, CBackground); + ADDFN(CStopPhonographButton, CBackground); + ADDFN(CSUBGlass, CGameObject); + ADDFN(CSUBWrapper, CGameObject); + ADDFN(CSweetBowl, CGameObject); + ADDFN(CTelevision, CBackground); + ADDFN(CThirdClassCanal, CBackground); + ADDFN(CThrowTVDownWell, CGameObject); + ADDFN(CTitaniaStillControl, CGameObject); + ADDFN(CTOWParrotNav, CGameObject); + ADDFN(CUpLighter, CDropTarget); + ADDFN(CUselessLever, CToggleButton); + ADDFN(CVolumeControl, CGameObject); + ADDFN(CWheelButton, CBackground); + ADDFN(CWheelHotSpot, CBackground); + ADDFN(CWheelSpin, CBackground); + ADDFN(CWheelSpinHorn, CWheelSpin); + ADDFN(CGondolierBase, CGameObject); + ADDFN(CGondolierChest, CGondolierBase); + ADDFN(CGondolierFace, CGondolierBase); + ADDFN(CGondolierMixer, CGondolierBase); + ADDFN(CGondolierSlider, CGondolierBase); + ADDFN(CMaitreDArmHolder, CDropTarget); + ADDFN(CMaitreDBody, CMaitreDProdReceptor); + ADDFN(CMaitreDLegs, CMaitreDProdReceptor); + ADDFN(CMaitreDProdReceptor, CGameObject); + ADDFN(CParrotLobbyController, CParrotLobbyObject); + ADDFN(CParrotLobbyLinkUpdater, CParrotLobbyObject); + ADDFN(CParrotLobbyObject, CGameObject); + ADDFN(CParrotLobbyViewObject, CParrotLobbyObject); + ADDFN(CParrotLoser, CGameObject); + ADDFN(CParrotNutBowlActor, CGameObject); + ADDFN(CParrotNutEater, CGameObject); + ADDFN(CParrotPerchHolder, CMultiDropTarget); + ADDFN(CParrotSuccUBus, CSuccUBus); + ADDFN(CParrotTrigger, CGameObject); + ADDFN(CPlayerMeetsParrot, CGameObject); + ADDFN(CPET, CGameObject); + ADDFN(CPETClass1, CGameObject); + ADDFN(CPETClass2, CGameObject); + ADDFN(CPETClass3, CGameObject); + ADDFN(CPETLift, CPETTransport); + ADDFN(CPETMonitor, CGameObject); + ADDFN(CPETPellerator, CPETTransport); + ADDFN(CPETPosition, CGameObject); + ADDFN(CPETSentinal, CGameObject); + ADDFN(CPETSounds, CGameObject); + ADDFN(CPETTransition, CGameObject); + ADDFN(CPETTransport, CGameObject); + ADDFN(CPickUp, CGameObject); + ADDFN(CPickUpBarGlass, CPickUp); + ADDFN(CPickUpHose, CPickUp); + ADDFN(CPickUpLemon, CPickUp); + ADDFN(CPickUpSpeechCentre, CPickUp); + ADDFN(CPickUpVisCentre, CPickUp); + ADDFN(CBarShelfVisCentre, CPlaceHolderItem); + ADDFN(CLemonOnBar, CPlaceHolderItem); + ADDFN(CPlaceHolderItem, CGameObject); + ADDFN(CTVOnBar, CPlaceHolderItem); + ADDFN(CArmchair, CSGTStateRoom); + ADDFN(CBasin, CSGTStateRoom); + ADDFN(CBedfoot, CSGTStateRoom); + ADDFN(CBedhead, CSGTStateRoom); + ADDFN(CChestOfDrawers, CSGTStateRoom); + ADDFN(CDesk, CSGTStateRoom); + ADDFN(CDeskchair, CSGTStateRoom); + ADDFN(CDrawer, CSGTStateRoom); + ADDFN(CSGTDoors, CGameObject); + ADDFN(SGTNav, CSGTStateRoom); + ADDFN(CSGTNavigation, CGameObject); + ADDFN(CSGTRestaurantDoors, CGameObject); + ADDFN(CSGTStateControl, CBackground); + ADDFN(CSGTStateRoom, CBackground); + ADDFN(CSGTTV, CSGTStateRoom); + ADDFN(CSGTUpperDoorsSound, CClickResponder); + ADDFN(CToilet, CSGTStateRoom); + ADDFN(CVase, CSGTStateRoom); + ADDFN(CWashstand, CSGTStateRoom); + + ADDFN(CGondolier, CTransport); + ADDFN(CLift, CTransport); + ADDFN(CLiftindicator, CLift); + ADDFN(CPellerator, CTransport); + ADDFN(CServiceElevator, CTransport); + ADDFN(CTransport, CMobile); + + ADDFN(CActButton, CSTButton); + ADDFN(CChangesSeasonButton, CSTButton); + ADDFN(CChevLeftOff, CToggleSwitch); + ADDFN(CChevLeftOn, CToggleSwitch); + ADDFN(CChevRightOff, CToggleSwitch); + ADDFN(CChevRightOn, CToggleSwitch); + ADDFN(CChevSendRecSwitch, CToggleSwitch); + ADDFN(CChevSwitch, CToggleSwitch); + ADDFN(CEditControl, CGameObject); + ADDFN(CElevatorButton, CSTButton); + ADDFN(CGetFromSucc, CToggleSwitch); + ADDFN(CHelmetOnOff, CToggleSwitch); + ADDFN(CHomePhoto, CToggleSwitch); + ADDFN(CIconNavAction, CToggleSwitch); + ADDFN(CIconNavButt, CPetGraphic); + ADDFN(CIconNavDown, CToggleSwitch); + ADDFN(CIconNavImage, CPetGraphic); + ADDFN(CIconNavLeft, CToggleSwitch); + ADDFN(CIconNavReceive, CPetGraphic); + ADDFN(CIconNavRight, CToggleSwitch); + ADDFN(CIconNavSend, CPetGraphic); + ADDFN(CIconNavUp, CToggleSwitch); + ADDFN(CKeybrdButt, CToggleSwitch); + ADDFN(CMoveObjectButton, CSTButton); + ADDFN(CMusicControl, CBackground); + ADDFN(CMusicSlider, CMusicControl); + ADDFN(CMusicSliderPitch, CMusicSlider); + ADDFN(CMusicSliderSpeed, CMusicSlider); + ADDFN(CMusicSwitch, CMusicControl); + ADDFN(CMusicSwitchInversion, CMusicSwitch); + ADDFN(CMusicSwitchReverse, CMusicSwitch); + ADDFN(CMusicVoiceMute, CMusicControl); + ADDFN(CPetControl, CGameObject); + ADDFN(CPetDragChev, CPetGraphic2); + ADDFN(CPetGraphic, CGameObject); + ADDFN(CPetGraphic2, CGameObject); + ADDFN(PETLeaf, CGameObject); + ADDFN(CPetModeOff, CToggleSwitch); + ADDFN(CPetModeOn, CToggleSwitch); + ADDFN(CPetModePanel, CToggleSwitch); + ADDFN(CPetPannel1, CPetGraphic); + ADDFN(CPetPannel2, CPetGraphic); + ADDFN(CPetPannel3, CPetGraphic); + ADDFN(CSendToSucc, CToggleSwitch); + ADDFN(CSGTSelector, CPetGraphic); + ADDFN(CSliderButton, CSTButton); + ADDFN(CSmallChevLeftOff, CToggleSwitch); + ADDFN(CSmallChevLeftOn, CToggleSwitch); + ADDFN(CSmallChevRightOff, CToggleSwitch); + ADDFN(CSmallChevRightOn, CToggleSwitch); + ADDFN(CStatusChangeButton, CSTButton); + ADDFN(CSTButton, CBackground); + ADDFN(CTextDown, CPetGraphic); + ADDFN(CTextSkrew, CPetGraphic); + ADDFN(CTextUp, CPetGraphic); + ADDFN(CToggleButton, CBackground); + ADDFN(CToggleSwitch, CGameObject); + + ADDFN(CActMsg, CMessage); + ADDFN(CActivationmsg, CMessage); + ADDFN(CAddHeadPieceMsg, CMessage); + ADDFN(CAnimateMaitreDMsg, CMessage); + ADDFN(CArboretumGateMsg, CMessage); + ADDFN(CArmPickedUpFromTableMsg, CMessage); + ADDFN(CAutoSoundEvent, CGameObject); + ADDFN(CBilgeAutoSoundEvent, CAutoSoundEvent); + ADDFN(CBilgeDispensorEvent, CAutoSoundEvent); + ADDFN(CBodyInBilgeRoomMsg, CMessage); + ADDFN(CBowlStateChange, CMessage); + ADDFN(CCarryObjectArrivedMsg, CMessage); + ADDFN(CChangeMusicMsg, CMessage); + ADDFN(CChangeSeasonMsg, CMessage); + ADDFN(CCheckAllPossibleCodes, CMessage); + ADDFN(CCheckChevCode, CMessage); + ADDFN(CChildDragEndMsg, CMessage); + ADDFN(CChildDragMoveMsg, CMessage); + ADDFN(CChildDragStartMsg, CMessage); + ADDFN(CClearChevPanelBits, CMessage); + ADDFN(CCorrectMusicPlayedMsg, CMessage); + ADDFN(CCreateMusicPlayerMsg, CMessage); + ADDFN(CCylinderHolderReadyMsg, CMessage); + ADDFN(CDeactivationMsg, CMessage); + ADDFN(CDeliverCCarryMsg, CMessage); + ADDFN(CDisableMaitreDProdReceptor, CMessage); + ADDFN(CDismissBotMsg, CMessage); + ADDFN(CDoffNavHelmet, CMessage); + ADDFN(CDonNavHelmet, CMessage); + ADDFN(CDoorAutoSoundEvent, CAutoSoundEvent); + ADDFN(CDoorbotNeededInElevatorMsg, CMessage); + ADDFN(CDoorbotNeededInHomeMsg, CMessage); + ADDFN(CDropObjectMsg, CMessage); + ADDFN(CDropZoneGotObjectMsg, CMessage); + ADDFN(CDropZoneLostObjectMsg, CMessage); + ADDFN(CEditControlMsg, CMessage); + ADDFN(CEnterNodeMsg, CMessage); + ADDFN(CEnterRoomMsg, CMessage); + ADDFN(CEnterViewMsg, CMessage); + ADDFN(CEjectCylinderMsg, CMessage); + ADDFN(CErasePhonographCylinderMsg, CMessage); + ADDFN(CFrameMsg, CMessage); + ADDFN(CFreshenCookieMsg, CMessage); + ADDFN(CGetChevClassBits, CMessage); + ADDFN(CGetChevClassNum, CMessage); + ADDFN(CGetChevCodeFromRoomNameMsg, CMessage); + ADDFN(CGetChevFloorBits, CMessage); + ADDFN(CGetChevFloorNum, CMessage); + ADDFN(CGetChevLiftBits, CMessage); + ADDFN(CGetChevLiftNum, CMessage); + ADDFN(CGetChevRoomBits, CMessage); + ADDFN(CGetChevRoomNum, CMessage); + ADDFN(CHoseConnectedMsg, CMessage); + ADDFN(CInitializeAnimMsg, CMessage); + ADDFN(CIsEarBowlPuzzleDone, CMessage); + ADDFN(CIsHookedOnMsg, CMessage); + ADDFN(CIsParrotPresentMsg, CMessage); + ADDFN(CKeyCharMsg, CMessage); + ADDFN(CLeaveNodeMsg, CMessage); + ADDFN(CLeaveRoomMsg, CMessage); + ADDFN(CLeaveViewMsg, CMessage); + ADDFN(CLemonFallsFromTreeMsg, CMessage); + ADDFN(CLightsMsg, CMessage); + ADDFN(CLoadSuccessMsg, CMessage); + ADDFN(CLockPhonographMsg, CMessage); + ADDFN(CMaitreDDefeatedMsg, CMessage); + ADDFN(CMaitreDHappyMsg, CMessage); + ADDFN(CMessage, CSaveableObject); + ADDFN(CMissiveOMatActionMsg, CMessage); + ADDFN(CMouseMsg, CMessage); + ADDFN(CMouseMoveMsg, CMouseMsg); + ADDFN(CMouseButtonMsg, CMouseMsg); + ADDFN(CMouseButtonDownMsg, CMouseButtonMsg); + ADDFN(CMouseButtonUpMsg, CMouseButtonMsg); + ADDFN(CMouseDoubleClickMsg, CMouseButtonMsg); + ADDFN(CMouseDragMsg, CMouseMsg); + ADDFN(CMouseDragStartMsg, CMouseDragMsg); + ADDFN(CMouseDragMoveMsg, CMouseDragMsg); + ADDFN(CMouseDragEndMsg, CMouseDragMsg); + ADDFN(CMoveToStartPosMsg, CMessage); + ADDFN(CMovieEndMsg, CMessage); + ADDFN(CMovieFrameMsg, CMessage); + ADDFN(CMusicHasStartedMsg, CMessage); + ADDFN(CMusicHasStoppedMsg, CMessage); + ADDFN(CMusicSettingChangedMsg, CMessage); + ADDFN(CNPCPlayAnimationMsg, CMessage); + ADDFN(CNPCPlayIdleAnimationMsg, CMessage); + ADDFN(CNPCPlayTalkingAnimationMsg, CMessage); + ADDFN(CNPCQueueIdleAnimMsg, CMessage); + ADDFN(CNutPuzzleMsg, CMessage); + ADDFN(COnSummonBotMsg, CMessage); + ADDFN(COpeningCreditsMsg, CMessage); + ADDFN(CPETDeliverMsg, CMessage); + ADDFN(CPETGainedObjectMsg, CMessage); + ADDFN(CPETHelmetOnOffMsg, CMessage); + ADDFN(CPETKeyboardOnOffMsg, CMessage); + ADDFN(CPETLostObjectMsg, CMessage); + ADDFN(CPETObjectSelectedMsg, CMessage); + ADDFN(CPETObjectStateMsg, CMessage); + ADDFN(CPETPhotoOnOffMsg, CMessage); + ADDFN(CPETPlaySoundMsg, CMessage); + ADDFN(CPETReceiveMsg, CMessage); + ADDFN(CPETSetStarDestinationMsg, CMessage); + ADDFN(CPETStarFieldLockMsg, CMessage); + ADDFN(CPETStereoFieldOnOffMsg, CMessage); + ADDFN(CPETTargetMsg, CMessage); + ADDFN(CPETUpMsg, CPETTargetMsg); + ADDFN(CPETDownMsg, CPETTargetMsg); + ADDFN(CPETLeftMsg, CPETTargetMsg); + ADDFN(CPETRightMsg, CPETTargetMsg); + ADDFN(CPETActivateMsg, CPETTargetMsg); + ADDFN(CPanningAwayFromParrotMsg, CMessage); + ADDFN(CParrotSpeakMsg, CMessage); + ADDFN(CParrotTriesChickenMsg, CMessage); + ADDFN(CPassOnDragStartMsg, CMessage); + ADDFN(CPhonographPlayMsg, CMessage); + ADDFN(CPhonographReadyToPlayMsg, CMessage); + ADDFN(CPhonographRecordMsg, CMessage); + ADDFN(CPhonographStopMsg, CMessage); + ADDFN(CPlayRangeMsg, CMessage); + ADDFN(CPlayerTriesRestaurantTableMsg, CMessage); + ADDFN(CEnterNodeMsg, CMessage); + ADDFN(CEnterRoomMsg, CMessage); + ADDFN(CEnterViewMsg, CMessage); + ADDFN(CPreSaveMsg, CMessage); + ADDFN(CProdMaitreDMsg, CMessage); + ADDFN(CPumpingMsg, CMessage); + ADDFN(CPutBotBackInHisBoxMsg, CMessage); + ADDFN(CPutParrotBackMsg, CMessage); + ADDFN(CPuzzleSolvedMsg, CMessage); + ADDFN(CQueryCylinderHolderMsg, CMessage); + ADDFN(CQueryCylinderMsg, CMessage); + ADDFN(CQueryCylinderNameMsg, CMessage); + ADDFN(CQueryCylinderTypeMsg, CMessage); + ADDFN(CQueryMusicControlSettingMsg, CMessage); + ADDFN(CQueryPhonographState, CMessage); + ADDFN(CRecordOntoCylinderMsg, CMessage); + ADDFN(CRemoveFromGameMsg, CMessage); + ADDFN(CReplaceBowlAndNutsMsg, CMessage); + ADDFN(CRestaurantMusicChanged, CMessage); + ADDFN(CSendCCarryMsg, CMessage); + ADDFN(CSenseWorkingMsg, CMessage); + ADDFN(CServiceElevatorDoor, CMessage); + ADDFN(CServiceElevatorFloorChangeMsg, CMessage); + ADDFN(CServiceElevatorFloorRequestMsg, CMessage); + ADDFN(CServiceElevatorMsg, CMessage); + ADDFN(CSetChevButtonImageMsg, CMessage); + ADDFN(CSetChevClassBits, CMessage); + ADDFN(CSetChevFloorBits, CMessage); + ADDFN(CSetChevLiftBits, CMessage); + ADDFN(CSetChevPanelBitMsg, CMessage); + ADDFN(CSetChevPanelButtonsMsg, CMessage); + ADDFN(CSetChevRoomBits, CMessage); + ADDFN(CSetFrameMsg, CMessage); + ADDFN(CSetMusicControlsMsg, CMessage); + ADDFN(CSetVarMsg, CMessage); + ADDFN(CSetVolumeMsg, CMessage); + ADDFN(CShipSettingMsg, CMessage); + ADDFN(CShowTextMsg, CMessage); + ADDFN(CSignalObject, CMessage); + ADDFN(CSpeechFallsFromTreeMsg, CMessage); + ADDFN(CStartMusicMsg, CMessage); + ADDFN(CStatusChangeMsg, CMessage); + ADDFN(CStopMusicMsg, CMessage); + ADDFN(CSubAcceptCCarryMsg, CMessage); + ADDFN(CSubDeliverCCarryMsg, CMessage); + ADDFN(CSubSendCCarryMsg, CMessage); + ADDFN(CSUBTransition, CMessage); + ADDFN(CSubTurnOffMsg, CMessage); + ADDFN(CSubTurnOnMsg, CMessage); + ADDFN(CSummonBotMsg, CMessage); + ADDFN(CSummonBotQueryMsg, CMessage); + ADDFN(CTakeHeadPieceMsg, CMessage); + ADDFN(CTextInputMsg, CMessage); + ADDFN(CTimeDilationMsg, CMessage); + ADDFN(CTimeMsg, CMessage); + ADDFN(CTimerMsg, CTimeMsg); + ADDFN(CTitleSequenceEndedMsg, CMessage); + ADDFN(CTransitMsg, CMessage); + ADDFN(CTranslateObjectMsg, CMessage); + ADDFN(CTransportMsg, CMessage); + ADDFN(CTriggerAutoMusicPlayerMsg, CMessage); + ADDFN(CTriggerNPCEvent, CMessage); + ADDFN(CTrueTalkGetAnimSetMsg, CMessage); + ADDFN(CTrueTalkGetAssetDetailsMsg, CMessage); + ADDFN(CTrueTalkGetStateValueMsg, CMessage); + ADDFN(CTrueTalkNotifySpeechEndedMsg, CMessage); + ADDFN(CTrueTalkNotifySpeechStartedMsg, CMessage); + ADDFN(CTrueTalkQueueUpAnimSetMsg, CMessage); + ADDFN(CTrueTalkSelfQueueAnimSetMsg, CMessage); + ADDFN(CTrueTalkTriggerActionMsg, CMessage); + ADDFN(CTurnOff, CMessage); + ADDFN(CTurnOn, CMessage); + ADDFN(CUse, CMessage); + ADDFN(CUseWithCharMsg, CMessage); + ADDFN(CUseWithOtherMsg, CMessage); + ADDFN(CVirtualKeyCharMsg, CMessage); + ADDFN(CVisibleMsg, CMessage); + + ADDFN(CEnterBombRoom, CMovePlayerTo); + ADDFN(CEnterBridge, CGameObject); + ADDFN(CEnterExitFirstClassState, CGameObject); + ADDFN(CEnterExitMiniLift, CSGTNavigation); + ADDFN(CEnterExitSecClassMiniLift, CGameObject); + ADDFN(CEnterExitView, CGameObject); + ADDFN(CEnterSecClassState, CGameObject); + ADDFN(CExitArboretum, CMovePlayerTo); + ADDFN(CExitBridge, CMovePlayerTo); + ADDFN(CExitLift, CGameObject); + ADDFN(CExitPellerator, CGameObject); + ADDFN(CExitStateRoom, CMovePlayerTo); + ADDFN(CExitTiania, CMovePlayerTo); + ADDFN(CMovePlayerInParrotRoom, CMovePlayerTo); + ADDFN(CMovePlayerTo, CGameObject); + ADDFN(CMovePlayerToFrom, CGameObject); + ADDFN(CMultiMove, CMovePlayerTo); + ADDFN(CPanFromPel, CMovePlayerTo); + ADDFN(CRestaurantPanHandler, CMovePlayerTo); + ADDFN(CScraliontisTable, CRestaurantPanHandler); + ADDFN(CRestrictedMove, CMovePlayerTo); + ADDFN(CTripDownCanal, CMovePlayerTo); + + ADDFN(CBarbot, CTrueTalkNPC); + ADDFN(CBellBot, CTrueTalkNPC); + ADDFN(CCallBot, CGameObject); + ADDFN(CCharacter, CGameObject); + ADDFN(CDeskbot, CTrueTalkNPC); + ADDFN(CDoorbot, CTrueTalkNPC); + ADDFN(CMaitreD, CTrueTalkNPC); + ADDFN(CLiftBot, CTrueTalkNPC); + ADDFN(CMobile, CCharacter); + ADDFN(CParrot, CTrueTalkNPC); + ADDFN(CRobotController, CGameObject); + ADDFN(CStarlings, CCharacter); + ADDFN(CSuccUBus, CTrueTalkNPC); + ADDFN(CSummonBots, CRobotController); + ADDFN(CTitania, CCharacter); + ADDFN(CTrueTalkNPC, CCharacter); + + ADDFN(CAutoMusicPlayer, CAutoMusicPlayerBase); + ADDFN(CAutoMusicPlayerBase, CGameObject); + ADDFN(CAutoSoundPlayer, CGameObject); + ADDFN(CAutoSoundPlayerADSR, CAutoSoundPlayer); + ADDFN(CBackgroundSoundMaker, CGameObject); + ADDFN(CBirdSong, CRoomAutoSoundPlayer); + ADDFN(CDomeFromTopOfWell, CViewAutoSoundPlayer); + ADDFN(CGondolierSong, CGameObject); + ADDFN(CEnterViewTogglesOtherMusic, CTriggerAutoMusicPlayer); + ADDFN(CGondolierSong, CRoomAutoSoundPlayer); + ADDFN(CMusicPlayer, CGameObject); + ADDFN(CNodeAutoSoundPlayer, CAutoSoundPlayer); + ADDFN(CRestrictedAutoMusicPlayer, CAutoMusicPlayer); + ADDFN(CRoomAutoSoundPlayer, CAutoSoundPlayer); + ADDFN(CRoomTriggerAutoMusicPlayer, CTriggerAutoMusicPlayer); + ADDFN(CSeasonNoises, CViewAutoSoundPlayer); + ADDFN(CSeasonalMusicPlayer, CAutoMusicPlayerBase); + ADDFN(CAutoMusicPlayer, CAutoMusicPlayerBase); + ADDFN(CAutoMusicPlayerBase, CAutoMusicPlayer); + ADDFN(CTitaniaSpeech, CGameObject); + ADDFN(CTriggerAutoMusicPlayer, CGameObject); + ADDFN(CViewAutoSoundPlayer, CAutoSoundPlayer); + ADDFN(CViewTogglesOtherMusic, CEnterViewTogglesOtherMusic); + ADDFN(CWaterLappingSounds, CRoomAutoSoundPlayer); + ADDFN(CStarControl, CGameObject); + ADDFN(CTimeEventInfo, ListItem); +} + +void CSaveableObject::freeClassList() { + Common::List<ClassDef *>::iterator i; + for (i = _classDefs->begin(); i != _classDefs->end(); ++i) + delete *i; + + delete _classDefs; + delete _classList; +} + +CSaveableObject *CSaveableObject::createInstance(const Common::String &name) { + return (*_classList)[name](); +} + +void CSaveableObject::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); +} + +void CSaveableObject::load(SimpleFile *file) { + file->readNumber(); +} + +void CSaveableObject::saveHeader(SimpleFile *file, int indent) { + file->writeClassStart(getType()->_className, indent); +} + +void CSaveableObject::saveFooter(SimpleFile *file, int indent) { + file->writeClassEnd(indent); +} + +bool CSaveableObject::isInstanceOf(const ClassDef *classDef) const { + for (ClassDef *def = getType(); def != nullptr; def = def->_parent) { + if (def == classDef) + return true; + } + + return false; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/saveable_object.h b/engines/titanic/core/saveable_object.h new file mode 100644 index 0000000000..6d80ad121d --- /dev/null +++ b/engines/titanic/core/saveable_object.h @@ -0,0 +1,110 @@ +/* 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. + * + */ + +#ifndef TITANIC_SAVEABLE_OBJECT_H +#define TITANIC_SAVEABLE_OBJECT_H + +#include "common/scummsys.h" +#include "common/array.h" +#include "common/hash-str.h" +#include "common/list.h" +#include "titanic/support/simple_file.h" + +namespace Titanic { + +class CSaveableObject; + +class ClassDef { +public: + const char *_className; + ClassDef *_parent; +public: + ClassDef(const char *className, ClassDef *parent) : + _className(className), _parent(parent) {} + virtual ~ClassDef() {} + virtual CSaveableObject *create(); +}; + +template<typename T> +class TypeTemplate : public ClassDef { +public: + TypeTemplate(const char *className, ClassDef *parent) : + ClassDef(className, parent) {} + virtual CSaveableObject *create() { return new T(); } +}; + +#define CLASSDEF \ + static ClassDef *_type; \ + virtual ClassDef *getType() const { return _type; } + +class CSaveableObject { + typedef CSaveableObject *(*CreateFunction)(); +private: + static Common::List<ClassDef *> *_classDefs; + static Common::HashMap<Common::String, CreateFunction> *_classList; +public: + /** + * Sets up the list of saveable object classes + */ + static void initClassList(); + + /** + * Free the list of saveable object classes + */ + static void freeClassList(); + + /** + * Creates a new instance of a saveable object class + */ + static CSaveableObject *createInstance(const Common::String &name); +public: + CLASSDEF + virtual ~CSaveableObject() {} + + bool isInstanceOf(const ClassDef *classDef) const; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Write out a header definition for the class to file + * prior to saving the actual data for the class + */ + virtual void saveHeader(SimpleFile *file, int indent); + + /** + * Writes out a footer for the class after it's data has + * been written to file + */ + virtual void saveFooter(SimpleFile *file, int indent); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SAVEABLE_OBJECT_H */ diff --git a/engines/titanic/core/static_image.cpp b/engines/titanic/core/static_image.cpp new file mode 100644 index 0000000000..977009e750 --- /dev/null +++ b/engines/titanic/core/static_image.cpp @@ -0,0 +1,39 @@ +/* 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/core/static_image.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CStaticImage, CGameObject); + +void CStaticImage::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + CGameObject::save(file, indent); +} + +void CStaticImage::load(SimpleFile *file) { + file->readNumber(); + CGameObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/static_image.h b/engines/titanic/core/static_image.h new file mode 100644 index 0000000000..7a715a84fa --- /dev/null +++ b/engines/titanic/core/static_image.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. + * + */ + +#ifndef TITANIC_STATIC_IMAGE_H +#define TITANIC_STATIC_IMAGE_H + +#include "titanic/core/game_object.h" + +namespace Titanic { + +class CStaticImage : public CGameObject { + DECLARE_MESSAGE_MAP; +public: + CLASSDEF; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STATIC_IMAGE_H */ diff --git a/engines/titanic/core/tree_item.cpp b/engines/titanic/core/tree_item.cpp new file mode 100644 index 0000000000..6adbbe39fa --- /dev/null +++ b/engines/titanic/core/tree_item.cpp @@ -0,0 +1,275 @@ +/* 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/core/tree_item.h" +#include "titanic/core/dont_save_file_item.h" +#include "titanic/core/file_item.h" +#include "titanic/core/game_object.h" +#include "titanic/core/game_object_desc_item.h" +#include "titanic/core/link_item.h" +#include "titanic/core/mail_man.h" +#include "titanic/core/named_item.h" +#include "titanic/core/node_item.h" +#include "titanic/core/project_item.h" +#include "titanic/core/view_item.h" +#include "titanic/core/room_item.h" +#include "titanic/pet_control/pet_control.h" +#include "titanic/game_manager.h" +#include "titanic/game/placeholder/place_holder_item.h" + +namespace Titanic { + +EMPTY_MESSAGE_MAP(CTreeItem, CMessageTarget); + +CTreeItem::CTreeItem() : _parent(nullptr), _firstChild(nullptr), + _nextSibling(nullptr), _priorSibling(nullptr), _field14(0) { +} + +void CTreeItem::dump(int indent) { + CString line = dumpItem(indent); + debug("%s", line.c_str()); + + CTreeItem *item = getFirstChild(); + while (item) { + item->dump(indent + 1); + + item = item->getNextSibling(); + } +} + +CString CTreeItem::dumpItem(int indent) const { + CString result; + for (int idx = 0; idx < indent; ++idx) + result += '\t'; + result += getType()->_className; + + return result; +} + +void CTreeItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(0, indent); + CMessageTarget::save(file, indent); +} + +void CTreeItem::load(SimpleFile *file) { + file->readNumber(); + CMessageTarget::load(file); +} + +bool CTreeItem::isFileItem() const { + return isInstanceOf(CFileItem::_type); +} + +bool CTreeItem::isRoomItem() const { + return isInstanceOf(CRoomItem::_type); +} + +bool CTreeItem::isNodeItem() const { + return isInstanceOf(CNodeItem::_type); +} + +bool CTreeItem::isViewItem() const { + return isInstanceOf(CViewItem::_type); +} + +bool CTreeItem::isLinkItem() const { + return isInstanceOf(CLinkItem::_type); +} + +bool CTreeItem::isPlaceHolderItem() const { + return isInstanceOf(CPlaceHolderItem::_type); +} + +bool CTreeItem::isNamedItem() const { + return isInstanceOf(CNamedItem::_type); +} + +bool CTreeItem::isGameObject() const { + return isInstanceOf(CGameObject::_type); +} + +bool CTreeItem::isGameObjectDescItem() const { + return isInstanceOf(CGameObjectDescItem::_type); +} + +CGameManager *CTreeItem::getGameManager() const { + return _parent ? _parent->getGameManager() : nullptr; +} + +CProjectItem *CTreeItem::getRoot() const { + CTreeItem *parent = getParent(); + + if (parent) { + do { + parent = parent->getParent(); + } while (parent->getParent()); + } + + return dynamic_cast<CProjectItem *>(parent); +} + +CTreeItem *CTreeItem::getLastSibling() { + CTreeItem *item = this; + while (item->getNextSibling()) + item = item->getNextSibling(); + + return item; +} + +CTreeItem *CTreeItem::getLastChild() const { + if (!_firstChild) + return nullptr; + return _firstChild->getLastSibling(); +} + +CTreeItem *CTreeItem::scan(CTreeItem *item) const { + if (_firstChild) + return _firstChild; + + const CTreeItem *treeItem = this; + while (treeItem != item) { + if (treeItem->_nextSibling) + return treeItem->_nextSibling; + + treeItem = treeItem->_parent; + if (!treeItem) + break; + } + + return nullptr; +} + +CTreeItem *CTreeItem::findChildInstanceOf(ClassDef *classDef) const { + for (CTreeItem *treeItem = _firstChild; treeItem; treeItem = treeItem->getNextSibling()) { + if (treeItem->isInstanceOf(classDef)) + return treeItem; + } + + return nullptr; +} + +CTreeItem *CTreeItem::findNextInstanceOf(ClassDef *classDef, CTreeItem *startItem) const { + CTreeItem *treeItem = startItem ? startItem->getNextSibling() : getFirstChild(); + + for (; treeItem; treeItem = treeItem->getNextSibling()) { + if (treeItem->isInstanceOf(classDef)) + return treeItem; + } + + return nullptr; +} + +void CTreeItem::addUnder(CTreeItem *newParent) { + if (newParent->_firstChild) + addSibling(newParent->_firstChild->getLastSibling()); + else + setParent(newParent); +} + +void CTreeItem::setParent(CTreeItem *newParent) { + _parent = newParent; + _priorSibling = nullptr; + _nextSibling = newParent->_firstChild; + + if (newParent->_firstChild) + newParent->_firstChild->_priorSibling = this; + newParent->_firstChild = this; +} + +void CTreeItem::addSibling(CTreeItem *item) { + _priorSibling = item; + _nextSibling = item->_nextSibling; + _parent = item->_parent; + + if (item->_nextSibling) + item->_nextSibling->_priorSibling = this; + item->_nextSibling = this; +} + +void CTreeItem::moveUnder(CTreeItem *newParent) { + if (newParent) { + detach(); + addUnder(newParent); + } +} + +void CTreeItem::destroyAll() { + destroyChildren(); + detach(); + delete this; +} + +int CTreeItem::destroyChildren() { + if (!_firstChild) + return 0; + + CTreeItem *item = _firstChild, *child, *nextSibling; + int total = 0; + + do { + child = item->_firstChild; + nextSibling = item->_nextSibling; + + if (child) + total += item->destroyChildren(); + item->detach(); + delete item; + ++total; + } while ((item = nextSibling) != nullptr); + + return total; +} + +void CTreeItem::detach() { + // Delink this item from any prior and/or next siblings + if (_priorSibling) + _priorSibling->_nextSibling = _nextSibling; + if (_nextSibling) + _nextSibling->_priorSibling = _priorSibling; + + if (_parent && _parent->_firstChild == this) + _parent->_firstChild = _nextSibling; + + _priorSibling = _nextSibling = _parent = nullptr; +} + +CNamedItem *CTreeItem::findByName(const CString &name, int maxLen) { + CString nameLower = name; + nameLower.toLowercase(); + + for (CTreeItem *treeItem = this; treeItem; treeItem = treeItem->scan(this)) { + CString nodeName = treeItem->getName(); + nodeName.toLowercase(); + + if (maxLen) { + if (nodeName.left(maxLen).compareTo(nameLower)) + return dynamic_cast<CNamedItem *>(treeItem); + } else { + if (!nodeName.compareTo(nameLower)) + return dynamic_cast<CNamedItem *>(treeItem); + } + } + + return nullptr; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/tree_item.h b/engines/titanic/core/tree_item.h new file mode 100644 index 0000000000..db4ba30a44 --- /dev/null +++ b/engines/titanic/core/tree_item.h @@ -0,0 +1,252 @@ +/* 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. + * + */ + +#ifndef TITANIC_TREE_ITEM_H +#define TITANIC_TREE_ITEM_H + +#include "titanic/core/message_target.h" +#include "titanic/support/simple_file.h" + +namespace Titanic { + +class CGameManager; +class CMovieClipList; +class CNamedItem; +class CProjectItem; +class CScreenManager; +class CViewItem; + +class CTreeItem: public CMessageTarget { + friend class CMessage; + DECLARE_MESSAGE_MAP; +private: + CTreeItem *_parent; + CTreeItem *_nextSibling; + CTreeItem *_priorSibling; + CTreeItem *_firstChild; + int _field14; +public: + CLASSDEF; + CTreeItem(); + + + /** + * Dump the item and any of it's children + */ + void dump(int indent); + + /** + * Dump the item + */ + virtual CString dumpItem(int indent) const; + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Get the game manager for the project + */ + virtual CGameManager *getGameManager() const; + + /** + * Returns true if the item is a file item + */ + virtual bool isFileItem() const; + + /** + * Returns true if the item is a room item + */ + virtual bool isRoomItem() const; + + /** + * Returns true if the item is a node item + */ + virtual bool isNodeItem() const; + + /** + * Returns true if the item is a view item + */ + virtual bool isViewItem() const; + + /** + * Returns true if the item is a link item + */ + virtual bool isLinkItem() const; + + /** + * Returns true if the item is a placeholder item + */ + virtual bool isPlaceHolderItem() const; + + /** + * Returns true if the item is a named item + */ + virtual bool isNamedItem() const; + + /** + * Returns true if the item is a game object + */ + virtual bool isGameObject() const; + + /** + * Returns true if the item is a game object desc item + */ + virtual bool isGameObjectDescItem() const; + + /** + * Gets the name of the item, if any + */ + virtual const CString getName() const { return CString(); } + + /** + * Compares the name of the item to a passed name + */ + virtual int compareTo(const CString &name, int maxLen = 0) const { return false; } + + /** + * Returns the clip list, if any, associated with the item + */ + virtual const CMovieClipList *getMovieClips() const { return nullptr; } + + /** + * Returns true if the given item connects to another specified view + */ + virtual bool connectsTo(CViewItem *destView) const { return false; } + + /** + * Allows the item to draw itself + */ + virtual void draw(CScreenManager *screenManager) {} + + /** + * Gets the bounds occupied by the item + */ + virtual Rect getBounds() const { return Rect(); } + + /** + * Called when the view changes + */ + virtual void viewChange() {} + + /** + * Get the parent for the given item + */ + CTreeItem *getParent() const { return _parent; } + + /** + * Jumps up through the parents to find the root item + */ + CProjectItem *getRoot() const; + + /** + * Get the next sibling + */ + CTreeItem *getNextSibling() const { return _nextSibling; } + + /** + * Get the prior sibling + */ + CTreeItem *getPriorSibling() const { return _priorSibling; } + + /** + * Get the last sibling of this sibling + */ + CTreeItem *getLastSibling(); + + /** + * Get the first child of the item, if any + */ + CTreeItem *getFirstChild() const { return _firstChild; } + + /** + * Get the last child of the item, if any + */ + CTreeItem *getLastChild() const; + + /** + * Given all the recursive children of the tree item, gives the next + * item in sequence to the passed starting item + */ + CTreeItem *scan(CTreeItem *item) const; + + /** + * Find the first child item that is of a given type + */ + CTreeItem *findChildInstanceOf(ClassDef *classDef) const; + + /** + * Find the next sibling item that is of the given type + */ + CTreeItem *findNextInstanceOf(ClassDef *classDef, CTreeItem *startItem) const; + + /** + * Adds the item under another tree item + */ + void addUnder(CTreeItem *newParent); + + /** + * Sets the parent for the item + */ + void setParent(CTreeItem *newParent); + + /** + * Adds the item as a sibling of another item + */ + void addSibling(CTreeItem *item); + + /** + * Moves the tree item to be under another parent + */ + void moveUnder(CTreeItem *newParent); + + /** + * Destroys both the item as well as any of it's children + */ + void destroyAll(); + + /** + * Destroys all child tree items under this one. + * @returns Total number of tree items recursively removed + */ + int destroyChildren(); + + /** + * Detach the tree item from any other associated tree items + */ + void detach(); + + /** + * Finds a tree item by name + */ + CNamedItem *findByName(const CString &name, int maxLen = 0); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TREE_ITEM_H */ diff --git a/engines/titanic/core/turn_on_object.cpp b/engines/titanic/core/turn_on_object.cpp new file mode 100644 index 0000000000..221602bb7b --- /dev/null +++ b/engines/titanic/core/turn_on_object.cpp @@ -0,0 +1,59 @@ +/* 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/core/turn_on_object.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CTurnOnObject, CBackground) + ON_MESSAGE(MouseButtonDownMsg) + ON_MESSAGE(MouseButtonUpMsg) +END_MESSAGE_MAP() + +CTurnOnObject::CTurnOnObject() : CBackground(), _msgName("NULL") { +} + +void CTurnOnObject::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_msgName, indent); + + CBackground::save(file, indent); +} + +void CTurnOnObject::load(SimpleFile *file) { + file->readNumber(); + _msgName = file->readString(); + + CBackground::load(file); +} + +bool CTurnOnObject::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + return true; +} + +bool CTurnOnObject::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + CTurnOn turnOn; + turnOn.execute(_msgName); + return true; +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/turn_on_object.h b/engines/titanic/core/turn_on_object.h new file mode 100644 index 0000000000..0f7cd76382 --- /dev/null +++ b/engines/titanic/core/turn_on_object.h @@ -0,0 +1,53 @@ +/* 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. + * + */ + +#ifndef TITANIC_TURN_ON_OBJECT_H +#define TITANIC_TURN_ON_OBJECT_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CTurnOnObject : public CBackground { + DECLARE_MESSAGE_MAP; + bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); +protected: + CString _msgName; +public: + CLASSDEF; + CTurnOnObject(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TURN_ON_OBJECT_H */ diff --git a/engines/titanic/core/turn_on_play_sound.cpp b/engines/titanic/core/turn_on_play_sound.cpp new file mode 100644 index 0000000000..2f9dba24a6 --- /dev/null +++ b/engines/titanic/core/turn_on_play_sound.cpp @@ -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. + * + */ + +#include "titanic/core/turn_on_play_sound.h" + +namespace Titanic { + +CTurnOnPlaySound::CTurnOnPlaySound() : CTurnOnObject(), + _string3("NULL"), _fieldF8(80), _fieldFC(0) { +} + +void CTurnOnPlaySound::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeQuotedLine(_string3, indent); + file->writeNumberLine(_fieldF8, indent); + file->writeNumberLine(_fieldFC, indent); + + CTurnOnObject::save(file, indent); +} + +void CTurnOnPlaySound::load(SimpleFile *file) { + file->readNumber(); + _string3 = file->readString(); + _fieldF8 = file->readNumber(); + _fieldFC = file->readNumber(); + + CTurnOnObject::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/turn_on_play_sound.h b/engines/titanic/core/turn_on_play_sound.h new file mode 100644 index 0000000000..1164135071 --- /dev/null +++ b/engines/titanic/core/turn_on_play_sound.h @@ -0,0 +1,52 @@ +/* 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. + * + */ + +#ifndef TITANIC_TURN_ON_PLAY_SOUND_H +#define TITANIC_TURN_ON_PLAY_SOUND_H + +#include "titanic/core/turn_on_object.h" + +namespace Titanic { + +class CTurnOnPlaySound : public CTurnOnObject { +private: + CString _string3; + int _fieldF8; + int _fieldFC; +public: + CLASSDEF; + CTurnOnPlaySound(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TURN_ON_PLAY_SOUND_H */ diff --git a/engines/titanic/core/turn_on_turn_off.cpp b/engines/titanic/core/turn_on_turn_off.cpp new file mode 100644 index 0000000000..d43ddf7038 --- /dev/null +++ b/engines/titanic/core/turn_on_turn_off.cpp @@ -0,0 +1,53 @@ +/* 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/core/turn_on_turn_off.h" + +namespace Titanic { + +CTurnOnTurnOff::CTurnOnTurnOff() : CBackground(), _fieldE0(0), + _fieldE4(0), _fieldE8(0), _fieldEC(0), _fieldF0(0) { +} + +void CTurnOnTurnOff::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + file->writeNumberLine(_fieldE0, indent); + file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_fieldE8, indent); + file->writeNumberLine(_fieldEC, indent); + file->writeNumberLine(_fieldF0, indent); + + CBackground::save(file, indent); +} + +void CTurnOnTurnOff::load(SimpleFile *file) { + file->readNumber(); + _fieldE0 = file->readNumber(); + _fieldE4 = file->readNumber(); + _fieldE8 = file->readNumber(); + _fieldEC = file->readNumber(); + _fieldF0 = file->readNumber(); + + CBackground::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/turn_on_turn_off.h b/engines/titanic/core/turn_on_turn_off.h new file mode 100644 index 0000000000..adca6876ff --- /dev/null +++ b/engines/titanic/core/turn_on_turn_off.h @@ -0,0 +1,54 @@ +/* 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. + * + */ + +#ifndef TITANIC_TURN_ON_TURN_OFF_H +#define TITANIC_TURN_ON_TURN_OFF_H + +#include "titanic/core/background.h" + +namespace Titanic { + +class CTurnOnTurnOff : public CBackground { +private: + int _fieldE0; + int _fieldE4; + int _fieldE8; + int _fieldEC; + int _fieldF0; +public: + CLASSDEF; + CTurnOnTurnOff(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TURN_ON_TURN_OFF_H */ diff --git a/engines/titanic/core/view_item.cpp b/engines/titanic/core/view_item.cpp new file mode 100644 index 0000000000..56069a9799 --- /dev/null +++ b/engines/titanic/core/view_item.cpp @@ -0,0 +1,313 @@ +/* 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/game_manager.h" +#include "titanic/support/screen_manager.h" +#include "titanic/core/project_item.h" +#include "titanic/core/room_item.h" +#include "titanic/core/view_item.h" +#include "titanic/messages/messages.h" +#include "titanic/pet_control/pet_control.h" + +namespace Titanic { + +BEGIN_MESSAGE_MAP(CViewItem, CNamedItem) + ON_MESSAGE(MouseButtonDownMsg) + ON_MESSAGE(MouseButtonUpMsg) + ON_MESSAGE(MouseDoubleClickMsg) + ON_MESSAGE(MouseMoveMsg) +END_MESSAGE_MAP() + +CViewItem::CViewItem() : CNamedItem() { + Common::fill(&_buttonUpTargets[0], &_buttonUpTargets[4], (CTreeItem *)nullptr); + _field24 = 0; + _field28 = 0.0; + _viewNumber = 0; + _field50 = 0; + _field54 = 0; + setData(0.0); +} + +void CViewItem::setData(double v) { + _field28 = v; + _field50 = cos(_field28) * 30.0; + _field54 = sin(_field28) * -30.0; +} + +void CViewItem::save(SimpleFile *file, int indent) { + file->writeNumberLine(1, indent); + _resourceKey.save(file, indent); + file->writeQuotedLine("V", indent); + file->writeFloatLine(_field28, indent + 1); + file->writeNumberLine(_viewNumber, indent + 1); + + CNamedItem::save(file, indent); +} + +void CViewItem::load(SimpleFile *file) { + int val = file->readNumber(); + + switch (val) { + case 1: + _resourceKey.load(file); + // Deliberate fall-through + + default: + file->readBuffer(); + setData(file->readFloat()); + _viewNumber = file->readNumber(); + break; + } + + CNamedItem::load(file); +} + +bool CViewItem::getResourceKey(CResourceKey *key) { + *key = _resourceKey; + CString filename = key->exists(); + return !filename.empty(); +} + +void CViewItem::leaveView(CViewItem *newView) { + // Only do the processing if we've been passed a view, and it's not the same + if (newView && newView != this) { + CLeaveViewMsg viewMsg(this, newView); + viewMsg.execute(this, nullptr, MSGFLAG_SCAN); + + CNodeItem *oldNode = findNode(); + CNodeItem *newNode = newView->findNode(); + if (newNode != oldNode) { + CLeaveNodeMsg nodeMsg(oldNode, newNode); + nodeMsg.execute(oldNode, nullptr, MSGFLAG_SCAN); + + CRoomItem *oldRoom = oldNode->findRoom(); + CRoomItem *newRoom = newNode->findRoom(); + if (newRoom != oldRoom) { + CGameManager *gm = getGameManager(); + if (gm) + gm->viewChange(); + + CLeaveRoomMsg roomMsg(oldRoom, newRoom); + roomMsg.execute(oldRoom, nullptr, MSGFLAG_SCAN); + } + } + } +} + +void CViewItem::preEnterView(CViewItem *newView) { + // Only do the processing if we've been passed a view, and it's not the same + if (newView && newView != this) { + CPreEnterViewMsg viewMsg(this, newView); + viewMsg.execute(this, nullptr, MSGFLAG_SCAN); + + CNodeItem *oldNode = findNode(); + CNodeItem *newNode = newView->findNode(); + if (newNode != oldNode) { + CPreEnterNodeMsg nodeMsg(oldNode, newNode); + nodeMsg.execute(oldNode, nullptr, MSGFLAG_SCAN); + + CRoomItem *oldRoom = oldNode->findRoom(); + CRoomItem *newRoom = newNode->findRoom(); + if (newRoom != oldRoom) { + CPreEnterRoomMsg roomMsg(oldRoom, newRoom); + roomMsg.execute(oldRoom, nullptr, MSGFLAG_SCAN); + } + } + } +} + +void CViewItem::enterView(CViewItem *newView) { + // Only do the processing if we've been passed a view, and it's not the same + if (newView && newView != this) { + CEnterViewMsg viewMsg(this, newView); + viewMsg.execute(this, nullptr, MSGFLAG_SCAN); + + CNodeItem *oldNode = findNode(); + CNodeItem *newNode = newView->findNode(); + if (newNode != oldNode) { + CEnterNodeMsg nodeMsg(oldNode, newNode); + nodeMsg.execute(oldNode, nullptr, MSGFLAG_SCAN); + + CRoomItem *oldRoom = oldNode->findRoom(); + CRoomItem *newRoom = newNode->findRoom(); + + CPetControl *petControl = nullptr; + if (newRoom != nullptr) { + petControl = newRoom->getRoot()->getPetControl(); + if (petControl) + petControl->enterNode(newNode); + } + + if (newRoom != oldRoom) { + CEnterRoomMsg roomMsg(oldRoom, newRoom); + roomMsg.execute(oldRoom, nullptr, MSGFLAG_SCAN); + + if (petControl) + petControl->enterRoom(newRoom); + } + } + } +} + +CLinkItem *CViewItem::findLink(CViewItem *newView) { + for (CTreeItem *treeItem = getFirstChild(); treeItem; + treeItem = scan(treeItem)) { + CLinkItem *link = static_cast<CLinkItem *>(treeItem); + if (link && link->connectsTo(newView)) + return link; + } + + return nullptr; +} + +bool CViewItem::MouseButtonDownMsg(CMouseButtonDownMsg *msg) { + if (msg->_buttons & MB_LEFT) { + if (!handleMouseMsg(msg, true)) { + CGameManager *gm = getGameManager(); + if (gm->test54()) { + findNode()->findRoom(); + + CLinkItem *linkItem = dynamic_cast<CLinkItem *>( + findChildInstanceOf(CLinkItem::_type)); + while (linkItem) { + if (linkItem->_bounds.contains(msg->_mousePos)) { + gm->_gameState.triggerLink(linkItem); + return true; + } + + linkItem = dynamic_cast<CLinkItem *>( + findNextInstanceOf(CLinkItem::_type, linkItem)); + } + } + } + } + + return true; +} + +bool CViewItem::MouseButtonUpMsg(CMouseButtonUpMsg *msg) { + if (msg->_buttons & MB_LEFT) + handleMouseMsg(msg, false); + + return true; +} + +bool CViewItem::MouseDoubleClickMsg(CMouseDoubleClickMsg *msg) { + if (msg->_buttons & MB_LEFT) + handleMouseMsg(msg, false); + + return true; +} + +bool CViewItem::MouseMoveMsg(CMouseMoveMsg *msg) { + CScreenManager *screenManager = CScreenManager::_screenManagerPtr; + uint changeCount = screenManager->_mouseCursor->getChangeCount(); + + if (handleMouseMsg(msg, true)) { + // If the cursor hasn't been set in the call to handleMouseMsg, + // then reset it back to the default arrow cursor + if (screenManager->_mouseCursor->getChangeCount() == changeCount) + screenManager->_mouseCursor->setCursor(CURSOR_ARROW); + } else { + // Iterate through each link item, and if any is highlighted, + // change the mouse cursor to the designated cursor for the item + CTreeItem *treeItem = getFirstChild(); + while (treeItem) { + CLinkItem *linkItem = dynamic_cast<CLinkItem *>(treeItem); + if (linkItem && linkItem->_bounds.contains(msg->_mousePos)) { + screenManager->_mouseCursor->setCursor(linkItem->_cursorId); + return true; + } + + treeItem = treeItem->getNextSibling(); + } + + if (!handleMouseMsg(msg, false) || (screenManager->_mouseCursor->getChangeCount() == changeCount)) + screenManager->_mouseCursor->setCursor(CURSOR_ARROW); + } + + return true; +} + +bool CViewItem::handleMouseMsg(CMouseMsg *msg, bool flag) { + CMouseButtonUpMsg *upMsg = dynamic_cast<CMouseButtonUpMsg *>(msg); + if (msg->isButtonUpMsg()) { + handleButtonUpMsg(upMsg); + return true; + } + + Common::Array<CGameObject *> gameObjects; + for (CTreeItem *treeItem = scan(this); treeItem; treeItem = treeItem->scan(this)) { + CGameObject *gameObject = dynamic_cast<CGameObject *>(treeItem); + if (gameObject) { + if (gameObject->checkPoint(msg->_mousePos, false, true) && + (!flag || !gameObject->_field60)) { + if (gameObjects.size() < 256) + gameObjects.push_back(gameObject); + } + } + } + + const CMouseMoveMsg *moveMsg = dynamic_cast<const CMouseMoveMsg *>(msg); + if (moveMsg) { + if (gameObjects.size() == 0) + return false; + + for (int idx = (int)gameObjects.size() - 1; idx >= 0; ++idx) { + if (gameObjects[idx]->_cursorId != CURSOR_IGNORE) { + CScreenManager::_screenManagerPtr->_mouseCursor->setCursor(gameObjects[idx]->_cursorId); + break; + } + } + } + if (gameObjects.size() == 0) + return false; + + bool result = false; + for (int idx = (int)gameObjects.size() - 1; idx >= 0; --idx) { + if (msg->execute(gameObjects[idx])) { + if (msg->isButtonDownMsg()) + _buttonUpTargets[msg->_buttons >> 1] = gameObjects[idx]; + return true; + } + + if (CMouseMsg::isSupportedBy(gameObjects[idx])) + result = true; + } + + return result; +} + +void CViewItem::handleButtonUpMsg(CMouseButtonUpMsg *msg) { + CTreeItem *&target = _buttonUpTargets[msg->_buttons >> 1]; + + if (target) { + msg->execute(target); + target = nullptr; + } +} + +void CViewItem::fn1(double val1, double val2, double val3) { + warning("TODO: CViewItem::fn1"); +} + +} // End of namespace Titanic diff --git a/engines/titanic/core/view_item.h b/engines/titanic/core/view_item.h new file mode 100644 index 0000000000..6e8003d6c6 --- /dev/null +++ b/engines/titanic/core/view_item.h @@ -0,0 +1,105 @@ +/* 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. + * + */ + +#ifndef TITANIC_VIEW_ITEM_H +#define TITANIC_VIEW_ITEM_H + +#include "titanic/core/link_item.h" +#include "titanic/core/named_item.h" +#include "titanic/core/resource_key.h" +#include "titanic/messages/mouse_messages.h" + +namespace Titanic { + +class CViewItem : public CNamedItem { + DECLARE_MESSAGE_MAP; + bool MouseButtonDownMsg(CMouseButtonDownMsg *msg); + bool MouseButtonUpMsg(CMouseButtonUpMsg *msg); + bool MouseMoveMsg(CMouseMoveMsg *msg); + bool MouseDoubleClickMsg(CMouseDoubleClickMsg *msg); +private: + CTreeItem *_buttonUpTargets[4]; +private: + void setData(double v); + + /** + * Called to handle mouse messagaes on the view + */ + bool handleMouseMsg(CMouseMsg *msg, bool flag); + + /** + * Handles mouse button up messages + */ + void handleButtonUpMsg(CMouseButtonUpMsg *msg); +protected: + int _field24; + double _field28; + CResourceKey _resourceKey; + int _field50; + int _field54; +public: + int _viewNumber; +public: + CLASSDEF; + CViewItem(); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent); + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Get the resource key for the view + */ + bool getResourceKey(CResourceKey *key); + + /** + * Called when leaving the view + */ + void leaveView(CViewItem *newView); + + /** + * Called on an old view just left, and about to enter a new view + */ + void preEnterView(CViewItem *newView); + + /** + * Called when a new view is being entered + */ + void enterView(CViewItem *newView); + + /** + * Finds a link which connects to another designated view + */ + CLinkItem *findLink(CViewItem *newView); + + void fn1(double val1, double val2, double val3); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_NAMED_ITEM_H */ |