diff options
Diffstat (limited to 'engines/bladerunner/scene.cpp')
-rw-r--r-- | engines/bladerunner/scene.cpp | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/engines/bladerunner/scene.cpp b/engines/bladerunner/scene.cpp new file mode 100644 index 0000000000..c29a6345cc --- /dev/null +++ b/engines/bladerunner/scene.cpp @@ -0,0 +1,322 @@ +/* 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 "bladerunner/scene.h" + +#include "bladerunner/bladerunner.h" + +#include "bladerunner/actor.h" +#include "bladerunner/adq.h" +#include "bladerunner/chapters.h" +#include "bladerunner/gameinfo.h" +#include "bladerunner/items.h" +#include "bladerunner/settings.h" +#include "bladerunner/scene_objects.h" +#include "bladerunner/script/script.h" +#include "bladerunner/slice_renderer.h" + +#include "common/str.h" + +namespace BladeRunner { + +bool Scene::open(int setId, int sceneId, bool isLoadingGame) { + if (!isLoadingGame) { + _vm->_adq->flush(1, false); + } + + _setId = setId; + _sceneId = sceneId; + + const Common::String setName = _vm->_gameInfo->getSceneName(_sceneId); + + if (isLoadingGame) { + // TODO: Set up overlays + } else { + _regions->clear(); + _exits->clear(); + // TODO: Reset aesc + // TODO: Clear regions + // TODO: Destroy all overlays + _defaultLoop = 0; + _defaultLoopSet = false; + _specialLoopAtEnd = false; + _specialLoopMode = -1; + _specialLoop = -1; + _frame = -1; + } + + Common::String vqaName; + int currentResourceId = _vm->_chapters->currentResourceId(); + if (currentResourceId == 1) { + vqaName = Common::String::format("%s.VQA", setName.c_str()); + } else { + vqaName = Common::String::format("%s_%d.VQA", setName.c_str(), MIN(currentResourceId, 3)); + } + + if (_vqaPlayer != nullptr) + delete _vqaPlayer; + + _vqaPlayer = new VQAPlayer(_vm); + + Common::String sceneName = _vm->_gameInfo->getSceneName(sceneId); + if (!_vm->_script->open(sceneName)) + return false; + + if (!isLoadingGame) + _vm->_script->InitializeScene(); + + Common::String setResourceName = Common::String::format("%s-MIN.SET", sceneName.c_str()); + if (!_set->open(setResourceName)) + return false; + + _vm->_sliceRenderer->setView(*_vm->_view); + + if (isLoadingGame) { + // TODO: Advance VQA frame + if (sceneId >= 73 && sceneId <= 76) + _vm->_script->SceneLoaded(); + return true; + } + + if (!_vqaPlayer->open(vqaName)) + return false; + + if (_specialLoop == -1) { + _vqaPlayer->setLoop(_defaultLoop, -1, 2, nullptr, nullptr); + _defaultLoopSet = true; + _specialLoopAtEnd = false; + } + _vm->_scene->advanceFrame(_vm->_surface1, _vm->_zBuffer1); + + _vm->_playerActor->setAtXYZ(_actorStartPosition, _actorStartFacing); + //_vm->_playerActor->setSetId(setId); + + _vm->_script->SceneLoaded(); + + _vm->_sceneObjects->clear(); + + // Init click map + int actorCount = _vm->_gameInfo->getActorCount(); + for (int i = 0; i != actorCount; ++i) { + Actor *actor = _vm->_actors[i]; + if (actor->getSetId() == setId) { + _vm->_sceneObjects->addActor( + i, + actor->getBoundingBox(), + actor->getScreenRectangle(), + 1, + 0, + actor->isTargetable(), + actor->isRetired()); + } + } + + _set->addObjectsToScene(_vm->_sceneObjects); + _vm->_items->addToSet(setId); + _vm->_sceneObjects->updateObstacles(); + // TODO: add all items to scene + // TODO: calculate walking obstacles?? + + if (_specialLoopMode) { + _vm->_script->PlayerWalkedIn(); + } + + return true; +} + +bool Scene::close(bool isLoadingGame) { + bool result = true; + if (getSetId() == -1) { + return true; + } + + //_vm->_policeMaze->clear(!isLoadingGame); + if (isLoadingGame) { + _vm->_script->PlayerWalkedOut(); + } + + // if (SceneScript_isLoaded() && !SceneScript_unload()) { + // result = false; + // } + if (_vqaPlayer != nullptr) { + //_vqaPlayer->stop(); + delete _vqaPlayer; + _vqaPlayer = nullptr; + } + _sceneId = -1; + _setId = -1; + + return result; +} + +int Scene::advanceFrame(Graphics::Surface &surface, uint16 *&zBuffer) { + int frame = _vqaPlayer->update(); + if (frame >= 0) { + surface.copyFrom(*_vqaPlayer->getSurface()); + memcpy(zBuffer, _vqaPlayer->getZBuffer(), 640 * 480 * 2); + _vqaPlayer->updateView(_vm->_view); + _vqaPlayer->updateLights(_vm->_lights); + } + + if (_specialLoopMode && _specialLoopMode != 2 && _specialLoopMode != 3) { + if (_specialLoopMode == 1) { + if (frame == -3) { // TODO: when will this happen? bad data in/eof of vqa + _vm->_settings->setNewSetAndScene(_nextSetId, _nextSceneId); + _vm->playerGainsControl(); + } + } else if (!_specialLoopAtEnd) { + _vqaPlayer->setLoop(_defaultLoop + 1, -1, 0, &Scene::loopEndedStatic, this); + _specialLoopAtEnd = true; + } + } else if (!this->_defaultLoopSet) { + _vqaPlayer->setLoop(_defaultLoop, -1, 1, &Scene::loopEndedStatic, this); + _defaultLoopSet = true; + if (_specialLoopMode == 0) { + _vm->playerLosesControl(); + } + } + + if (frame >= 0) { + _frame = frame; + } + + return frame; +} + +void Scene::setActorStart(Vector3 position, int facing) { + _actorStartPosition = position; + _actorStartFacing = facing; +} + +void Scene::loopSetDefault(int loopId) { + _defaultLoop = loopId; +} + +void Scene::loopStartSpecial(int specialLoopMode, int loopId, int flags) { + _specialLoopMode = specialLoopMode; + _specialLoop = loopId; + + int unknown = -1; + if (_specialLoopMode == 1) { + unknown = 0; + } + + int loopMode = 1; + if (flags) { + loopMode = 2; + } + + _vqaPlayer->setLoop(_specialLoop, unknown, loopMode, &Scene::loopEndedStatic, this); + if (_specialLoopMode == 1) { + this->_nextSetId = _vm->_settings->getNewSet(); + this->_nextSceneId = _vm->_settings->getNewScene(); + } + if (flags) { + this->_specialLoopAtEnd = true; + loopEnded(0, _specialLoop); + } +} + +int Scene::findObject(const char *objectName) { + return _set->findObject(objectName); +} + +bool Scene::objectSetHotMouse(int objectId) { + return _set->objectSetHotMouse(objectId); +} + +bool Scene::objectGetBoundingBox(int objectId, BoundingBox *boundingBox) { + return _set->objectGetBoundingBox(objectId, boundingBox); +} + +void Scene::objectSetIsClickable(int objectId, bool isClickable, bool sceneLoaded) { + _set->objectSetIsClickable(objectId, isClickable); + if (sceneLoaded) { + _vm->_sceneObjects->setIsClickable(objectId + 198, isClickable); + } +} + +void Scene::objectSetIsObstacle(int objectId, bool isObstacle, bool sceneLoaded, bool updateWalkpath) { + _set->objectSetIsObstacle(objectId, isObstacle); + if (sceneLoaded) { + _vm->_sceneObjects->setIsObstacle(objectId + 198, isObstacle); + if (updateWalkpath) { + _vm->_sceneObjects->updateObstacles(); + } + } +} + +void Scene::objectSetIsObstacleAll(bool isObstacle, bool sceneLoaded) { + int i; + for (i = 0; i < (int)_set->getObjectCount(); i++) { + _set->objectSetIsObstacle(i, isObstacle); + if (sceneLoaded) { + _vm->_sceneObjects->setIsObstacle(i + 198, isObstacle); + } + } +} + +void Scene::objectSetIsTarget(int objectId, bool isTarget, bool sceneLoaded) { + _set->objectSetIsTarget(objectId, isTarget); + if (sceneLoaded) { + _vm->_sceneObjects->setIsTarget(objectId + 198, isTarget); + } +} + +const char *Scene::objectGetName(int objectId) { + return _set->objectGetName(objectId); +} + +void Scene::loopEnded(int frame, int loopId) { + if (_specialLoopMode && _specialLoopMode != 2 && _specialLoopMode != 3) { + if (_specialLoopMode == 1) { + _defaultLoopSet = true; + _specialLoopAtEnd = false; + _vm->playerLosesControl(); + } + } else if (_specialLoopAtEnd) { + _vqaPlayer->setLoop(_defaultLoop, -1, 1, &Scene::loopEndedStatic, this); + _defaultLoopSet = true; + _specialLoopAtEnd = false; + if (_specialLoopMode == 0) { + _vm->playerLosesControl(); + } + } else { + if (_specialLoopMode == 0) { + _vm->playerGainsControl(); + _playerWalkedIn = true; + } + if (_specialLoopMode == 3) { + //TODO: + //spinner::open(Spinner); + } + _specialLoopMode = -1; + _specialLoop = -1; + _vqaPlayer->setLoop(_defaultLoop + 1, -1, 0, nullptr, nullptr); + _specialLoopAtEnd = true; + } +} + +void Scene::loopEndedStatic(void *data, int frame, int loopId) { + ((Scene*)data)->loopEnded(frame, loopId); +} +} // End of namespace BladeRunner |