/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ /* * This file is based on WME Lite. * http://dead-code.org/redir.php?target=wmelite * Copyright (c) 2011 Jan Nedoma */ #include "engines/wintermute/base/base_object.h" #include "engines/wintermute/base/base_parser.h" #include "engines/wintermute/base/scriptables/script_value.h" #include "engines/wintermute/base/scriptables/script_stack.h" #include "engines/wintermute/base/sound/base_sound.h" #include "engines/wintermute/base/sound/base_sound_manager.h" #include "engines/wintermute/base/base_game.h" #include "engines/wintermute/base/base_sprite.h" #include "engines/wintermute/platform_osystem.h" namespace Wintermute { IMPLEMENT_PERSISTENT(BaseObject, false) ////////////////////////////////////////////////////////////////////// BaseObject::BaseObject(BaseGame *inGame) : BaseScriptHolder(inGame) { _posX = _posY = 0; _movable = true; _zoomable = true; _registrable = true; _shadowable = true; _rotatable = false; _is3D = false; _alphaColor = 0; _scale = -1; _relativeScale = 0; _scaleX = -1; _scaleY = -1; _ready = true; _soundEvent = nullptr; _iD = _gameRef->getSequence(); _rect.setEmpty(); _rectSet = false; _cursor = nullptr; _activeCursor = nullptr; _sharedCursors = false; _sFX = nullptr; _sFXStart = 0; _sFXVolume = 100; _autoSoundPanning = true; _editorAlwaysRegister = false; _editorSelected = false; _editorOnly = false; _rotate = 0.0f; _rotateValid = false; _relativeRotate = 0.0f; for (int i = 0; i < 7; i++) { _caption[i] = nullptr; } _saveState = true; _nonIntMouseEvents = false; // sound FX _sFXType = SFX_NONE; _sFXParam1 = _sFXParam2 = _sFXParam3 = _sFXParam4 = 0; _blendMode = Graphics::BLEND_NORMAL; } ////////////////////////////////////////////////////////////////////// BaseObject::~BaseObject() { cleanup(); } ////////////////////////////////////////////////////////////////////////// bool BaseObject::cleanup() { if (_gameRef && _gameRef->_activeObject == this) { _gameRef->_activeObject = nullptr; } BaseScriptHolder::cleanup(); delete[] _soundEvent; _soundEvent = nullptr; if (!_sharedCursors) { delete _cursor; delete _activeCursor; _cursor = nullptr; _activeCursor = nullptr; } delete _sFX; _sFX = nullptr; for (int i = 0; i < 7; i++) { delete[] _caption[i]; _caption[i] = nullptr; } _sFXType = SFX_NONE; _sFXParam1 = _sFXParam2 = _sFXParam3 = _sFXParam4 = 0; return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// void BaseObject::setCaption(const char *caption, int caseVal) { if (caseVal == 0) { caseVal = 1; } if (caseVal < 1 || caseVal > 7) { return; } delete[] _caption[caseVal - 1]; _caption[caseVal - 1] = new char[strlen(caption) + 1]; if (_caption[caseVal - 1]) { strcpy(_caption[caseVal - 1], caption); _gameRef->expandStringByStringTable(&_caption[caseVal - 1]); } } ////////////////////////////////////////////////////////////////////////// const char *BaseObject::getCaption(int caseVal) { if (caseVal == 0) { caseVal = 1; } if (caseVal < 1 || caseVal > 7 || _caption[caseVal - 1] == nullptr) { return ""; } else { return _caption[caseVal - 1]; } } ////////////////////////////////////////////////////////////////////////// bool BaseObject::listen(BaseScriptHolder *param1, uint32 param2) { return STATUS_FAILED; } ////////////////////////////////////////////////////////////////////////// // high level scripting interface ////////////////////////////////////////////////////////////////////////// bool BaseObject::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) { ////////////////////////////////////////////////////////////////////////// // SkipTo ////////////////////////////////////////////////////////////////////////// if (strcmp(name, "SkipTo") == 0) { stack->correctParams(2); _posX = stack->pop()->getInt(); _posY = stack->pop()->getInt(); afterMove(); stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Caption ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Caption") == 0) { stack->correctParams(1); stack->pushString(getCaption(stack->pop()->getInt())); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetCursor ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetCursor") == 0) { stack->correctParams(1); if (DID_SUCCEED(setCursor(stack->pop()->getString()))) { stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // RemoveCursor ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "RemoveCursor") == 0) { stack->correctParams(0); if (!_sharedCursors) { delete _cursor; _cursor = nullptr; } else { _cursor = nullptr; } stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetCursor ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetCursor") == 0) { stack->correctParams(0); if (!_cursor || !_cursor->getFilename()) { stack->pushNULL(); } else { stack->pushString(_cursor->getFilename()); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetCursorObject ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetCursorObject") == 0) { stack->correctParams(0); if (!_cursor) { stack->pushNULL(); } else { stack->pushNative(_cursor, true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // HasCursor ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "HasCursor") == 0) { stack->correctParams(0); if (_cursor) { stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetCaption ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetCaption") == 0) { stack->correctParams(2); setCaption(stack->pop()->getString(), stack->pop()->getInt()); stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // LoadSound ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "LoadSound") == 0) { stack->correctParams(1); const char *filename = stack->pop()->getString(); if (DID_SUCCEED(playSFX(filename, false, false))) { stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // PlaySound ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "PlaySound") == 0) { stack->correctParams(3); const char *filename; bool looping; uint32 loopStart; ScValue *val1 = stack->pop(); ScValue *val2 = stack->pop(); ScValue *val3 = stack->pop(); if (val1->_type == VAL_BOOL) { filename = nullptr; looping = val1->getBool(); loopStart = val2->getInt(); } else { if (val1->isNULL()) { filename = nullptr; } else { filename = val1->getString(); } looping = val2->isNULL() ? false : val2->getBool(); loopStart = val3->getInt(); } if (DID_FAIL(playSFX(filename, looping, true, NULL, loopStart))) { stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // PlaySoundEvent ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "PlaySoundEvent") == 0) { stack->correctParams(2); const char *filename; const char *eventName; ScValue *val1 = stack->pop(); ScValue *val2 = stack->pop(); if (val2->isNULL()) { filename = nullptr; eventName = val1->getString(); } else { filename = val1->getString(); eventName = val2->getString(); } if (DID_FAIL(playSFX(filename, false, true, eventName))) { stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // StopSound ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "StopSound") == 0) { stack->correctParams(0); if (DID_FAIL(stopSFX())) { stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // PauseSound ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "PauseSound") == 0) { stack->correctParams(0); if (DID_FAIL(pauseSFX())) { stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // ResumeSound ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "ResumeSound") == 0) { stack->correctParams(0); if (DID_FAIL(resumeSFX())) { stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // IsSoundPlaying ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "IsSoundPlaying") == 0) { stack->correctParams(0); if (_sFX && _sFX->isPlaying()) { stack->pushBool(true); } else { stack->pushBool(false); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetSoundPosition ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetSoundPosition") == 0) { stack->correctParams(1); uint32 time = stack->pop()->getInt(); if (DID_FAIL(setSFXTime(time))) { stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetSoundPosition ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetSoundPosition") == 0) { stack->correctParams(0); if (!_sFX) { stack->pushInt(0); } else { stack->pushInt(_sFX->getPositionTime()); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SetSoundVolume ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetSoundVolume") == 0) { stack->correctParams(1); int volume = stack->pop()->getInt(); if (DID_FAIL(setSFXVolume(volume))) { stack->pushBool(false); } else { stack->pushBool(true); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // GetSoundVolume ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetSoundVolume") == 0) { stack->correctParams(0); if (!_sFX) { stack->pushInt(_sFXVolume); } else { stack->pushInt(_sFX->getVolumePercent()); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SoundFXNone ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SoundFXNone") == 0) { stack->correctParams(0); _sFXType = SFX_NONE; _sFXParam1 = 0; _sFXParam2 = 0; _sFXParam3 = 0; _sFXParam4 = 0; stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SoundFXEcho ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SoundFXEcho") == 0) { stack->correctParams(4); _sFXType = SFX_ECHO; _sFXParam1 = (float)stack->pop()->getFloat(0); // Wet/Dry Mix [%] (0-100) _sFXParam2 = (float)stack->pop()->getFloat(0); // Feedback [%] (0-100) _sFXParam3 = (float)stack->pop()->getFloat(333.0f); // Left Delay [ms] (1-2000) _sFXParam4 = (float)stack->pop()->getFloat(333.0f); // Right Delay [ms] (1-2000) stack->pushNULL(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SoundFXReverb ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SoundFXReverb") == 0) { stack->correctParams(4); _sFXType = SFX_REVERB; _sFXParam1 = (float)stack->pop()->getFloat(0); // In Gain [dB] (-96 - 0) _sFXParam2 = (float)stack->pop()->getFloat(0); // Reverb Mix [dB] (-96 - 0) _sFXParam3 = (float)stack->pop()->getFloat(1000.0f); // Reverb Time [ms] (0.001 - 3000) _sFXParam4 = (float)stack->pop()->getFloat(0.001f); // HighFreq RT Ratio (0.001 - 0.999) stack->pushNULL(); return STATUS_OK; } else { return BaseScriptHolder::scCallMethod(script, stack, thisStack, name); } } ////////////////////////////////////////////////////////////////////////// ScValue *BaseObject::scGetProperty(const Common::String &name) { _scValue->setNULL(); ////////////////////////////////////////////////////////////////////////// // Type ////////////////////////////////////////////////////////////////////////// if (name == "Type") { _scValue->setString("object"); return _scValue; } ////////////////////////////////////////////////////////////////////////// // Caption ////////////////////////////////////////////////////////////////////////// else if (name == "Caption") { _scValue->setString(getCaption(1)); return _scValue; } ////////////////////////////////////////////////////////////////////////// // X ////////////////////////////////////////////////////////////////////////// else if (name == "X") { _scValue->setInt(_posX); return _scValue; } ////////////////////////////////////////////////////////////////////////// // Y ////////////////////////////////////////////////////////////////////////// else if (name == "Y") { _scValue->setInt(_posY); return _scValue; } ////////////////////////////////////////////////////////////////////////// // Height (RO) ////////////////////////////////////////////////////////////////////////// else if (name == "Height") { _scValue->setInt(getHeight()); return _scValue; } ////////////////////////////////////////////////////////////////////////// // Ready (RO) ////////////////////////////////////////////////////////////////////////// else if (name == "Ready") { _scValue->setBool(_ready); return _scValue; } ////////////////////////////////////////////////////////////////////////// // Movable ////////////////////////////////////////////////////////////////////////// else if (name == "Movable") { _scValue->setBool(_movable); return _scValue; } ////////////////////////////////////////////////////////////////////////// // Registrable/Interactive ////////////////////////////////////////////////////////////////////////// else if (name == "Registrable" || name == "Interactive") { _scValue->setBool(_registrable); return _scValue; } ////////////////////////////////////////////////////////////////////////// // Zoomable/Scalable ////////////////////////////////////////////////////////////////////////// else if (name == "Zoomable" || name == "Scalable") { _scValue->setBool(_zoomable); return _scValue; } ////////////////////////////////////////////////////////////////////////// // Rotatable ////////////////////////////////////////////////////////////////////////// else if (name == "Rotatable") { _scValue->setBool(_rotatable); return _scValue; } ////////////////////////////////////////////////////////////////////////// // AlphaColor ////////////////////////////////////////////////////////////////////////// else if (name == "AlphaColor") { _scValue->setInt((int)_alphaColor); return _scValue; } ////////////////////////////////////////////////////////////////////////// // BlendMode ////////////////////////////////////////////////////////////////////////// else if (name == "BlendMode") { _scValue->setInt((int)_blendMode); return _scValue; } ////////////////////////////////////////////////////////////////////////// // Scale ////////////////////////////////////////////////////////////////////////// else if (name == "Scale") { if (_scale < 0) { _scValue->setNULL(); } else { _scValue->setFloat((double)_scale); } return _scValue; } ////////////////////////////////////////////////////////////////////////// // ScaleX ////////////////////////////////////////////////////////////////////////// else if (name == "ScaleX") { if (_scaleX < 0) { _scValue->setNULL(); } else { _scValue->setFloat((double)_scaleX); } return _scValue; } ////////////////////////////////////////////////////////////////////////// // ScaleY ////////////////////////////////////////////////////////////////////////// else if (name == "ScaleY") { if (_scaleY < 0) { _scValue->setNULL(); } else { _scValue->setFloat((double)_scaleY); } return _scValue; } ////////////////////////////////////////////////////////////////////////// // RelativeScale ////////////////////////////////////////////////////////////////////////// else if (name == "RelativeScale") { _scValue->setFloat((double)_relativeScale); return _scValue; } ////////////////////////////////////////////////////////////////////////// // Rotate ////////////////////////////////////////////////////////////////////////// else if (name == "Rotate") { if (!_rotateValid) { _scValue->setNULL(); } else { _scValue->setFloat((double)_rotate); } return _scValue; } ////////////////////////////////////////////////////////////////////////// // RelativeRotate ////////////////////////////////////////////////////////////////////////// else if (name == "RelativeRotate") { _scValue->setFloat((double)_relativeRotate); return _scValue; } ////////////////////////////////////////////////////////////////////////// // Colorable ////////////////////////////////////////////////////////////////////////// else if (name == "Colorable") { _scValue->setBool(_shadowable); return _scValue; } ////////////////////////////////////////////////////////////////////////// // SoundPanning ////////////////////////////////////////////////////////////////////////// else if (name == "SoundPanning") { _scValue->setBool(_autoSoundPanning); return _scValue; } ////////////////////////////////////////////////////////////////////////// // SaveState ////////////////////////////////////////////////////////////////////////// else if (name == "SaveState") { _scValue->setBool(_saveState); return _scValue; } ////////////////////////////////////////////////////////////////////////// // NonIntMouseEvents ////////////////////////////////////////////////////////////////////////// else if (name == "NonIntMouseEvents") { _scValue->setBool(_nonIntMouseEvents); return _scValue; } ////////////////////////////////////////////////////////////////////////// // AccCaption ////////////////////////////////////////////////////////////////////////// else if (name == "AccCaption") { _scValue->setNULL(); return _scValue; } else { return BaseScriptHolder::scGetProperty(name); } } ////////////////////////////////////////////////////////////////////////// bool BaseObject::scSetProperty(const char *name, ScValue *value) { ////////////////////////////////////////////////////////////////////////// // Caption ////////////////////////////////////////////////////////////////////////// if (strcmp(name, "Caption") == 0) { setCaption(value->getString()); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // X ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "X") == 0) { _posX = value->getInt(); afterMove(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Y ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Y") == 0) { _posY = value->getInt(); afterMove(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Movable ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Movable") == 0) { _movable = value->getBool(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Registrable/Interactive ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Registrable") == 0 || strcmp(name, "Interactive") == 0) { _registrable = value->getBool(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Zoomable/Scalable ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Zoomable") == 0 || strcmp(name, "Scalable") == 0) { _zoomable = value->getBool(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Rotatable ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Rotatable") == 0) { _rotatable = value->getBool(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // AlphaColor ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "AlphaColor") == 0) { _alphaColor = (uint32)value->getInt(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // BlendMode ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "BlendMode") == 0) { int i = value->getInt(); if (i < Graphics::BLEND_NORMAL || i >= Graphics::NUM_BLEND_MODES) { i = Graphics::BLEND_NORMAL; } _blendMode = (Graphics::TSpriteBlendMode)i; return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Scale ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Scale") == 0) { if (value->isNULL()) { _scale = -1; } else { _scale = (float)value->getFloat(); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // ScaleX ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "ScaleX") == 0) { if (value->isNULL()) { _scaleX = -1; } else { _scaleX = (float)value->getFloat(); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // ScaleY ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "ScaleY") == 0) { if (value->isNULL()) { _scaleY = -1; } else { _scaleY = (float)value->getFloat(); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // RelativeScale ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "RelativeScale") == 0) { _relativeScale = (float)value->getFloat(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Rotate ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Rotate") == 0) { if (value->isNULL()) { _rotate = 0.0f; _rotateValid = false; } else { _rotate = (float)value->getFloat(); _rotateValid = true; } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // RelativeRotate ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "RelativeRotate") == 0) { _relativeRotate = (float)value->getFloat(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // Colorable ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "Colorable") == 0) { _shadowable = value->getBool(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SoundPanning ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SoundPanning") == 0) { _autoSoundPanning = value->getBool(); if (!_autoSoundPanning) { resetSoundPan(); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // SaveState ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SaveState") == 0) { _saveState = value->getBool(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // NonIntMouseEvents ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "NonIntMouseEvents") == 0) { _nonIntMouseEvents = value->getBool(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// // AccCaption ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "AccCaption") == 0) { return STATUS_OK; } else { return BaseScriptHolder::scSetProperty(name, value); } } ////////////////////////////////////////////////////////////////////////// const char *BaseObject::scToString() { return "[object]"; } ////////////////////////////////////////////////////////////////////////// bool BaseObject::showCursor() { if (_cursor) { return _gameRef->drawCursor(_cursor); } else { return STATUS_FAILED; } } ////////////////////////////////////////////////////////////////////////// bool BaseObject::saveAsText(BaseDynamicBuffer *buffer, int indent) { return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// bool BaseObject::persist(BasePersistenceManager *persistMgr) { BaseScriptHolder::persist(persistMgr); for (int i = 0; i < 7; i++) { persistMgr->transferCharPtr(TMEMBER(_caption[i])); } persistMgr->transferPtr(TMEMBER_PTR(_activeCursor)); persistMgr->transferUint32(TMEMBER(_alphaColor)); persistMgr->transferBool(TMEMBER(_autoSoundPanning)); persistMgr->transferPtr(TMEMBER_PTR(_cursor)); persistMgr->transferBool(TMEMBER(_sharedCursors)); persistMgr->transferBool(TMEMBER(_editorAlwaysRegister)); persistMgr->transferBool(TMEMBER(_editorOnly)); persistMgr->transferBool(TMEMBER(_editorSelected)); persistMgr->transferSint32(TMEMBER(_iD)); persistMgr->transferBool(TMEMBER(_is3D)); persistMgr->transferBool(TMEMBER(_movable)); persistMgr->transferSint32(TMEMBER(_posX)); persistMgr->transferSint32(TMEMBER(_posY)); persistMgr->transferFloat(TMEMBER(_relativeScale)); persistMgr->transferBool(TMEMBER(_rotatable)); persistMgr->transferFloat(TMEMBER(_scale)); persistMgr->transferPtr(TMEMBER_PTR(_sFX)); persistMgr->transferUint32(TMEMBER(_sFXStart)); persistMgr->transferSint32(TMEMBER(_sFXVolume)); persistMgr->transferBool(TMEMBER(_ready)); persistMgr->transferRect32(TMEMBER(_rect)); persistMgr->transferBool(TMEMBER(_rectSet)); persistMgr->transferBool(TMEMBER(_registrable)); persistMgr->transferBool(TMEMBER(_shadowable)); persistMgr->transferCharPtr(TMEMBER(_soundEvent)); persistMgr->transferBool(TMEMBER(_zoomable)); persistMgr->transferFloat(TMEMBER(_scaleX)); persistMgr->transferFloat(TMEMBER(_scaleY)); persistMgr->transferFloat(TMEMBER(_rotate)); persistMgr->transferBool(TMEMBER(_rotateValid)); persistMgr->transferFloat(TMEMBER(_relativeRotate)); persistMgr->transferBool(TMEMBER(_saveState)); persistMgr->transferBool(TMEMBER(_nonIntMouseEvents)); persistMgr->transferSint32(TMEMBER_INT(_sFXType)); persistMgr->transferFloat(TMEMBER(_sFXParam1)); persistMgr->transferFloat(TMEMBER(_sFXParam2)); persistMgr->transferFloat(TMEMBER(_sFXParam3)); persistMgr->transferFloat(TMEMBER(_sFXParam4)); persistMgr->transferSint32(TMEMBER_INT(_blendMode)); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// bool BaseObject::setCursor(const char *filename) { if (!_sharedCursors) { delete _cursor; _cursor = nullptr; } _sharedCursors = false; _cursor = new BaseSprite(_gameRef); if (!_cursor || DID_FAIL(_cursor->loadFile(filename))) { delete _cursor; _cursor = nullptr; return STATUS_FAILED; } else { return STATUS_OK; } } ////////////////////////////////////////////////////////////////////////// bool BaseObject::setActiveCursor(const char *filename) { delete _activeCursor; _activeCursor = new BaseSprite(_gameRef); if (!_activeCursor || DID_FAIL(_activeCursor->loadFile(filename))) { delete _activeCursor; _activeCursor = nullptr; return STATUS_FAILED; } else { return STATUS_OK; } } ////////////////////////////////////////////////////////////////////////// int32 BaseObject::getHeight() { return 0; } ////////////////////////////////////////////////////////////////////////// bool BaseObject::handleMouse(TMouseEvent event, TMouseButton button) { return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// bool BaseObject::handleKeypress(Common::Event *event, bool printable) { return false; } ////////////////////////////////////////////////////////////////////////// bool BaseObject::handleMouseWheel(int delta) { return false; } ////////////////////////////////////////////////////////////////////////// bool BaseObject::playSFX(const char *filename, bool looping, bool playNow, const char *eventName, uint32 loopStart) { // just play loaded sound if (filename == nullptr && _sFX) { if (_gameRef->_editorMode || _sFXStart) { _sFX->setVolumePercent(_sFXVolume); _sFX->setPositionTime(_sFXStart); if (!_gameRef->_editorMode) { _sFXStart = 0; } } if (playNow) { setSoundEvent(eventName); if (loopStart) { _sFX->setLoopStart(loopStart); } return _sFX->play(looping); } else { return STATUS_OK; } } if (filename == nullptr) { return STATUS_FAILED; } // create new sound delete _sFX; _sFX = new BaseSound(_gameRef); if (_sFX && DID_SUCCEED(_sFX->setSound(filename, Audio::Mixer::kSFXSoundType, true))) { _sFX->setVolumePercent(_sFXVolume); if (_sFXStart) { _sFX->setPositionTime(_sFXStart); _sFXStart = 0; } _sFX->applyFX(_sFXType, _sFXParam1, _sFXParam2, _sFXParam3, _sFXParam4); if (playNow) { setSoundEvent(eventName); if (loopStart) { _sFX->setLoopStart(loopStart); } return _sFX->play(looping); } else { return STATUS_OK; } } else { delete _sFX; _sFX = nullptr; return STATUS_FAILED; } } ////////////////////////////////////////////////////////////////////////// bool BaseObject::stopSFX(bool deleteSound) { if (_sFX) { _sFX->stop(); if (deleteSound) { delete _sFX; _sFX = nullptr; } return STATUS_OK; } else { return STATUS_FAILED; } } ////////////////////////////////////////////////////////////////////////// bool BaseObject::pauseSFX() { if (_sFX) { return _sFX->pause(); } else { return STATUS_FAILED; } } ////////////////////////////////////////////////////////////////////////// bool BaseObject::resumeSFX() { if (_sFX) { return _sFX->resume(); } else { return STATUS_FAILED; } } ////////////////////////////////////////////////////////////////////////// bool BaseObject::setSFXTime(uint32 time) { _sFXStart = time; if (_sFX && _sFX->isPlaying()) { return _sFX->setPositionTime(time); } else { return STATUS_OK; } } ////////////////////////////////////////////////////////////////////////// bool BaseObject::setSFXVolume(int volume) { _sFXVolume = volume; if (_sFX) { return _sFX->setVolumePercent(volume); } else { return STATUS_OK; } } ////////////////////////////////////////////////////////////////////////// bool BaseObject::updateSounds() { if (_soundEvent) { if (_sFX && !_sFX->isPlaying()) { applyEvent(_soundEvent); setSoundEvent(nullptr); } } if (_sFX) { updateOneSound(_sFX); } return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// bool BaseObject::updateOneSound(BaseSound *sound) { bool ret = STATUS_OK; if (sound) { if (_autoSoundPanning) { ret = sound->setPan(_gameRef->_soundMgr->posToPan(_posX - _gameRef->_offsetX, _posY - _gameRef->_offsetY)); } ret = sound->applyFX(_sFXType, _sFXParam1, _sFXParam2, _sFXParam3, _sFXParam4); } return ret; } ////////////////////////////////////////////////////////////////////////// bool BaseObject::resetSoundPan() { if (!_sFX) { return STATUS_OK; } else { return _sFX->setPan(0.0f); } } ////////////////////////////////////////////////////////////////////////// bool BaseObject::getExtendedFlag(const char *flagName) { return false; } ////////////////////////////////////////////////////////////////////////// bool BaseObject::isReady() { return _ready; } ////////////////////////////////////////////////////////////////////////// void BaseObject::setSoundEvent(const char *eventName) { delete[] _soundEvent; _soundEvent = nullptr; if (eventName) { _soundEvent = new char[strlen(eventName) + 1]; if (_soundEvent) { strcpy(_soundEvent, eventName); } } } ////////////////////////////////////////////////////////////////////////// bool BaseObject::afterMove() { return STATUS_OK; } } // End of namespace Wintermute