From 2c15b164d736d1339998f9dcf7a4a230984cdff5 Mon Sep 17 00:00:00 2001 From: Peter Kohaut Date: Sun, 2 Oct 2016 00:20:56 +0200 Subject: BLADERUNNER: added support for rendering items in scenes --- engines/bladerunner/actor.cpp | 7 +-- engines/bladerunner/actor_combat.h | 38 +++++++------- engines/bladerunner/bladerunner.cpp | 23 ++++---- engines/bladerunner/bladerunner.h | 1 - engines/bladerunner/item.cpp | 98 ++++++++++++++++++++++++++++++++++- engines/bladerunner/item.h | 68 +++++++++++++----------- engines/bladerunner/items.cpp | 40 +++++++++++++- engines/bladerunner/items.h | 7 ++- engines/bladerunner/script/script.cpp | 6 +-- engines/bladerunner/script/script.h | 2 +- engines/bladerunner/view.cpp | 7 +-- engines/bladerunner/view.h | 2 +- 12 files changed, 219 insertions(+), 80 deletions(-) (limited to 'engines/bladerunner') diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp index 29c83e78cb..ba0bedae5f 100644 --- a/engines/bladerunner/actor.cpp +++ b/engines/bladerunner/actor.cpp @@ -176,8 +176,8 @@ void Actor::processMovement() { }*/ } -void Actor::setAtXYZ(Vector3 pos, int facing, bool snapFacing, bool moving, bool retired) { - _position = pos; +void Actor::setAtXYZ(Vector3 position, int facing, bool snapFacing, bool moving, bool retired) { + _position = position; setFacing(facing, snapFacing); if (_vm->_scene->_setId == _setId) { @@ -404,6 +404,7 @@ void Actor::draw() { // TODO: Handle SHORTY mode _vm->_sliceRenderer->drawFrame(_animationId, _animationFrame, draw_position, draw_facing, draw_scale, _vm->_surface2, _vm->_zBuffer2); + //todo udpate screenrect } int Actor::getSetId() { @@ -814,7 +815,7 @@ int Actor::soundVolume() { } int Actor::soundBalance() { - Vector2 screenPosition = _vm->_view->calculateScreenPosition(_position); + Vector3 screenPosition = _vm->_view->calculateScreenPosition(_position); return 127.0f * (MAX(MIN(screenPosition.x / 640.0f, 1.0f), 0.0f) * 2.0f - 1.0f); } diff --git a/engines/bladerunner/actor_combat.h b/engines/bladerunner/actor_combat.h index 37fc57742a..df06e83f22 100644 --- a/engines/bladerunner/actor_combat.h +++ b/engines/bladerunner/actor_combat.h @@ -34,27 +34,27 @@ class ActorCombat BladeRunnerEngine *_vm; private: - int _actorId; - int _combatOn; - int _field2; - int _field3; - int _otherActorId; - int _field5; - int _field6; - int _field7; - int _field8; - int _field9; - int _field10; - int _field11; - int _field12; - int _actorHp; - int _field14; - int _field15; +// int _actorId; +// int _combatOn; +// int _field2; +// int _field3; +// int _otherActorId; +// int _field5; +// int _field6; +// int _field7; +// int _field8; +// int _field9; +// int _field10; +// int _field11; +// int _field12; +// int _actorHp; +// int _field14; +// int _field15; Vector3 actorPosition; Vector3 otherActorPosition; - int _availableCoversCount; - int _availableFleeWaypointsCount; - int _field24; +// int _availableCoversCount; +// int _availableFleeWaypointsCount; +// int _field24; public: ActorCombat(BladeRunnerEngine *vm); diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp index b683e350f1..663d17dda9 100644 --- a/engines/bladerunner/bladerunner.cpp +++ b/engines/bladerunner/bladerunner.cpp @@ -507,15 +507,15 @@ void BladeRunnerEngine::gameLoop() { #if _DEBUG void drawBBox(Vector3 start, Vector3 end, View* view, Graphics::Surface *surface, int color) { - Vector2 bfl = view->calculateScreenPosition(Vector3(start.x, start.y, start.z)); - Vector2 bfr = view->calculateScreenPosition(Vector3(start.x, end.y, start.z)); - Vector2 bbr = view->calculateScreenPosition(Vector3(end.x, end.y, start.z)); - Vector2 bbl = view->calculateScreenPosition(Vector3(end.x, start.y, start.z)); + Vector3 bfl = view->calculateScreenPosition(Vector3(start.x, start.y, start.z)); + Vector3 bfr = view->calculateScreenPosition(Vector3(start.x, end.y, start.z)); + Vector3 bbr = view->calculateScreenPosition(Vector3(end.x, end.y, start.z)); + Vector3 bbl = view->calculateScreenPosition(Vector3(end.x, start.y, start.z)); - Vector2 tfl = view->calculateScreenPosition(Vector3(start.x, start.y, end.z)); - Vector2 tfr = view->calculateScreenPosition(Vector3(start.x, end.y, end.z)); - Vector2 tbr = view->calculateScreenPosition(Vector3(end.x, end.y, end.z)); - Vector2 tbl = view->calculateScreenPosition(Vector3(end.x, start.y, end.z)); + Vector3 tfl = view->calculateScreenPosition(Vector3(start.x, start.y, end.z)); + Vector3 tfr = view->calculateScreenPosition(Vector3(start.x, end.y, end.z)); + Vector3 tbr = view->calculateScreenPosition(Vector3(end.x, end.y, end.z)); + Vector3 tbl = view->calculateScreenPosition(Vector3(end.x, start.y, end.z)); surface->drawLine(bfl.x, bfl.y, bfr.x, bfr.y, color); surface->drawLine(bfr.x, bfr.y, bbr.x, bbr.y, color); @@ -599,7 +599,8 @@ void BladeRunnerEngine::gameTick() { } } - // TODO: Draw items + _items->tick(); + // TODO: Draw item pickup // TODO: Draw dialogue menu @@ -664,8 +665,8 @@ void BladeRunnerEngine::gameTick() { Walkbox *walkbox = &_scene->_set->_walkboxes[i]; for(int j = 0; j < walkbox->_vertexCount; j++) { - Vector2 start = _view->calculateScreenPosition(walkbox->_vertices[j]); - Vector2 end = _view->calculateScreenPosition(walkbox->_vertices[(j+1) % walkbox->_vertexCount]); + Vector3 start = _view->calculateScreenPosition(walkbox->_vertices[j]); + Vector3 end = _view->calculateScreenPosition(walkbox->_vertices[(j+1) % walkbox->_vertexCount]); //debug("walkbox[%i][%i] = x=%f y=%f x=%f y=%f", i, j, start.x, start.y, end.x, end.y); _surface2.drawLine(start.x, start.y, end.x, end.y, 0b111111111100000); } diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h index d73667863a..7c2e74de4e 100644 --- a/engines/bladerunner/bladerunner.h +++ b/engines/bladerunner/bladerunner.h @@ -28,7 +28,6 @@ #include "common/array.h" #include "common/random.h" #include "common/stream.h" -#include "common/types.h" #include "engines/engine.h" diff --git a/engines/bladerunner/item.cpp b/engines/bladerunner/item.cpp index 7017997e90..74ddf1ad13 100644 --- a/engines/bladerunner/item.cpp +++ b/engines/bladerunner/item.cpp @@ -1,11 +1,38 @@ #include "bladerunner/item.h" +#include "bladerunner/bladerunner.h" +//#include "bladerunner/slice_animations.h" +#include "bladerunner/slice_renderer.h" + namespace BladeRunner { -Item::Item() { - _animationId = -1; +Item::Item(BladeRunnerEngine *vm) { + _vm = vm; + _itemId = -1; _setId = -1; + + _animationId = -1; + _position.x = 0; + _position.y = 0; + _position.z = 0; + _facing = 0; + _angle = 0.0f; + _width = 0; + _height = 0; + _boundingBox.setXYZ(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + _screenX = 0; + _screenY = 0; + _depth = 0.0f; + _isTargetable = false; + _isSpinning = false; + _facingChange = 0; + _isVisible = true; + _isPoliceMazeEnemy = true; + _screenRectangle.bottom = -1; + _screenRectangle.right = -1; + _screenRectangle.top = -1; + _screenRectangle.left = -1; } Item::~Item() { @@ -17,4 +44,71 @@ void Item::getXYZ(float *x, float *y, float *z) { *z = _position.z; } +bool Item::isTargetable() { + return _isTargetable; +} + +void Item::tick(bool special) { + if (_isVisible) { + Vector3 postition(_position.x, -_position.z, _position.y); + int animationId = _animationId + (special ? 1 : 0); + _vm->_sliceRenderer->drawFrame(animationId, 0, postition, M_PI - _angle, 1.0f, _vm->_surface2, _vm->_zBuffer2); + //todo udpate screenrect + if (_isSpinning) { + _facing += _facingChange; + + if (_facing >= 1024) { + _facing -= 1024; + } else if (_facing < 0) { + _facing += 1024; + } + _angle = M_PI / 512.0f * _facing; + + if (_facingChange > 0) { + _facingChange = _facingChange - 20; + if (_facingChange < 0) { + _facingChange = 0; + _isSpinning = false; + } + } else if (_facingChange < 0) { + _facingChange = _facingChange + 20; + if (_facingChange > 0) { + _facingChange = 0; + _isSpinning = false; + } + } else { + _isSpinning = false; + } + } + } +} + +void Item::setXYZ(Vector3 position) { + _position = position; + int halfWidth = _width / 2; + _boundingBox.setXYZ(_position.x - halfWidth, _position.y, _position.z - halfWidth, + _position.x + halfWidth, _position.y + _height, _position.z + halfWidth); + Vector3 screenPosition = _vm->_view->calculateScreenPosition(_position); + _screenX = screenPosition.x; + _screenY = screenPosition.y; + _depth = screenPosition.z * 25.5f; +} + +void Item::init(int itemId, int setId, int animationId, Vector3 position, int facing, int height, int width, bool isTargetable, bool isVisible, bool isPoliceMazeEnemy) { + _itemId = itemId; + _setId = setId; + _animationId = animationId; + _facing = facing; + _angle = M_PI / 512.0f * facing; + _width = width; + _height = height; + _isTargetable = isTargetable; + _isVisible = isVisible; + _isPoliceMazeEnemy = isPoliceMazeEnemy; + setXYZ(position); + _screenRectangle.bottom = -1; + _screenRectangle.right = -1; + _screenRectangle.top = -1; + _screenRectangle.left = -1; +} } // End of namespace BladeRunner diff --git a/engines/bladerunner/item.h b/engines/bladerunner/item.h index 5bb8e5481a..95500c3ceb 100644 --- a/engines/bladerunner/item.h +++ b/engines/bladerunner/item.h @@ -23,44 +23,52 @@ #ifndef BLADERUNNER_ITEM_H #define BLADERUNNER_ITEM_H -#include "bladerunner/bladerunner.h" #include "bladerunner/boundingbox.h" +#include "bladerunner/vector.h" -#include "common/array.h" #include "common/rect.h" namespace BladeRunner { - class Items; - class Item { - friend class Items; - private: - int _itemId; - int _setId; +class BladeRunnerEngine; +class Items; - BoundingBox _boundingBox; - Common::Rect _screenRectangle; - int _animationId; - Vector3 _position; - int _facing; - float _angle; - int _width; - int _height; - //int field_1C8; - int _target; - //float field_1D0; - int _targetable; - int _spinning; - int _angleChange; - float _cameraAngle; - int _obstacle; - //int field_1E8; - public: - Item(); - ~Item(); +class Item { + BladeRunnerEngine *_vm; - void getXYZ(float *x, float *y, float *z); - }; + friend class Items; + +private: + int _itemId; + int _setId; + + BoundingBox _boundingBox; + Common::Rect _screenRectangle; + int _animationId; + Vector3 _position; + int _facing; + float _angle; + int _width; + int _height; + int _screenX; + int _screenY; + float _depth; + bool _isTargetable; + bool _isSpinning; + int _facingChange; + bool _isVisible; + bool _isPoliceMazeEnemy; + +public: + Item(BladeRunnerEngine* vm); + ~Item(); + + void getXYZ(float *x, float *y, float *z); + bool isTargetable(); + void tick(bool special); + void setXYZ(Vector3 position); + void init(int itemId, int setId, int animationId, Vector3 position, int facing, int height, int width, bool isTargetable, bool isVisible, bool isPoliceMazeEnemy); +}; } diff --git a/engines/bladerunner/items.cpp b/engines/bladerunner/items.cpp index da3e74c69a..46ea9e842c 100644 --- a/engines/bladerunner/items.cpp +++ b/engines/bladerunner/items.cpp @@ -1,5 +1,8 @@ #include "bladerunner/items.h" +#include "bladerunner/scene.h" +#include "bladerunner/scene_objects.h" + namespace BladeRunner { Items::Items(BladeRunnerEngine *vm) { @@ -7,18 +10,51 @@ Items::Items(BladeRunnerEngine *vm) { } Items::~Items() { + for(int i = _items.size() -1; i >= 0; i--) { + delete _items.remove_at(i); + } } void Items::getXYZ(int itemId, float* x, float* y, float* z) { int itemIndex = findItem(itemId); assert(itemIndex != -1); - _items[itemIndex].getXYZ(x, y, z); + _items[itemIndex]->getXYZ(x, y, z); +} + +void Items::tick() { + int setId = _vm->_scene->getSetId(); + for(int i = 0; i < (int)_items.size(); i++) { + if(_items[i]->_setId != setId) { + continue; + } + bool set14NotTarget = setId == 14 && !_items[i]->isTargetable(); + _items[i]->tick(set14NotTarget); + } +} + +bool Items::add(int itemId, int animationId, int setId, Vector3 position, int facing, int height, int width, bool isTargetable, bool isVisible, bool isPoliceMazeEnemy, bool addToSet) { + if (_items.size() >= 100) { + return false; + } + int i = findItem(itemId); + if(i == -1) { + i = _items.size(); + } + + Item *item = new Item(_vm); + item->init(itemId, setId, animationId, position, facing, height, width, isTargetable, isVisible, isPoliceMazeEnemy); + _items.push_back(item); + + if(addToSet && setId == _vm->_scene->getSetId()) { + return _vm->_sceneObjects->addItem(itemId + SCENE_OBJECTS_ITEMS_OFFSET, &item->_boundingBox, &item->_screenRectangle, isTargetable, isVisible); + } + return true; } int Items::findItem(int itemId) { for (int i = 0; i < (int)_items.size(); i++) { - if (_items[i]._itemId == itemId) + if (_items[i]->_itemId == itemId) return i; } return -1; diff --git a/engines/bladerunner/items.h b/engines/bladerunner/items.h index 08d2a2b958..aa6f41f3f2 100644 --- a/engines/bladerunner/items.h +++ b/engines/bladerunner/items.h @@ -27,22 +27,21 @@ #include "bladerunner/item.h" #include "common/array.h" -#include "common/rect.h" namespace BladeRunner { class Items { BladeRunnerEngine *_vm; -private: - Common::Array _items; + Common::Array _items; public: Items(BladeRunnerEngine *vm); ~Items(); void getXYZ(int itemId, float *x, float *y, float *z); - + void tick(); + bool add(int itemId, int animationId, int setId, Vector3 position, int facing, int height, int width, bool isTargetable, bool isVisible, bool isPoliceMazeEnemy, bool b); private: int findItem(int itemId); }; diff --git a/engines/bladerunner/script/script.cpp b/engines/bladerunner/script/script.cpp index dd6e293163..2b944f40b8 100644 --- a/engines/bladerunner/script/script.cpp +++ b/engines/bladerunner/script/script.cpp @@ -46,6 +46,7 @@ #include "bladerunner/script/ai_00_mccoy.h" #include "bladerunner/script/aiscript_officer_leroy.h" +#include "bladerunner/items.h" namespace BladeRunner { @@ -631,9 +632,8 @@ void ScriptBase::Actor_Set_Immunity_To_Obstacles(int actorId, bool isImmune) { _vm->_actors[actorId]->setImmunityToObstacles(isImmune); } -void ScriptBase::Item_Add_To_World(int itemId, int animationId, int sceneIndex, float x, float y, float z, signed int angle, int height, int width, bool isTargetable, bool isObstacle, bool isPoliceMazeEnemy, bool updateOnly) { - //TODO - warning("Item_Add_To_World(%d, %d, %d, %f, %f, %f, %d, %d, %d, %d, %d, %d, %d)", itemId, animationId, sceneIndex, x, y, z, angle, height, width, isTargetable, isObstacle, isPoliceMazeEnemy, updateOnly); +void ScriptBase::Item_Add_To_World(int itemId, int animationId, int setId, float x, float y, float z, signed int facing, int height, int width, bool isTargetable, bool isObstacle, bool isPoliceMazeEnemy, bool updateOnly) { + _vm->_items->add(itemId, animationId, setId, Vector3(x, y, z), facing, height, width, isTargetable, isObstacle, isPoliceMazeEnemy, updateOnly == 0); } void ScriptBase::Item_Remove_From_World(int itemId) { diff --git a/engines/bladerunner/script/script.h b/engines/bladerunner/script/script.h index 0ab9efa65f..222cd4c935 100644 --- a/engines/bladerunner/script/script.h +++ b/engines/bladerunner/script/script.h @@ -119,7 +119,7 @@ protected: void Actor_Clues_Transfer_New_From_Mainframe(int actorId); void Actor_Set_Invisible(int actorId, bool isInvisible); void Actor_Set_Immunity_To_Obstacles(int actorId, bool isImmune); - void Item_Add_To_World(int itemId, int animationId, int sceneIndex, float x, float y, float z, signed int angle, int height, int width, bool isTargetable, bool isObstacle, bool isPoliceMazeEnemy, bool updateOnly); + void Item_Add_To_World(int itemId, int animationId, int setId, float x, float y, float z, signed int facing, int height, int width, bool isTargetable, bool isObstacle, bool isPoliceMazeEnemy, bool updateOnly); void Item_Remove_From_World(int itemId); void Item_Spin_In_World(int itemId); void Item_Flag_As_Target(int itemId); diff --git a/engines/bladerunner/view.cpp b/engines/bladerunner/view.cpp index b01273f34d..ab9eb3e2e6 100644 --- a/engines/bladerunner/view.cpp +++ b/engines/bladerunner/view.cpp @@ -76,11 +76,12 @@ void View::calculateCameraPosition() { _cameraPosition.z = invertedMatrix(2, 3); } -Vector2 View::calculateScreenPosition(Vector3 worldPosition) { +Vector3 View::calculateScreenPosition(Vector3 worldPosition) { Vector3 viewPosition = _frameViewMatrix * worldPosition; - return Vector2( + return Vector3( this->_viewportHalfWidth - viewPosition.x / viewPosition.z * _viewportDistance, - this->_viewportHalfHeight - viewPosition.y / viewPosition.z * _viewportDistance + this->_viewportHalfHeight - viewPosition.y / viewPosition.z * _viewportDistance, + viewPosition.z ); } diff --git a/engines/bladerunner/view.h b/engines/bladerunner/view.h index 2ffb4a9648..bb92dc1429 100644 --- a/engines/bladerunner/view.h +++ b/engines/bladerunner/view.h @@ -45,7 +45,7 @@ public: float _viewportDistance; bool read(Common::ReadStream *stream); - Vector2 calculateScreenPosition(Vector3 worldPosition); + Vector3 calculateScreenPosition(Vector3 worldPosition); private: void setFovX(float fovX); -- cgit v1.2.3