diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp index d95c6529e0fb..d16ee84f399c 100644 --- a/engines/bladerunner/actor.cpp +++ b/engines/bladerunner/actor.cpp @@ -30,6 +30,9 @@ #include "bladerunner/waypoints.h" #include "bladerunner/scene.h" #include "bladerunner/items.h" +#include "bladerunner/script/script.h" +#include "bladerunner/slice_animations.h" +#include "bladerunner/audio_speech.h" namespace BladeRunner { @@ -100,15 +103,20 @@ void Actor::setup(int actorId) { _timersRemain[4] = 60000; _animationMode = -1; - // TODO: screen rect = { -1, -1, -1, -1 }; + _screenRectangle = Common::Rect(-1, -1, -1, -1); + _combatAnimationMode = 4; + _unknown1 = 7; + _unknown2 = 8; int actorCount = (int)_vm->_gameInfo->getActorCount(); for (int i = 0; i != actorCount; ++i) _friendlinessToOther[i] = 50; - // TODO: Setup clues + _combatInfo->setup(); + _clues->removeAll(); + _movementTrack->flush(); - // TODO: Flush movement track + _actorSpeed = Vector3(); } void Actor::set_at_xyz(Vector3 position, int facing, bool halfOrSet, int moving, bool retired) { @@ -179,7 +187,6 @@ void Actor::setSetId(int setId) { } } - void Actor::setFacing(int facing, bool halfOrSet) { if (facing < 0 || facing >= 1024) { return; @@ -218,15 +225,15 @@ void Actor::setFacing(int facing, bool halfOrSet) { } void Actor::setBoundingBox(Vector3 position, bool retired) { - if(retired) { - - }else { + if (retired) { + _bbox->setXyz(position.x - (_retiredWidth / 2.0f), position.y, position.z - (_retiredWidth / 2.0f), position.x + (_retiredWidth / 2.0f), position.y + _retiredHeight, position.z + (_retiredWidth / 2.0f)); + } else { _bbox->setXyz(position.x - 12.0f, position.y + 6.0f, position.z - 12.0f, position.x + 12.0f, position.y + 72.0f, position.z + 12.0f); } } -void Actor::changeAnimationMode(int animationMode, int force) { +void Actor::changeAnimationMode(int animationMode, bool force) { if (force == 1) { _animationMode = -1; } @@ -234,15 +241,30 @@ void Actor::changeAnimationMode(int animationMode, int force) { //TODO: _vm->actorScript->ChangeAnimationMode(_id, animationMode); _animationMode = animationMode; } +} +void Actor::setFps(int fps) { + _fps = fps; + if (fps == 0) { + _frame_ms = 0; + } else { + if(_fps == -1) { + _frame_ms = -1000; + } else if (_fps == -2) { + _fps = _vm->_sliceAnimations->getFps(_animationId); + _frame_ms = 1000 / _fps; + } else { + _frame_ms = 1000 / _fps; + } + } } bool Actor::isWalking() { return _walkInfo->isWalking(); } -void Actor::stopWalking(int value) { - if (value == 1 && _id == 0) { +void Actor::stopWalking(bool value) { + if (value && _id == 0) { _vm->_playerActorIdle = true; } @@ -325,10 +347,6 @@ void Actor::faceHeading(int heading, bool animate) { } } -int Actor::getFriendlinessToOther(int otherActorId) { - return _friendlinessToOther[otherActorId]; -} - void Actor::modifyFriendlinessToOther(int otherActorId, signed int change) { _friendlinessToOther[otherActorId] = MIN(MAX(_friendlinessToOther[otherActorId] + change, 0), 100); } @@ -353,28 +371,12 @@ void Actor::setCombatAggressiveness(int combatAggressiveness) { _combatAggressiveness = combatAggressiveness; } -int Actor::getCurrentHP() { - return _currentHP; +void Actor::setInvisible(bool isInvisible) { + _isInvisible = isInvisible; } -int Actor::getMaxHP() { - return _maxHP; -} - -int Actor::getCombatAggressiveness() { - return _combatAggressiveness; -} - -int Actor::getHonesty() { - return _honesty; -} - -int Actor::getIntelligence() { - return _intelligence; -} - -int Actor::getStability() { - return _stability; +void Actor::setImmunityToObstacles(bool isImmune) { + _isImmuneToObstacles = isImmune; } void Actor::modifyCurrentHP(signed int change) { @@ -415,12 +417,156 @@ void Actor::retire(bool isRetired, int width, int height, int retiredByActorId) _isRetired = isRetired; _retiredWidth = MAX(width, 0); _retiredHeight = MAX(height, 0); - if(_id == 0 && isRetired) { + if (_id == 0 && isRetired) { _vm->playerLosesControl(); _vm->_playerDead = true; } - if(isRetired) { + if (isRetired) { //TODO: _vm->actorScript->Retired(_id, retiredByActorId); } } + +void Actor::setTargetable(bool targetable) { + _isTargetable = targetable; +} + +void Actor::setHealth(int hp, int maxHp) { + _currentHP = hp; + _maxHP = maxHp; + if(hp > 0) { + retire(0, 0, 0, -1); + } +} + +void Actor::combatModeOn(int a2, int a3, int otherActorId, int a5, int combatAnimationMode, int a7, int a8, int a9, int a10, int a11, int ammoDamage, int a13, int a14) { + _combatAnimationMode = combatAnimationMode; + _unknown1 = a7; + _unknown2 = a8; + _inCombat = true; + if (_id > 0) + _combatInfo->combatOn(_id, a2, a3, otherActorId, a5, a9, a10, a11, ammoDamage, a13, a14); + stopWalking(0); + changeAnimationMode(_combatAnimationMode, 0); + int i; + for (i = 0; i < (int)_vm->_gameInfo->getActorCount(); i++) { + Actor *otherActor = _vm->_actors[i]; + if (i != _id && otherActor->_setId == _setId && !otherActor->_isRetired) { + //TODO: _vm->actorScript->OtherAgentEnteredCombatMode(i, _id, 1); + } + } +} + +void Actor::combatModeOff() { + if (_id > 0) + _combatInfo->combatOff(); + _inCombat = false; + stopWalking(0); + changeAnimationMode(0, 0); + int i; + for (i = 0; i < (int)_vm->_gameInfo->getActorCount(); i++) { + Actor *otherActor = _vm->_actors[i]; + if (i != _id && otherActor->_setId == _setId && !otherActor->_isRetired) { + //TODO: _vm->actorScript->OtherAgentEnteredCombatMode(i, _id, 0); + } + } +} + +float Actor::distanceFromActor(int otherActorId) { + return (_position - _vm->_actors[otherActorId]->_position).length(); +} + +float Actor::getX() { + return _position.x; +} + +float Actor::getY() { + return _position.y; +} + +float Actor::getZ() { + return _position.z; +} + +void Actor::getXYZ(float* x, float* y, float* z) { + *x = _position.x; + *y = _position.y; + *z = _position.z; +} + +int Actor::getFacing() { + return _facing; +} + +int Actor::getAnimationMode() { + return _animationMode; +} + +void Actor::setGoal(int goalNumber) { + if (goalNumber == _goalNumber) + return; + + //TODO: _vm->actorScript->GoalChanged(_id, _goalNumber, goalNumber); + + _vm->_script->SceneActorChangedGoal(_id, goalNumber, _goalNumber, _vm->_scene->getSetId() == _setId); +} + +int Actor::getGoal() { + return _goalNumber; +} + +void Actor::speechPlay(int sentenceId, bool voiceOver) { + char name[13]; + sprintf(name, "%02d-%04d.AUD", _id, sentenceId); //TODO somewhere here should be also language code + int balance; + + if(voiceOver || _id == 99) { + balance = 0; + }else { + Vector3 pos = _vm->_view->_frameViewMatrix * _position; + int screenX = 0, screenY = 0; + //TODO: transform to screen space using fov; + balance = 127 * (2 * screenX - 640) / 640; + balance = MIN(127, MAX(-127, balance)); + } + + _vm->_audioSpeech->playSpeech(name, balance); +} + +void Actor::speechStop() { + _vm->_audioSpeech->stopSpeech(); +} + +bool Actor::isSpeeching() { + return _vm->_audioSpeech->isPlaying(); +} + +void Actor::addClueToDatabase(int clueId, int unknown, bool clueAcquired, bool unknownFlag, int fromActorId) { + _clues->add(_id, clueId, unknown, clueAcquired, unknownFlag, fromActorId); +} + +void Actor::acquireClue(int clueId, byte unknownFlag, int fromActorId) { + _clues->acquire(clueId, unknownFlag, fromActorId); +} + +void Actor::loseClue(int clueId) { + _clues->lose(clueId); +} + +bool Actor::hasClue(int clueId) { + return _clues->isAcquired(clueId); +} + +void Actor::copyClues(int actorId) { + Actor *otherActor = _vm->_actors[actorId]; + int i; + for (i = 0; i < (int)_vm->_gameInfo->getClueCount(); i++) { + if(hasClue(i) && !_clues->isFlag4(i) && !otherActor->hasClue(i)) { + int fromActorId = _id; + if (_id == 99) + fromActorId = _clues->getFromActorId(i); + otherActor->acquireClue(i, 0, fromActorId); + } + } +} + } // End of namespace BladeRunner diff --git a/engines/bladerunner/actor.h b/engines/bladerunner/actor.h index 4da73d4bc671..4d383f03b10f 100644 --- a/engines/bladerunner/actor.h +++ b/engines/bladerunner/actor.h @@ -40,7 +40,7 @@ class BoundingBox; class Actor { BladeRunnerEngine *_vm; - + friend class ScriptBase; private: BoundingBox *_bbox; Common::Rect _screenRectangle; @@ -76,7 +76,6 @@ class Actor { bool _isMoving; bool _damageAnimIfMoving; - // Animation int _width; int _height; @@ -96,6 +95,12 @@ class Actor { float _scale; + int _unknown1; + int _unknown2; + int _unknown3; + + Vector3 _actorSpeed; + public: Actor(BladeRunnerEngine *_vm, int actorId); ~Actor(); @@ -105,6 +110,13 @@ class Actor { void set_at_xyz(Vector3 pos, int facing, bool halfOrSet, int unknown, bool retired); void set_at_waypoint(int waypointId, int angle, int unknown, bool retired); + float getX(); + float getY(); + float getZ(); + void getXYZ(float* x, float* y, float* z); + int getFacing(); + int getAnimationMode(); + void draw(); int getSetId(); @@ -113,13 +125,15 @@ class Actor { Common::Rect* getScreenRectangle() { return &_screenRectangle; } bool isRetired() { return _isRetired; } bool isTargetable() { return _isTargetable; } + void setTargetable(bool targetable); bool inCombat() { return _inCombat; } bool isMoving() { return _isMoving; } void setMoving(bool value) { _isMoving = value; } bool isWalking(); - void stopWalking(int value); - - void changeAnimationMode(int animationMode, int force); + void stopWalking(bool value); + + void changeAnimationMode(int animationMode, bool force); + void setFps(int fps); void faceActor(int otherActorId, bool animate); void faceObject(char *objectName, bool animate); @@ -128,19 +142,14 @@ class Actor { void faceXYZ(float x, float y, float z, bool animate); void faceCurrentCamera(bool animate); void faceHeading(int heading, bool animate); - int getFriendlinessToOther(int otherActorId); void modifyFriendlinessToOther(int otherActorId, signed int change); void setFriendlinessToOther(int otherActorId, int friendliness); void setHonesty(int honesty); void setIntelligence(int intelligence); void setStability(int stability); void setCombatAggressiveness(int combatAggressiveness); - int getCurrentHP(); - int getMaxHP(); - int getCombatAggressiveness(); - int getHonesty(); - int getIntelligence(); - int getStability(); + void setInvisible(bool isInvisible); + void setImmunityToObstacles(bool isImmune); void modifyCurrentHP(signed int change); void modifyMaxHP(signed int change); void modifyCombatAggressiveness(signed int change); @@ -149,13 +158,27 @@ class Actor { void modifyStability(signed int change); void setFlagDamageAnimIfMoving(bool value); bool getFlagDamageAnimIfMoving(); + void setHealth(int hp, int maxHp); + void retire(bool isRetired, int width, int height, int retiredByActorId); - void retire(bool isRetired, int unknown1, int unknown2, int retiredByActorId); + void combatModeOn(int a2, int a3, int a4, int a5, int combatAnimationMode, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14); + void combatModeOff(); + void setGoal(int goalNumber); + int getGoal(); + float distanceFromActor(int otherActorId); + void speechPlay(int sentenceId, bool voiceOver); + void speechStop(); + bool isSpeeching(); + void addClueToDatabase(int clueId, int unknown, bool clueAcquired, bool unknownFlag, int fromActorId); + void acquireClue(int clueId, byte unknownFlag, int fromActorId); + void loseClue(int clueId); + bool hasClue(int clueId); + void copyClues(int actorId); private: void setFacing(int facing, bool halfOrSet); void setBoundingBox(Vector3 position, bool retired); diff --git a/engines/bladerunner/actor_clues.cpp b/engines/bladerunner/actor_clues.cpp index f99b6b1d61f2..c8bc04c32895 100644 --- a/engines/bladerunner/actor_clues.cpp +++ b/engines/bladerunner/actor_clues.cpp @@ -64,7 +64,7 @@ namespace BladeRunner _clues[clueIndex]._flags = 0; } - int ActorClues::isAcquired(int clueId) + bool ActorClues::isAcquired(int clueId) { int clueIndex = findClueIndex(clueId); if (clueIndex == -1) @@ -82,7 +82,7 @@ namespace BladeRunner return _clues[clueIndex]._fromActorId; } - int ActorClues::isFlag2(int clueId) + bool ActorClues::isFlag2(int clueId) { int clueIndex = findClueIndex(clueId); if (clueIndex == -1) @@ -91,7 +91,7 @@ namespace BladeRunner return (_clues[clueIndex]._flags & 0x02) >> 1; } - int ActorClues::isFlag3(int clueId) + bool ActorClues::isFlag3(int clueId) { int clueIndex = findClueIndex(clueId); if (clueIndex == -1) @@ -100,7 +100,7 @@ namespace BladeRunner return (_clues[clueIndex]._flags & 0x04) >> 2; } - int ActorClues::isFlag4(int clueId) + bool ActorClues::isFlag4(int clueId) { int clueIndex = findClueIndex(clueId); if (clueIndex == -1) @@ -144,14 +144,14 @@ namespace BladeRunner return -1; } - void ActorClues::add(int actorId, int clueId, int field1, char acquired, char flag2, int fromActorId) + void ActorClues::add(int actorId, int clueId, int unknown, bool acquired, bool unknownFlag, int fromActorId) { _clues[_count]._clueId = clueId; - _clues[_count]._field1 = field1; + _clues[_count]._field1 = unknown; _clues[_count]._flags = 0; _clues[_count]._flags = _clues[_count]._flags & 0xFE | (acquired & 0x01); - _clues[_count]._flags = _clues[_count]._flags & 0xFD | ((flag2 << 1) & 0x02); + _clues[_count]._flags = _clues[_count]._flags & 0xFD | ((unknownFlag << 1) & 0x02); _clues[_count]._fromActorId = fromActorId; ++_count; @@ -172,7 +172,7 @@ namespace BladeRunner _clues[index]._field8 = 0; } - int ActorClues::exists(int clueId) + bool ActorClues::exists(int clueId) { return findClueIndex(clueId) != -1; } diff --git a/engines/bladerunner/actor_clues.h b/engines/bladerunner/actor_clues.h index 02d6bbb1cafa..0f08254a6021 100644 --- a/engines/bladerunner/actor_clues.h +++ b/engines/bladerunner/actor_clues.h @@ -56,13 +56,14 @@ namespace BladeRunner { ActorClues(BladeRunnerEngine *_vm, int cluesType); ~ActorClues(); + void add(int actorId, int clueId, int unknown, bool acquired, bool unknownFlag, int fromActorId); void acquire(int clueId, char flag2, int fromActorId); void lose(int clueId); - int isAcquired(int clueId); + bool isAcquired(int clueId); int getFromActorId(int clueId); - int isFlag2(int clueId); - int isFlag3(int clueId); - int isFlag4(int clueId); + bool isFlag2(int clueId); + bool isFlag3(int clueId); + bool isFlag4(int clueId); int getField1(int clueId); int getCount(); @@ -72,10 +73,10 @@ namespace BladeRunner { //savegame //loadgame private: + bool exists(int clueId); int findClueIndex(int clueId); - void add(int actorId, int clueId, int field1, char acquired, char flag2, int fromActorId); void remove(int clueIndex); - int exists(int clueId); + }; } diff --git a/engines/bladerunner/actor_combat.cpp b/engines/bladerunner/actor_combat.cpp index 286ec1d938c3..f595b010eece 100644 --- a/engines/bladerunner/actor_combat.cpp +++ b/engines/bladerunner/actor_combat.cpp @@ -8,4 +8,19 @@ ActorCombat::ActorCombat(BladeRunnerEngine* vm) { ActorCombat::~ActorCombat() { } + + +void ActorCombat::hitAttempt() { +} + + +void ActorCombat::combatOn(int actorId, int a3, int a4, int otherActorId, int a6, int a7, int a8, int a9, int ammoDamage, int a11, int a12) { +} + +void ActorCombat::combatOff() { +} + + +void ActorCombat::setup() { +} } \ No newline at end of file diff --git a/engines/bladerunner/actor_combat.h b/engines/bladerunner/actor_combat.h index a4ab4c9b78a3..0f6ccc9102ce 100644 --- a/engines/bladerunner/actor_combat.h +++ b/engines/bladerunner/actor_combat.h @@ -58,6 +58,13 @@ namespace BladeRunner { public: ActorCombat(BladeRunnerEngine *vm); ~ActorCombat(); + + void setup(); + + void hitAttempt(); + + void combatOn(int actorId, int a3, int a4, int otherActorId, int a6, int a7, int a8, int a9, int a10, int a11, int a12); + void combatOff(); }; } diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp index 62d6a819ffdc..0f5f320382e6 100644 --- a/engines/bladerunner/bladerunner.cpp +++ b/engines/bladerunner/bladerunner.cpp @@ -46,6 +46,7 @@ #include "bladerunner/vqa_decoder.h" #include "bladerunner/waypoints.h" #include "bladerunner/items.h" +#include "bladerunner/combat.h" #include "common/array.h" #include "common/error.h" @@ -69,6 +70,7 @@ BladeRunnerEngine::BladeRunnerEngine(OSystem *syst) _script = new Script(this); _settings = new Settings(this); _lights = new Lights(this); + _combat = new Combat(this); } BladeRunnerEngine::~BladeRunnerEngine() { @@ -91,7 +93,8 @@ BladeRunnerEngine::~BladeRunnerEngine() { // delete[] _zBuffer1; // delete[] _zBuffer2; - delete _items; + + delete _combat; delete _waypoints; delete _lights; delete _settings; @@ -402,7 +405,8 @@ void BladeRunnerEngine::shutdown() { // TODO: Delete KIA6PT.FON - // TODO: Delete Items + delete _items; + _items = 0; delete _gameFlags; _gameFlags = 0; @@ -553,6 +557,12 @@ void BladeRunnerEngine::handleEvents() { } } +void BladeRunnerEngine::gameWaitForActive() { + while(!_windowIsActive) { + handleEvents(); + } +} + void BladeRunnerEngine::loopActorSpeaking() { if (!_audioSpeech->isPlaying()) return; diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h index 87391d749c93..e90889adb8b6 100644 --- a/engines/bladerunner/bladerunner.h +++ b/engines/bladerunner/bladerunner.h @@ -57,6 +57,7 @@ class Lights; class View; class Waypoints; class Items; +class Combat; class BladeRunnerEngine : public Engine { @@ -85,6 +86,7 @@ class BladeRunnerEngine : public Engine { Lights *_lights; Waypoints *_waypoints; Items *_items; + Combat *_combat; TextResource *_textActorNames; TextResource *_textCrimes; @@ -111,7 +113,12 @@ class BladeRunnerEngine : public Engine { bool _playerActorIdle; bool _playerDead; - + bool _speechSkipped; + bool _gameOver; + int _gameAutoSave; + bool _gameIsLoading; + bool _sceneIsLoading; + private: static const int kArchiveCount = 10; MIXArchive _archives[kArchiveCount]; @@ -130,10 +137,11 @@ class BladeRunnerEngine : public Engine { bool loadSplash(); bool init2(); - + void gameLoop(); void gameTick(); void handleEvents(); + void gameWaitForActive(); void loopActorSpeaking(); void outtakePlay(int id, bool no_localization, int container = -1); diff --git a/engines/bladerunner/combat.cpp b/engines/bladerunner/combat.cpp new file mode 100644 index 000000000000..5fe2e3f36e44 --- /dev/null +++ b/engines/bladerunner/combat.cpp @@ -0,0 +1,59 @@ +#include "bladerunner/combat.h" +#include "bladerunner/bladerunner.h" +#include "bladerunner/actor.h" +#include "bladerunner/settings.h" + +namespace BladeRunner { + + +Combat::Combat(BladeRunnerEngine* vm) { + _vm = vm; + + _active = false; + _enabled = true; + + int i; + for (i = 0; i < 9; i++) { + _hitSoundId[i] = -1; + _missSoundId[i] = -1; + } +} + +Combat::~Combat() { +} + +void Combat::activate() { + if(_enabled) { + _vm->_playerActor->combatModeOn(-1, -1, -1, -1, 4, 7, 8, -1, -1, -1, _vm->_combat->_ammoDamage[_vm->_settings->getAmmoType()], 0, 0); + _active = true; + } +} + +void Combat::deactivate() { + if (_enabled) { + _vm->_playerActor->combatModeOff(); + _active = false; + } +} + +bool Combat::isActive() { + return _active; +} + +void Combat::enable() { + _enabled = true; +} + +void Combat::disable() { + _enabled = false; +} + + +void Combat::setHitSoundId(int row, int column, int soundId) { + _hitSoundId[row * 3 + column] = soundId; +} + +void Combat::setMissSoundId(int row, int column, int soundId) { + _missSoundId[row * 3 + column] = soundId; +} +} \ No newline at end of file diff --git a/engines/bladerunner/combat.h b/engines/bladerunner/combat.h new file mode 100644 index 000000000000..5860fd76d0dc --- /dev/null +++ b/engines/bladerunner/combat.h @@ -0,0 +1,61 @@ +/* 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 BLADERUNNER_COMBAT_H +#define BLADERUNNER_COMBAT_H + +#include "bladerunner/bladerunner.h" + +namespace BladeRunner { + +class Combat { + BladeRunnerEngine *_vm; + + bool _active; + bool _enabled; + int _hitSoundId[9]; + int _missSoundId[9]; + int _random1; + int _random2; + +public: + int _ammoDamage[3] = { 10, 20, 30 }; + +public: + Combat(BladeRunnerEngine *vm); + ~Combat(); + + void activate(); + void deactivate(); + bool isActive(); + + void enable(); + void disable(); + + void setHitSoundId(int row, int column, int soundId); + void setMissSoundId(int row, int column, int soundId); + +}; + +} + +#endif diff --git a/engines/bladerunner/items.cpp b/engines/bladerunner/items.cpp index 7d717ff1cec8..be03b9beafb6 100644 --- a/engines/bladerunner/items.cpp +++ b/engines/bladerunner/items.cpp @@ -19,7 +19,7 @@ void Items::getXyz(int itemId, float* x, float* y, float* z) { int Items::findItem(int itemId) { int i; - for (i = 0; i < _items.size();i++) { + for (i = 0; i < (int)_items.size(); i++) { if (_items[i]._itemId == itemId) return i; } diff --git a/engines/bladerunner/mouse.cpp b/engines/bladerunner/mouse.cpp index 2eede84de15d..64c64b24355f 100644 --- a/engines/bladerunner/mouse.cpp +++ b/engines/bladerunner/mouse.cpp @@ -27,7 +27,7 @@ #include "bladerunner/scene.h" #include "graphics/surface.h" -#include "common/rect.h"" +#include "common/rect.h" namespace BladeRunner { diff --git a/engines/bladerunner/scene.cpp b/engines/bladerunner/scene.cpp index c734a1a82f1f..3c04ee881428 100644 --- a/engines/bladerunner/scene.cpp +++ b/engines/bladerunner/scene.cpp @@ -148,6 +148,11 @@ int Scene::getSetId() { return _setId; } + +int Scene::getSceneId() { + return _sceneId; +} + int Scene::findObject(char* objectName) { return _set->findObject(objectName); } @@ -160,4 +165,38 @@ 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->updateWalkpath(); + } + } +} + +void Scene::objectSetIsObstacleAll(bool isObstacle, bool sceneLoaded) { + int i; + for (i = 0; i < (int)_set->_objectCount; i++) { + _set->objectSetIsObstacle(i, isObstacle); + if (sceneLoaded) { + _vm->_sceneObjects->setIsObstacle(i + 198, isObstacle); + } + } +} + +void Scene::objectSetIsCombatTarget(int objectId, bool isCombatTarget, bool sceneLoaded) { + _set->objectSetIsCombatTarget(objectId, isCombatTarget); + if (sceneLoaded) { + _vm->_sceneObjects->setIsCombatTarget(objectId + 198, isCombatTarget); + } +} + } // End of namespace BladeRunner diff --git a/engines/bladerunner/scene.h b/engines/bladerunner/scene.h index 97a9b3409fe1..cabd912b0d1e 100644 --- a/engines/bladerunner/scene.h +++ b/engines/bladerunner/scene.h @@ -77,9 +77,14 @@ class Scene { int advanceFrame(Graphics::Surface &surface, uint16 *&zBuffer); void setActorStart(Vector3 position, int facing); int getSetId(); + int getSceneId(); int findObject(char *objectName); bool objectSetHotMouse(int objectId); bool objectGetBoundingBox(int objectId, BoundingBox *boundingBox); + void objectSetIsClickable(int objectId, bool isClickable, bool sceneLoaded); + void objectSetIsObstacle(int objectId, bool isObstacle, bool sceneLoaded, bool updateWalkpath); + void objectSetIsObstacleAll(bool isObstacle, bool sceneLoaded); + void objectSetIsCombatTarget(int objectId, bool isCombatTarget, bool sceneLoaded); }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/scene_objects.cpp b/engines/bladerunner/scene_objects.cpp index 6ac00dc63538..ec9e247fd22f 100644 --- a/engines/bladerunner/scene_objects.cpp +++ b/engines/bladerunner/scene_objects.cpp @@ -2,183 +2,239 @@ namespace BladeRunner { - SceneObjects::SceneObjects(BladeRunnerEngine *vm, View *view) { - _vm = vm; - _view = view; +SceneObjects::SceneObjects(BladeRunnerEngine *vm, View *view) { + _vm = vm; + _view = view; - _count = 0; - _sceneObjects = new SceneObject[SCENE_OBJECTS_COUNT]; - _sceneObjectsSortedByDistance = new int[SCENE_OBJECTS_COUNT]; + _count = 0; + _sceneObjects = new SceneObject[SCENE_OBJECTS_COUNT]; + _sceneObjectsSortedByDistance = new int[SCENE_OBJECTS_COUNT]; - int i; - for (i = 0; i < SCENE_OBJECTS_COUNT; i++) { - _sceneObjectsSortedByDistance[i] = -1; - } + int i; + for (i = 0; i < SCENE_OBJECTS_COUNT; i++) { + _sceneObjectsSortedByDistance[i] = -1; } +} + +SceneObjects::~SceneObjects() { + _vm = nullptr; + _view = nullptr; + _count = 0; + + delete[] _sceneObjectsSortedByDistance; + delete[] _sceneObjects; +} - SceneObjects::~SceneObjects() { - _vm = nullptr; - _view = nullptr; - _count = 0; - delete[] _sceneObjectsSortedByDistance; - delete[] _sceneObjects; +void SceneObjects::clear() { + int i; + for (i = 0; i < SCENE_OBJECTS_COUNT; i++) { + _sceneObjects[i]._sceneObjectId = -1; + _sceneObjects[i]._sceneObjectType = SceneObjectTypeUnknown; + _sceneObjects[i]._distanceToCamera = 0; + _sceneObjects[i]._present = 0; + _sceneObjects[i]._isClickable = 0; + _sceneObjects[i]._isObstacle = 0; + _sceneObjects[i]._unknown1 = 0; + _sceneObjects[i]._isCombatTarget = 0; + _sceneObjects[i]._isMoving = 0; + _sceneObjects[i]._isRetired = 0; } +} +bool SceneObjects::addActor(int sceneObjectId, BoundingBox* boundingBox, Common::Rect* screenRectangle, uint8 isClickable, uint8 isMoving, uint8 isCombatTarget, uint8 isRetired) { + return addSceneObject(sceneObjectId, SceneObjectTypeActor, boundingBox, screenRectangle, isClickable, 0, 0, isCombatTarget, isMoving, isRetired); +} - void SceneObjects::clear() { - int i; - for (i = 0; i < SCENE_OBJECTS_COUNT; i++) { - _sceneObjects[i]._sceneObjectId = -1; - _sceneObjects[i]._sceneObjectType = SceneObjectTypeUnknown; - _sceneObjects[i]._distanceToCamera = 0; - _sceneObjects[i]._present = 0; - _sceneObjects[i]._isClickable = 0; - _sceneObjects[i]._isObstacle = 0; - _sceneObjects[i]._unknown1 = 0; - _sceneObjects[i]._isCombatTarget = 0; - _sceneObjects[i]._isMoving = 0; - _sceneObjects[i]._isRetired = 0; +bool SceneObjects::addObject(int sceneObjectId, BoundingBox* boundingBox, uint8 isClickable, uint8 isObstacle, uint8 unknown1, uint8 isCombatTarget) { + Common::Rect rect(-1, -1, -1, -1); + return addSceneObject(sceneObjectId, SceneObjectTypeObject, boundingBox, &rect, isClickable, isObstacle, unknown1, isCombatTarget, 0, 0); +} + +bool SceneObjects::addItem(int sceneObjectId, BoundingBox* boundingBox, Common::Rect* screenRectangle, uint8 isCombatTarget, uint8 isObstacle) { + return addSceneObject(sceneObjectId, SceneObjectTypeItem, boundingBox, screenRectangle, isObstacle, 0, 0, isCombatTarget, 0, 0); +} + +bool SceneObjects::remove(int sceneObjectId) +{ + int i = findById(sceneObjectId); + if (i == -1 || !_sceneObjects[i]._present) { + return false; + } + int j; + for (j = 0; j < _count; j++) { + if (_sceneObjectsSortedByDistance[j] == i) { + break; } } - - bool SceneObjects::addActor(int sceneObjectId, BoundingBox* boundingBox, Common::Rect* screenRectangle, uint8 isClickable, uint8 isMoving, uint8 isCombatTarget, uint8 isRetired) { - return addSceneObject(sceneObjectId, SceneObjectTypeActor, boundingBox, screenRectangle, isClickable, 0, 0, isCombatTarget, isMoving, isRetired); + int k; + for (k = j; k < _count - 1; k++) { + _sceneObjectsSortedByDistance[k] = _sceneObjectsSortedByDistance[k + 1]; } - bool SceneObjects::addObject(int sceneObjectId, BoundingBox* boundingBox, uint8 isClickable, uint8 isObstacle, uint8 unknown1, uint8 isCombatTarget) { - Common::Rect rect(-1, -1, -1, -1); - return addSceneObject(sceneObjectId, SceneObjectTypeObject, boundingBox, &rect, isClickable, isObstacle, unknown1, isCombatTarget, 0, 0); - } + --_count; + return true; +} - bool SceneObjects::addItem(int sceneObjectId, BoundingBox* boundingBox, Common::Rect* screenRectangle, uint8 isCombatTarget, uint8 isObstacle) { - return addSceneObject(sceneObjectId, SceneObjectTypeItem, boundingBox, screenRectangle, isObstacle, 0, 0, isCombatTarget, 0, 0); - } +int SceneObjects::findByXYZ(int *isClickable, int *isObstacle, int *isCombatTarget, float x, float y, float z, int mustBeClickable, int mustBeObstacle, int mustBeCombatTarget) { + BoundingBox boundingBox; + *isClickable = 0; + *isObstacle = 0; + *isCombatTarget = 0; - bool SceneObjects::remove(int sceneObjectId) - { - int i = findById(sceneObjectId); - if (i == -1 || !_sceneObjects[i]._present) { - return false; + if (!_count) + return -1; + + int i; + for (i = 0; i < _count; i++) { + //assert(_sceneObjectsSortedByDistance[i] < _count); + SceneObject *sceneObject = &_sceneObjects[_sceneObjectsSortedByDistance[i]]; + if ((mustBeClickable && !sceneObject->_isClickable) + || (mustBeObstacle && !sceneObject->_isObstacle) + || (mustBeCombatTarget && !sceneObject->_isCombatTarget)) { + continue; } - int j; - for (j = 0; j < _count; j++) { - if (_sceneObjectsSortedByDistance[j] == i) { - break; - } + + boundingBox = sceneObject->_boundingBox; + + if (sceneObject->_sceneObjectType == SceneObjectTypeObject || sceneObject->_sceneObjectType == SceneObjectTypeItem) { + boundingBox.expand(-4.0, 0.0, -4.0, 4.0, 0.0, 4.0); } - int k; - for (k = j; k < _count - 1; k++) { - _sceneObjectsSortedByDistance[k] = _sceneObjectsSortedByDistance[k + 1]; + + if (boundingBox.inside(x, y, z)) { + *isClickable = sceneObject->_isClickable; + *isObstacle = sceneObject->_isObstacle; + *isCombatTarget = sceneObject->_isCombatTarget; + return sceneObject->_sceneObjectId; } + } - --_count; - return true; - } - - int SceneObjects::findByXYZ(int *isClickable, int *isObstacle, int *isCombatTarget, float x, float y, float z, int mustBeClickable, int mustBeObstacle, int mustBeCombatTarget) { - BoundingBox boundingBox; - *isClickable = 0; - *isObstacle = 0; - *isCombatTarget = 0; - - if (!_count) - return -1; - - int i; - for (i = 0; i < _count; i++) { - //assert(_sceneObjectsSortedByDistance[i] < _count); - SceneObject *sceneObject = &_sceneObjects[_sceneObjectsSortedByDistance[i]]; - if ((mustBeClickable && !sceneObject->_isClickable) - || (mustBeObstacle && !sceneObject->_isObstacle) - || (mustBeCombatTarget && !sceneObject->_isCombatTarget)) { - continue; - } - - boundingBox = sceneObject->_boundingBox; - - if (sceneObject->_sceneObjectType == SceneObjectTypeObject || sceneObject->_sceneObjectType == SceneObjectTypeItem) { - boundingBox.expand(-4.0, 0.0, -4.0, 4.0, 0.0, 4.0); - } - - if (boundingBox.inside(x, y, z)) { - *isClickable = sceneObject->_isClickable; - *isObstacle = sceneObject->_isObstacle; - *isCombatTarget = sceneObject->_isCombatTarget; - return sceneObject->_sceneObjectId; - } + return -1; +} + +int SceneObjects::findById(int sceneObjectId) +{ + int i; + for (i = 0; i < _count; i++) { + if (_sceneObjects[i]._present && _sceneObjects[i]._sceneObjectId == sceneObjectId) { + return i; } + } + return -1; +} - return -1; +bool SceneObjects::addSceneObject(int sceneObjectId, SceneObjectType sceneObjectType, BoundingBox* boundingBox, Common::Rect* screenRectangle, uint8 isClickable, uint8 isObstacle, uint8 unknown1, uint8 isCombatTarget, uint isMoving, uint isRetired) { + int index = findEmpty(); + if (_count >= SCENE_OBJECTS_COUNT || index == -1) { + return false; } - int SceneObjects::findById(int sceneObjectId) - { - int i; - for (i = 0; i < _count; i++) { - if (_sceneObjects[i]._present && _sceneObjects[i]._sceneObjectId == sceneObjectId) { - return i; - } + _sceneObjects[index]._sceneObjectId = sceneObjectId; + _sceneObjects[index]._sceneObjectType = sceneObjectType; + _sceneObjects[index]._present = 1; + _sceneObjects[index]._boundingBox = *boundingBox; + _sceneObjects[index]._screenRectangle = *screenRectangle; + _sceneObjects[index]._isClickable = isClickable; + _sceneObjects[index]._isObstacle = isObstacle; + _sceneObjects[index]._unknown1 = unknown1; + _sceneObjects[index]._isCombatTarget = isCombatTarget; + _sceneObjects[index]._isMoving = isMoving; + _sceneObjects[index]._isRetired = isRetired; + + float centerZ = (_sceneObjects[index]._boundingBox.getZ0() + _sceneObjects[index]._boundingBox.getZ1()) / 2.0; + + float distanceToCamera = fabs(_view->_cameraPosition.z - centerZ); + _sceneObjects[index]._distanceToCamera = distanceToCamera; + + // insert according to distance from camera + int i, j; + for (i = 0; i < _count; i++) { + if (distanceToCamera < _sceneObjects[_sceneObjectsSortedByDistance[i]]._distanceToCamera) { + break; } - return -1; } - bool SceneObjects::addSceneObject(int sceneObjectId, SceneObjectType sceneObjectType, BoundingBox* boundingBox, Common::Rect* screenRectangle, uint8 isClickable, uint8 isObstacle, uint8 unknown1, uint8 isCombatTarget, uint isMoving, uint isRetired) { - int index = findEmpty(); - if (_count >= SCENE_OBJECTS_COUNT || index == -1) { - return false; - } + for (j = _count - 1; j >= i; j--) { + _sceneObjectsSortedByDistance[j + 1] = _sceneObjectsSortedByDistance[j]; + } - _sceneObjects[index]._sceneObjectId = sceneObjectId; - _sceneObjects[index]._sceneObjectType = sceneObjectType; - _sceneObjects[index]._present = 1; - _sceneObjects[index]._boundingBox = *boundingBox; - _sceneObjects[index]._screenRectangle = *screenRectangle; - _sceneObjects[index]._isClickable = isClickable; - _sceneObjects[index]._isObstacle = isObstacle; - _sceneObjects[index]._unknown1 = unknown1; - _sceneObjects[index]._isCombatTarget = isCombatTarget; - _sceneObjects[index]._isMoving = isMoving; - _sceneObjects[index]._isRetired = isRetired; - - float centerZ = (_sceneObjects[index]._boundingBox.getZ0() + _sceneObjects[index]._boundingBox.getZ1()) / 2.0; - - float distanceToCamera = fabs(_view->_cameraPosition.z - centerZ); - _sceneObjects[index]._distanceToCamera = distanceToCamera; - - // insert according to distance from camera - int i, j; - for (i = 0; i < _count; i++) { - if (distanceToCamera < _sceneObjects[_sceneObjectsSortedByDistance[i]]._distanceToCamera) { - break; - } - } + _sceneObjectsSortedByDistance[i] = index; + ++_count; + return true; +} - for (j = _count - 1; j >= i; j--) { - _sceneObjectsSortedByDistance[j + 1] = _sceneObjectsSortedByDistance[j]; - } +int SceneObjects::findEmpty() { + int i; + for (i = 0; i < SCENE_OBJECTS_COUNT; i++) + { + if (!_sceneObjects[i]._present) + return i; + } + return -1; +} - _sceneObjectsSortedByDistance[i] = index; - ++_count; - return true; +void SceneObjects::setMoving(int sceneObjectId, bool isMoving) { + int i = findById(sceneObjectId); + if (i == -1 || !_sceneObjects[i]._present) { + return; } + _sceneObjects[i]._isMoving = isMoving; +} - int SceneObjects::findEmpty() { - int i; - for (i = 0; i < SCENE_OBJECTS_COUNT; i++) - { - if (!_sceneObjects[i]._present) - return i; - } - return -1; +void SceneObjects::setRetired(int sceneObjectId, bool isRetired) { + int i = findById(sceneObjectId); + if (i == -1 || !_sceneObjects[i]._present) { + return; } + _sceneObjects[i]._isRetired = isRetired; +} - void SceneObjects::setMoving(int sceneObjectId, bool isMoving) { - int i = findById(sceneObjectId); - if (i == -1 || !_sceneObjects[i]._present) { - return; - } - _sceneObjects[i]._isMoving = isMoving; +bool SceneObjects::isBetweenTwoXZ(int sceneObjectId, float x1, float z1, float x2, float z2) { + int i = findById(sceneObjectId); + if (i == -1 || !_sceneObjects[i]._present) { + return false; } + float objectX1, objectY1, objectZ1, objectX2, objectY2, objectZ2; + _sceneObjects[i]._boundingBox.getXyz(&objectX1, &objectY1, &objectZ1, &objectX2, &objectY2, &objectZ2); + + //TODO +// if (!lineIntersectection(sourceX, sourceZ, targetX, targetZ, objectX1, objectZ1, objectX2, objectZ1, &intersectionX, &intersectionY, &v18) +// && !lineIntersectection(sourceX, sourceZ, targetX, targetZ, objectX2, objectZ1, objectX2, objectZ2, &intersectionX, &intersectionY, &v18) +// && !lineIntersectection(sourceX, sourceZ, targetX, targetZ, objectX2, objectZ2, objectX1, objectZ2, &intersectionX, &intersectionY, &v18) +// && !lineIntersectection(sourceX, sourceZ, targetX, targetZ, objectX1, objectZ2, objectX1, objectZ1, &intersectionX, &intersectionY, &v18)) +// return false; + return true; +} + + +void SceneObjects::setIsClickable(int sceneObjectId, bool isClickable) { + int i = findById(sceneObjectId); + if (i == -1 || !_sceneObjects[i]._present) { + return; + } + _sceneObjects[i]._isClickable = isClickable; +} + +void SceneObjects::setIsObstacle(int sceneObjectId, bool isObstacle) { + int i = findById(sceneObjectId); + if (i == -1 || !_sceneObjects[i]._present) { + return; + } + _sceneObjects[i]._isObstacle = isObstacle; +} + +void SceneObjects::setIsCombatTarget(int sceneObjectId, bool isCombatTarget) { + int i = findById(sceneObjectId); + if (i == -1 || !_sceneObjects[i]._present) { + return; + } + _sceneObjects[i]._isCombatTarget = isCombatTarget; +} + + +void SceneObjects::updateWalkpath() { + //TODO: implement +} + } diff --git a/engines/bladerunner/scene_objects.h b/engines/bladerunner/scene_objects.h index 16188d96ab6b..bccb2ea376ec 100644 --- a/engines/bladerunner/scene_objects.h +++ b/engines/bladerunner/scene_objects.h @@ -81,6 +81,12 @@ namespace BladeRunner { void clear(); int findByXYZ(int *isClickable, int *isObstacle, int *isCombatTarget, float x, float y, float z, int mustBeClickable, int mustBeObstacle, int mustBeCombatTarget); void setMoving(int sceneObjectId, bool isMoving); + void setRetired(int sceneObjectId, bool isRetired); + bool isBetweenTwoXZ(int sceneObjectId, float x1, float z1, float x2, float z2); + void setIsClickable(int sceneObjectId, bool isClickable); + void setIsObstacle(int sceneObjectId, bool isObstacle); + void setIsCombatTarget(int sceneObjectId, bool isCombatTarget); + void updateWalkpath(); private: int findById(int sceneObjectId); bool addSceneObject(int sceneObjectId, SceneObjectType sceneObjectType, BoundingBox* boundingBox, Common::Rect* screenRectangle, uint8 isClickable, uint8 isObstacle, uint8 unknown1, uint8 isCombatTarget, uint unknown2, uint isRetired); diff --git a/engines/bladerunner/set.cpp b/engines/bladerunner/set.cpp index 7c1f25dcb04f..070fd64498aa 100644 --- a/engines/bladerunner/set.cpp +++ b/engines/bladerunner/set.cpp @@ -130,7 +130,7 @@ int Set::findWalkbox(float x, float z) { int i; float altitude = 0.0f; int foundWalkboxId = -1; - for (i = 0; i < _walkboxCount; i++) { + for (i = 0; i < (int)_walkboxCount; i++) { if (isXzInWalkbox(x, z, &_walkboxes[i])) { if (foundWalkboxId == -1 || altitude < _walkboxes[i]._altitude) { altitude = _walkboxes[i]._altitude; @@ -147,7 +147,7 @@ bool Set::isXzInWalkbox(float x, float z, Walkbox* walkbox) { float lastX = walkbox->_vertices[walkbox->_vertexCount - 1].x; float lastZ = walkbox->_vertices[walkbox->_vertexCount - 1].z; - for (i = 0; i < walkbox->_vertexCount; i++) { + for (i = 0; i < (int)walkbox->_vertexCount; i++) { float currentX = walkbox->_vertices[i].x; float currentZ = walkbox->_vertices[i].z; @@ -165,7 +165,7 @@ bool Set::isXzInWalkbox(float x, float z, Walkbox* walkbox) { int Set::findObject(char* objectName) { int i; - for (i = 0; i < _objectCount; i++) { + for (i = 0; i < (int)_objectCount; i++) { if (scumm_stricmp(objectName, _objects[i]._name) == 0) { return i; } @@ -174,7 +174,7 @@ int Set::findObject(char* objectName) { } bool Set::objectSetHotMouse(int objectId) { - if(!_objects || objectId < 0 || objectId >= _objectCount) { + if(!_objects || objectId < 0 || objectId >= (int)_objectCount) { return false; } @@ -185,7 +185,7 @@ bool Set::objectSetHotMouse(int objectId) { bool Set::objectGetBoundingBox(int objectId, BoundingBox* boundingBox) { assert(boundingBox); - if (!_objects || objectId < 0 || objectId >= _objectCount) { + if (!_objects || objectId < 0 || objectId >= (int)_objectCount) { boundingBox->setXyz(0, 0, 0, 0, 0, 0); return false; } @@ -197,4 +197,16 @@ bool Set::objectGetBoundingBox(int objectId, BoundingBox* boundingBox) { return true; } +void Set::objectSetIsClickable(int objectId, bool isClickable) { + _objects[objectId]._isClickable = isClickable; +} + +void Set::objectSetIsObstacle(int objectId, bool isObstacle) { + _objects[objectId]._isObstacle = isObstacle; +} + +void Set::objectSetIsCombatTarget(int objectId, bool isCombatTarget) { + _objects[objectId]._isCombatTarget = isCombatTarget; +} + } // End of namespace BladeRunner diff --git a/engines/bladerunner/set.h b/engines/bladerunner/set.h index 395ec6cf6de3..2db9c826eb6a 100644 --- a/engines/bladerunner/set.h +++ b/engines/bladerunner/set.h @@ -66,9 +66,8 @@ class Set { Walkbox *_walkboxes; int _walkboxStepSound[85]; int _footstepSoundOverride; - SetEffects *_effects; public: - + SetEffects *_effects; public: Set(BladeRunnerEngine *vm); @@ -82,6 +81,9 @@ class Set { bool objectSetHotMouse(int objectId); bool objectGetBoundingBox(int objectId, BoundingBox *boundingBox); + void objectSetIsClickable(int objectId, bool isClickable); + void objectSetIsObstacle(int objectId, bool isObstacle); + void objectSetIsCombatTarget(int objectId, bool isCombatTarget); private: bool isXzInWalkbox(float x, float z, Walkbox* walkbox); diff --git a/engines/bladerunner/set_effects.cpp b/engines/bladerunner/set_effects.cpp index f52482003343..6db81ce631ed 100644 --- a/engines/bladerunner/set_effects.cpp +++ b/engines/bladerunner/set_effects.cpp @@ -2,82 +2,121 @@ namespace BladeRunner { - SetEffects::SetEffects(BladeRunnerEngine* vm) - { - _vm = vm; - - _distanceColor.r = 1.0f; - _distanceColor.g = 1.0f; - _distanceColor.b = 1.0f; - _distanceCoeficient = 0.1f; - - _fadeColor.r = 0.0f; - _fadeColor.g = 0.0f; - _fadeColor.b = 0.0f; - _fadeDensity = 0.0f; - - _fogsCount = 0; - _fogs = NULL; - } - SetEffects::~SetEffects() - { - reset(); - } +SetEffects::SetEffects(BladeRunnerEngine* vm) { + _vm = vm; + + _distanceColor.r = 1.0f; + _distanceColor.g = 1.0f; + _distanceColor.b = 1.0f; + _distanceCoeficient = 0.1f; + + _fadeColor.r = 0.0f; + _fadeColor.g = 0.0f; + _fadeColor.b = 0.0f; + _fadeDensity = 0.0f; + + _fogsCount = 0; + _fogs = NULL; +} + +SetEffects::~SetEffects() { + reset(); +} - void SetEffects::read(Common::ReadStream* stream, int framesCount) - { - _distanceCoeficient = stream->readFloatLE(); - _distanceColor.r = stream->readFloatLE(); - _distanceColor.g = stream->readFloatLE(); - _distanceColor.b = stream->readFloatLE(); +void SetEffects::read(Common::ReadStream* stream, int framesCount) { + _distanceCoeficient = stream->readFloatLE(); + _distanceColor.r = stream->readFloatLE(); + _distanceColor.g = stream->readFloatLE(); + _distanceColor.b = stream->readFloatLE(); - _fogsCount = stream->readUint32LE(); - int i; - for (i = 0; i < _fogsCount; i++) + _fogsCount = stream->readUint32LE(); + int i; + for (i = 0; i < _fogsCount; i++) { + int type = stream->readUint32LE(); + Fog* fog = NULL; + switch (type) { - int type = stream->readUint32LE(); - Fog* fog = NULL; - switch(type) - { - case 0: - fog = new FogCone(); - break; - case 1: - fog = new FogSphere(); - break; - case 2: - fog = new FogBox(); - break; - } - if(!fog) - { - //TODO exception, unknown fog type - } - fog->read(stream, framesCount); - fog->_next = _fogs; - _fogs = fog; + case 0: + fog = new FogCone(); + break; + case 1: + fog = new FogSphere(); + break; + case 2: + fog = new FogBox(); + break; } + if (!fog) + { + //TODO exception, unknown fog type + } + fog->read(stream, framesCount); + fog->_next = _fogs; + _fogs = fog; } +} - void SetEffects::reset() - { - Fog* fog, *nextFog; - - if (!_fogs) - return; +void SetEffects::reset() { + Fog* fog, *nextFog; - do - { - fog = _fogs; - nextFog = fog->_next; - delete fog; - fog = nextFog; - } while (nextFog); + if (!_fogs) + return; - } + do { + fog = _fogs; + nextFog = fog->_next; + delete fog; + fog = nextFog; + } while (nextFog); + +} + +void SetEffects::setupFrame(int frame) { +} - void SetEffects::setupFrame(int frame) - { +void SetEffects::setFadeColor(float r, float g, float b) { + _fadeColor.r = r; + _fadeColor.r = g; + _fadeColor.b = b; +} + +void SetEffects::setFadeDensity(float density) { + _fadeDensity = density; +} + +void SetEffects::setFogColor(char* fogName, float r, float g, float b) { + Fog* fog = findFog(fogName); + if (fog == nullptr) + return; + + fog->_fogColor.r = r; + fog->_fogColor.g = g; + fog->_fogColor.b = b; +} + +void SetEffects::setFogDensity(char* fogName, float density) { + Fog* fog = findFog(fogName); + if (fog == nullptr) + return; + + fog->_fogDensity = density; +} + +Fog* SetEffects::findFog(char* fogName) { + if (!_fogs) + return nullptr; + + Fog* fog = _fogs; + + while (fog != nullptr) { + if (strcmp(fogName, fog->_name) == 0) { + break; + } + fog = fog->_next; } + + return fog; +} + } \ No newline at end of file diff --git a/engines/bladerunner/set_effects.h b/engines/bladerunner/set_effects.h index 5165cfba9418..8f628075fe99 100644 --- a/engines/bladerunner/set_effects.h +++ b/engines/bladerunner/set_effects.h @@ -29,34 +29,39 @@ #include "common/stream.h" - namespace BladeRunner { - class SetEffects - { - BladeRunnerEngine *_vm; +class SetEffects +{ + BladeRunnerEngine *_vm; + +private: + Color _distanceColor; + float _distanceCoeficient; + Color _fadeColor; + float _fadeDensity; + int _fogsCount; + Fog *_fogs; - private: - Color _distanceColor; - float _distanceCoeficient; - Color _fadeColor; - float _fadeDensity; - int _fogsCount; - Fog *_fogs; +public: + SetEffects(BladeRunnerEngine *vm); + ~SetEffects(); - public: - SetEffects(BladeRunnerEngine *vm); - ~SetEffects(); + void read(Common::ReadStream *stream, int framesCount); - void read(Common::ReadStream *stream, int framesCount); + void reset(); - void reset(); + void setupFrame(int frame); - void setupFrame(int frame); + void setFadeColor(float r, float g, float b); + void setFadeDensity(float density); + void setFogColor(char* fogName, float r, float g, float b); + void setFogDensity(char* fogName, float density); +private: - private: + Fog* findFog(char* fogName); - }; +}; } #endif diff --git a/engines/bladerunner/settings.cpp b/engines/bladerunner/settings.cpp index 0759762e9512..100f4924015d 100644 --- a/engines/bladerunner/settings.cpp +++ b/engines/bladerunner/settings.cpp @@ -95,4 +95,33 @@ bool Settings::openNewScene() { return true; } + +int Settings::getAmmoType() { + return _ammoType; +} + +int Settings::getAmmoAmount(int ammoType) { + return _ammoAmounts[ammoType]; +} + +void Settings::addAmmo(int ammoType, int ammo) { + if (ammoType > _ammoType || _ammoAmounts[_ammoType] == 0) + _ammoType = ammoType; + _ammoAmounts[ammoType] += ammo; +} + +int Settings::getDifficulty() { + return _difficulty; +} + +int Settings::getPlayerAgenda() { + return _playerAgenda; +} + +void Settings::setPlayerAgenda(int agenda) { + _playerAgenda = agenda; +} + + + } // End of namespace BladeRunner diff --git a/engines/bladerunner/settings.h b/engines/bladerunner/settings.h index 61ac42039d7b..e45eb32e88c7 100644 --- a/engines/bladerunner/settings.h +++ b/engines/bladerunner/settings.h @@ -44,6 +44,12 @@ class Settings { int _fullHDFrames; int _mst3k; + int _difficulty; + int _playerAgenda; + + int _ammoType; + int _ammoAmounts[3]; + public: Settings(BladeRunnerEngine *vm); @@ -87,6 +93,14 @@ class Settings { } bool openNewScene(); + + int getAmmoType(); + int getAmmoAmount(int ammoType); + + int getDifficulty(); + int getPlayerAgenda(); + void setPlayerAgenda(int agenda); + void addAmmo(int ammoType, int ammo); }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/slice_animations.cpp b/engines/bladerunner/slice_animations.cpp index efcd4b398742..b813c13a3d1e 100644 --- a/engines/bladerunner/slice_animations.cpp +++ b/engines/bladerunner/slice_animations.cpp @@ -63,14 +63,14 @@ bool SliceAnimations::open(const Common::String &name) { _animations.resize(animationCount); for (uint32 i = 0; i != animationCount; ++i) { - _animations[i].frameCount = file.readUint32LE(); - _animations[i].frameSize = file.readUint32LE(); - _animations[i].fps = file.readFloatLE(); - _animations[i].unk0 = file.readFloatLE(); - _animations[i].unk1 = file.readFloatLE(); - _animations[i].unk2 = file.readFloatLE(); - _animations[i].unk3 = file.readFloatLE(); - _animations[i].offset = file.readUint32LE(); + _animations[i].frameCount = file.readUint32LE(); + _animations[i].frameSize = file.readUint32LE(); + _animations[i].fps = file.readFloatLE(); + _animations[i].positionChange.x = file.readFloatLE(); + _animations[i].positionChange.y = file.readFloatLE(); + _animations[i].positionChange.z = file.readFloatLE(); + _animations[i].facingChange = file.readFloatLE(); + _animations[i].offset = file.readUint32LE(); #if 0 debug("%4d %6d %6x %7.2g %7.2g %7.2g %7.2g %7.2g %8x", @@ -172,8 +172,16 @@ void *SliceAnimations::getFramePtr(uint32 animation, uint32 frame) { int SliceAnimations::getNumberOfFrames(int animationId) { - if (animationId > _animations.size()) + if (animationId > (int)_animations.size()) return 0; return _animations[animationId].frameCount; } + + +float SliceAnimations::getFps(int animationId) { + if (animationId > (int)_animations.size()) + return 15.0f; + return _animations[animationId].fps; +} + } // End of namespace BladeRunner diff --git a/engines/bladerunner/slice_animations.h b/engines/bladerunner/slice_animations.h index b0c53b1e05a1..9af12e41c28e 100644 --- a/engines/bladerunner/slice_animations.h +++ b/engines/bladerunner/slice_animations.h @@ -23,6 +23,8 @@ #ifndef BLADERUNNER_SLICE_ANIMATIONS_H #define BLADERUNNER_SLICE_ANIMATIONS_H +#include "bladerunner/vector.h" + #include "common/array.h" #include "common/file.h" #include "common/str.h" @@ -46,10 +48,8 @@ class SliceAnimations { uint32 frameCount; uint32 frameSize; float fps; - float unk0; - float unk1; - float unk2; - float unk3; + Vector3 positionChange; + float facingChange; uint32 offset; }; @@ -102,10 +102,10 @@ class SliceAnimations { bool openCoreAnim(); bool openHDFrames(); - SlicePalette &getPalette(int i) { return _palettes[i]; }; + SlicePalette &getPalette(int i) { return _palettes[i]; } void *getFramePtr(uint32 animation, uint32 frame); - int getNumberOfFrames(int animationId); + float getFps(int animationId); }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/slice_renderer.cpp b/engines/bladerunner/slice_renderer.cpp index a52a123f54b5..389d818e6f21 100644 --- a/engines/bladerunner/slice_renderer.cpp +++ b/engines/bladerunner/slice_renderer.cpp @@ -54,6 +54,16 @@ void dump(const char *str, Matrix4x3 m) { } #endif + +SliceRenderer::SliceRenderer(BladeRunnerEngine* vm) { + _vm = vm; + int i; + + for (i = 0; i < 942; i++) { // yes, its going just to 942 and not 997 + _animationsShadowEnabled[i] = true; + } +} + SliceRenderer::~SliceRenderer() { } @@ -429,4 +439,12 @@ void SliceRenderer::preload(int animationId) { for (i = 0; i < _vm->_sliceAnimations->getNumberOfFrames(animationId); i++) _vm->_sliceAnimations->getFramePtr(animationId, i); } + +void SliceRenderer::disableShadows(int* animationsIdsList, int listSize) { + int i; + for (i = 0; i < listSize; i++) { + _animationsShadowEnabled[animationsIdsList[i]] = false; + } +} + } // End of namespace BladeRunner diff --git a/engines/bladerunner/slice_renderer.h b/engines/bladerunner/slice_renderer.h index 6e21d4f5f3e8..c702616bf713 100644 --- a/engines/bladerunner/slice_renderer.h +++ b/engines/bladerunner/slice_renderer.h @@ -80,15 +80,13 @@ class SliceRenderer { int _t5[256]; int _c6; - + bool _animationsShadowEnabled[997]; Matrix3x2 calculateFacingRotationMatrix(); void drawSlice(int slice, uint16 *frameLinePtr, uint16 *zbufLinePtr); public: - SliceRenderer(BladeRunnerEngine *vm) - : _vm(vm) - {} + SliceRenderer(BladeRunnerEngine *vm); ~SliceRenderer(); void setView(View *view); @@ -100,9 +98,9 @@ class SliceRenderer { void drawFrame(Graphics::Surface &surface, uint16 *zbuffer); - void preload(int animationId); + void disableShadows(int* animationsIdsList, int listSize); }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/vector.h b/engines/bladerunner/vector.h index 3b85da40d784..4f4bfed77856 100644 --- a/engines/bladerunner/vector.h +++ b/engines/bladerunner/vector.h @@ -56,6 +56,8 @@ class Vector3 Vector3(float ax, float ay, float az) : x(ax), y(ay), z(az) {} + + float length() { return sqrtf(x * x + y * y + z * z); } }; inline diff --git a/engines/bladerunner/waypoints.cpp b/engines/bladerunner/waypoints.cpp index d174e26cbcd3..60d342252008 100644 --- a/engines/bladerunner/waypoints.cpp +++ b/engines/bladerunner/waypoints.cpp @@ -50,6 +50,18 @@ bool Waypoints::reset(int waypointId) { _waypoints[waypointId]._present = false; return true; +} + +float Waypoints::getX(int waypointId) { + return _waypoints[waypointId]._position.x; +} +float Waypoints::getY(int waypointId) { + return _waypoints[waypointId]._position.y; } + +float Waypoints::getZ(int waypointId) { + return _waypoints[waypointId]._position.z; +} + } \ No newline at end of file diff --git a/engines/bladerunner/waypoints.h b/engines/bladerunner/waypoints.h index c74e405386f3..5ee46962204b 100644 --- a/engines/bladerunner/waypoints.h +++ b/engines/bladerunner/waypoints.h @@ -47,6 +47,9 @@ namespace BladeRunner { ~Waypoints(); void getXyz(int waypointId, float *x, float *y, float *z); + float getX(int waypointId); + float getY(int waypointId); + float getZ(int waypointId); int getSetId(int waypointId); bool set(int waypointId, int setId, Vector3 position);