diff options
155 files changed, 7210 insertions, 2182 deletions
diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp index 3f66899d5d..8462de836f 100644 --- a/engines/bladerunner/actor.cpp +++ b/engines/bladerunner/actor.cpp @@ -28,7 +28,7 @@ #include "bladerunner/actor_walk.h" #include "bladerunner/audio_speech.h" #include "bladerunner/boundingbox.h" -#include "bladerunner/gameinfo.h" +#include "bladerunner/game_info.h" #include "bladerunner/items.h" #include "bladerunner/mouse.h" #include "bladerunner/movement_track.h" @@ -345,10 +345,10 @@ void Actor::setAtXYZ(const Vector3 &position, int facing, bool snapFacing, bool setBoundingBox(_position, retired); - _vm->_sceneObjects->remove(_id + SCENE_OBJECTS_ACTORS_OFFSET); + _vm->_sceneObjects->remove(_id + kSceneObjectOffsetActors); if (_vm->_scene->getSetId() == _setId) { - _vm->_sceneObjects->addActor(_id + SCENE_OBJECTS_ACTORS_OFFSET, _bbox, &_screenRectangle, 1, moving, _isTargetable, retired); + _vm->_sceneObjects->addActor(_id + kSceneObjectOffsetActors, _bbox, &_screenRectangle, 1, moving, _isTargetable, retired); } } @@ -650,7 +650,7 @@ bool Actor::tick(bool forceDraw, Common::Rect *screenRect) { this->_position.z = this->_position.z + positionChange.x * sinx + positionChange.y * cosx; this->_position.y = this->_position.y + positionChange.z; - if (_vm->_sceneObjects->existsOnXZ(this->_id + SCENE_OBJECTS_ACTORS_OFFSET, this->_position.x, this->_position.z, false, false) == 1 && !this->_isImmuneToObstacles) { + if (_vm->_sceneObjects->existsOnXZ(this->_id + kSceneObjectOffsetActors, this->_position.x, this->_position.z, false, false) == 1 && !this->_isImmuneToObstacles) { this->_position.x = originalX; this->_position.y = originalY; this->_position.z = originalZ; @@ -691,13 +691,13 @@ bool Actor::draw(Common::Rect *screenRect) { // TODO: Handle SHORTY mode - _vm->_sliceRenderer->drawInWorld(_animationId, _animationFrame, drawPosition, drawAngle, drawScale, _vm->_surfaceGame, _vm->_zbuffer->getData()); + _vm->_sliceRenderer->drawInWorld(_animationId, _animationFrame, drawPosition, drawAngle, drawScale, _vm->_surfaceFront, _vm->_zbuffer->getData()); _vm->_sliceRenderer->getScreenRectangle(screenRect, _animationId, _animationFrame, drawPosition, drawAngle, drawScale); return !screenRect->isEmpty(); } -int Actor::getSetId() { +int Actor::getSetId() const { return _setId; } @@ -943,7 +943,7 @@ void Actor::setFlagDamageAnimIfMoving(bool value) { _damageAnimIfMoving = value; } -bool Actor::getFlagDamageAnimIfMoving() { +bool Actor::getFlagDamageAnimIfMoving() const { return _damageAnimIfMoving; } @@ -1009,29 +1009,29 @@ float Actor::distanceFromActor(int otherActorId) { return (_position - _vm->_actors[otherActorId]->_position).length(); } -float Actor::getX() { +float Actor::getX() const { return _position.x; } -float Actor::getY() { +float Actor::getY() const { return _position.y; } -float Actor::getZ() { +float Actor::getZ() const { return _position.z; } -void Actor::getXYZ(float *x, float *y, float *z) { +void Actor::getXYZ(float *x, float *y, float *z) const { *x = _position.x; *y = _position.y; *z = _position.z; } -int Actor::getFacing() { +int Actor::getFacing() const { return _facing; } -int Actor::getAnimationMode() { +int Actor::getAnimationMode() const { return _animationMode; } @@ -1046,7 +1046,7 @@ void Actor::setGoal(int goalNumber) { _vm->_sceneScript->ActorChangedGoal(_id, goalNumber, oldGoalNumber, _vm->_scene->getSetId() == _setId); } -int Actor::getGoal() { +int Actor::getGoal() const { return _goalNumber; } @@ -1055,7 +1055,7 @@ void Actor::speechPlay(int sentenceId, bool voiceOver) { sprintf(name, "%02d-%04d%s.AUD", _id, sentenceId, _vm->_languageCode); int balance; - if (voiceOver || _id == VOICEOVER_ACTOR) { + if (voiceOver || _id == BladeRunnerEngine::kActorVoiceOver) { balance = 0; } else { // Vector3 pos = _vm->_view->_frameViewMatrix * _position; @@ -1092,16 +1092,16 @@ void Actor::loseClue(int clueId) { _clues->lose(clueId); } -bool Actor::hasClue(int clueId) { +bool Actor::hasClue(int clueId) const { return _clues->isAcquired(clueId); } void Actor::copyClues(int actorId) { Actor *otherActor = _vm->_actors[actorId]; for (int i = 0; i < (int)_vm->_gameInfo->getClueCount(); i++) { - if (hasClue(i) && !_clues->isFlag4(i) && !otherActor->hasClue(i)) { + if (hasClue(i) && !_clues->isPrivate(i) && !otherActor->hasClue(i)) { int fromActorId = _id; - if (_id == VOICEOVER_ACTOR) { + if (_id == BladeRunnerEngine::kActorVoiceOver) { fromActorId = _clues->getFromActorId(i); } otherActor->acquireClue(i, false, fromActorId); diff --git a/engines/bladerunner/actor.h b/engines/bladerunner/actor.h index 8c426bde68..5068143776 100644 --- a/engines/bladerunner/actor.h +++ b/engines/bladerunner/actor.h @@ -39,6 +39,7 @@ class View; class Actor { friend class ScriptBase; + friend class KIA; BladeRunnerEngine *_vm; @@ -80,9 +81,9 @@ private: // Movement bool _movementTrackPaused; - int _movementTrackNextWaypointId; - int _movementTrackNextDelay; // probably not used - int _movementTrackNextAngle; // probably not used + int _movementTrackNextWaypointId; + int _movementTrackNextDelay; // probably not used + int _movementTrackNextAngle; // probably not used bool _movementTrackNextRunning; int _movementTrackWalkingToWaypointId; @@ -119,14 +120,14 @@ public: void setAtXYZ(const Vector3 &pos, int facing, bool setFacing = true, bool moving = false, bool retired = false); void setAtWaypoint(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(); + float getX() const; + float getY() const; + float getZ() const; + void getXYZ(float *x, float *y, float *z) const; + int getFacing() const; + int getAnimationMode() const; - Vector3 getPosition() { return _position; } + Vector3 getPosition() const { return _position; } void changeAnimationMode(int animationMode, bool force = false); void setFPS(int fps); @@ -153,12 +154,12 @@ public: bool tick(bool forceUpdate, Common::Rect *screenRect); bool draw(Common::Rect *screenRect); - int getSetId(); + int getSetId() const; void setSetId(int setId); BoundingBox *getBoundingBox() const { return _bbox; } Common::Rect *getScreenRectangle() { return &_screenRectangle; } int getWalkbox() const { return _walkboxId; } - bool isRetired()const { return _isRetired; } + bool isRetired() const { return _isRetired; } bool isTargetable() const { return _isTargetable; } void setTargetable(bool targetable); bool isImmuneToObstacles() const { return _isImmuneToObstacles; } @@ -192,7 +193,7 @@ public: void modifyIntelligence(signed int change); void modifyStability(signed int change); void setFlagDamageAnimIfMoving(bool value); - bool getFlagDamageAnimIfMoving(); + bool getFlagDamageAnimIfMoving() const; void setHealth(int hp, int maxHp); void retire(bool isRetired, int width, int height, int retiredByActorId); @@ -201,7 +202,7 @@ public: void combatModeOff(); void setGoal(int goalNumber); - int getGoal(); + int getGoal() const; float distanceFromActor(int otherActorId); @@ -212,15 +213,16 @@ public: void addClueToDatabase(int clueId, int unknown, bool clueAcquired, bool unknownFlag, int fromActorId); void acquireClue(int clueId, bool unknownFlag, int fromActorId); void loseClue(int clueId); - bool hasClue(int clueId); + bool hasClue(int clueId) const; void copyClues(int actorId); int soundVolume() const; int soundBalance() const; + private: void setFacing(int facing, bool halfOrSet = true); void setBoundingBox(const Vector3 &position, bool retired); - float distanceFromView(View* view) const; + float distanceFromView(View *view) const; bool loopWalk(const Vector3 &destination, int destinationOffset, bool a3, bool run, const Vector3 &start, float a6, float a7, bool a8, bool *isRunning, bool async); bool walkTo(bool run, const Vector3 &destination, bool a3); diff --git a/engines/bladerunner/actor_clues.cpp b/engines/bladerunner/actor_clues.cpp index cd848f9fbf..fe4291d558 100644 --- a/engines/bladerunner/actor_clues.cpp +++ b/engines/bladerunner/actor_clues.cpp @@ -23,7 +23,7 @@ #include "bladerunner/actor_clues.h" #include "bladerunner/bladerunner.h" -#include "bladerunner/gameinfo.h" +#include "bladerunner/game_info.h" #include "bladerunner/crimes_database.h" #include "common/debug.h" @@ -34,7 +34,6 @@ ActorClues::ActorClues(BladeRunnerEngine *vm, int cluesType) { _vm = vm; _count = 0; _maxCount = 0; - _clues = 0; switch (cluesType) { case 4: _maxCount = _vm->_gameInfo->getClueCount(); @@ -56,84 +55,97 @@ ActorClues::ActorClues(BladeRunnerEngine *vm, int cluesType) { } if (_maxCount > 0) { - _clues = new ActorClue[_maxCount]; - } else { - _clues = nullptr; + _clues.resize(_maxCount); } - if (_clues) { - removeAll(); - } else { - _maxCount = 0; - } -} - -ActorClues::~ActorClues() { - delete[] _clues; - - _maxCount = 0; - _count = 0; + removeAll(); } void ActorClues::acquire(int clueId, bool flag2, int fromActorId) { int clueIndex = findClueIndex(clueId); - _clues[clueIndex]._flags |= 0x01; - _clues[clueIndex]._flags = (_clues[clueIndex]._flags & ~0x02) | ((flag2 << 1) & 0x02); - _clues[clueIndex]._fromActorId = fromActorId; + _clues[clueIndex].flags |= 0x01; + _clues[clueIndex].flags = (_clues[clueIndex].flags & ~0x02) | ((flag2 << 1) & 0x02); + _clues[clueIndex].fromActorId = fromActorId; debug("Actor acquired clue: \"%s\" from %d", _vm->_crimesDatabase->getClueText(clueId), fromActorId); } void ActorClues::lose(int clueId) { int clueIndex = findClueIndex(clueId); - _clues[clueIndex]._flags = 0; + _clues[clueIndex].flags = 0; } -bool ActorClues::isAcquired(int clueId) { +bool ActorClues::isAcquired(int clueId) const { int clueIndex = findClueIndex(clueId); if (clueIndex == -1) { return false; } - return _clues[clueIndex]._flags & 0x01; + return _clues[clueIndex].flags & 0x01; } -int ActorClues::getFromActorId(int clueId) { +int ActorClues::getFromActorId(int clueId) const { int clueIndex = findClueIndex(clueId); if (clueIndex == -1) { return -1; } - return _clues[clueIndex]._fromActorId; + return _clues[clueIndex].fromActorId; } -bool ActorClues::isFlag2(int clueId) { +bool ActorClues::isFlag2(int clueId) const { int clueIndex = findClueIndex(clueId); if (clueIndex == -1) { return false; } - return (_clues[clueIndex]._flags & 0x02) >> 1; + return _clues[clueIndex].flags & 0x02; } -bool ActorClues::isViewed(int clueId) { +bool ActorClues::isViewed(int clueId) const { int clueIndex = findClueIndex(clueId); if (clueIndex == -1) { return false; } - return (_clues[clueIndex]._flags & 0x04) >> 2; + return _clues[clueIndex].flags & 0x04; +} + +void ActorClues::setViewed(int clueId, bool viewed) { + int clueIndex = findClueIndex(clueId); + if (clueIndex == -1) { + return; + } + + if (viewed) { + _clues[clueIndex].flags |= 0x04; + } else { + _clues[clueIndex].flags &= ~0x04; + } } -bool ActorClues::isFlag4(int clueId) { +bool ActorClues::isPrivate(int clueId) const { int clueIndex = findClueIndex(clueId); if (clueIndex == -1) { return false; } - return (_clues[clueIndex]._flags & 0x08) >> 3; + return _clues[clueIndex].flags & 0x08; +} + +void ActorClues::setPrivate(int clueId, bool isPrivate) { + int clueIndex = findClueIndex(clueId); + if (clueIndex == -1) { + return; + } + + if (isPrivate) { + _clues[clueIndex].flags |= 0x08; + } else { + _clues[clueIndex].flags &= ~0x08; + } } -int ActorClues::getField1(int clueId) { +int ActorClues::getField1(int clueId) const { if (!_count) { return 0; } @@ -143,10 +155,10 @@ int ActorClues::getField1(int clueId) { return 0; } - return _clues[clueIndex]._weight; + return _clues[clueIndex].weight; } -int ActorClues::getCount() { +int ActorClues::getCount() const { return _count; } @@ -157,9 +169,9 @@ void ActorClues::removeAll() { } } -int ActorClues::findClueIndex(int clueId) { +int ActorClues::findClueIndex(int clueId) const { for (int i = 0; i < _count; i++) { - if (clueId == _clues[i]._clueId) { + if (clueId == _clues[i].clueId) { return i; } } @@ -171,35 +183,36 @@ void ActorClues::add(int actorId, int clueId, int weight, bool acquired, bool un //debug("Actor %d added clue: \"%s\" from %d", actorId, _vm->_crimesDatabase->getClueText(clueId), fromActorId); - _clues[_count]._clueId = clueId; - _clues[_count]._weight = weight; + _clues[_count].clueId = clueId; + _clues[_count].weight = weight; - _clues[_count]._flags = 0; - _clues[_count]._flags = (_clues[_count]._flags & ~0x01) | (acquired & 0x01); - _clues[_count]._flags = (_clues[_count]._flags & ~0x02) | ((unknownFlag << 1) & 0x02); + _clues[_count].flags = 0; + _clues[_count].flags = (_clues[_count].flags & ~0x01) | (acquired & 0x01); + _clues[_count].flags = (_clues[_count].flags & ~0x02) | ((unknownFlag << 1) & 0x02); - _clues[_count]._fromActorId = fromActorId; + _clues[_count].fromActorId = fromActorId; ++_count; } void ActorClues::remove(int index) { - if (_vm->_crimesDatabase) - debug("Actor removed clue: \"%s\"", _vm->_crimesDatabase->getClueText(_clues[index]._clueId)); + if (_vm->_crimesDatabase) { + debug("Actor removed clue: \"%s\"", _vm->_crimesDatabase->getClueText(_clues[index].clueId)); + } - _clues[index]._clueId = -1; - _clues[index]._weight = 0; - _clues[index]._flags = 0; - _clues[index]._fromActorId = -1; + _clues[index].clueId = -1; + _clues[index].weight = 0; + _clues[index].flags = 0; + _clues[index].fromActorId = -1; - _clues[index]._field3 = -1; - _clues[index]._field4 = 0; - _clues[index]._field5 = -1; - _clues[index]._field6 = 0; - _clues[index]._field7 = -1; - _clues[index]._field8 = 0; + _clues[index].field3 = -1; + _clues[index].field4 = 0; + _clues[index].field5 = -1; + _clues[index].field6 = 0; + _clues[index].field7 = -1; + _clues[index].field8 = 0; } -bool ActorClues::exists(int clueId) { +bool ActorClues::exists(int clueId) const { return findClueIndex(clueId) != -1; } diff --git a/engines/bladerunner/actor_clues.h b/engines/bladerunner/actor_clues.h index d053ef532b..498986a77a 100644 --- a/engines/bladerunner/actor_clues.h +++ b/engines/bladerunner/actor_clues.h @@ -23,46 +23,54 @@ #ifndef BLADERUNNER_ACTOR_CLUES_H #define BLADERUNNER_ACTOR_CLUES_H +#include "common/array.h" + namespace BladeRunner { class BladeRunnerEngine; -struct ActorClue { - int _clueId; - int _weight; - int _fromActorId; - int _field3; - int _field4; - int _field5; - int _field6; - int _field7; - int _field8; - unsigned char _flags; -}; - class ActorClues { + struct Clue { + int clueId; + int weight; + int fromActorId; + int field3; + int field4; + int field5; + int field6; + int field7; + int field8; + unsigned char flags; + }; + BladeRunnerEngine *_vm; -private: - int _count; - int _maxCount; - ActorClue *_clues; + int _count; + int _maxCount; + Common::Array<Clue> _clues; public: ActorClues(BladeRunnerEngine *_vm, int cluesType); - ~ActorClues(); void add(int actorId, int clueId, int unknown, bool acquired, bool unknownFlag, int fromActorId); + void acquire(int clueId, bool flag2, int fromActorId); void lose(int clueId); - bool isAcquired(int clueId); - int getFromActorId(int clueId); - bool isFlag2(int clueId); - bool isViewed(int clueId); - bool isFlag4(int clueId); - int getField1(int clueId); + bool isAcquired(int clueId) const; + + int getFromActorId(int clueId) const; + + bool isFlag2(int clueId) const; + + bool isViewed(int clueId) const; + void setViewed(int clueId, bool viewed); + + bool isPrivate(int clueId) const; + void setPrivate(int clueId, bool isPrivate); + + int getField1(int clueId) const; - int getCount(); + int getCount() const; void removeAll(); @@ -70,8 +78,8 @@ public: //loadgame private: - bool exists(int clueId); - int findClueIndex(int clueId); + bool exists(int clueId) const; + int findClueIndex(int clueId) const; void remove(int clueIndex); }; diff --git a/engines/bladerunner/actor_combat.h b/engines/bladerunner/actor_combat.h index 3763f46be8..b7ec93533d 100644 --- a/engines/bladerunner/actor_combat.h +++ b/engines/bladerunner/actor_combat.h @@ -32,7 +32,6 @@ class BladeRunnerEngine; class ActorCombat { BladeRunnerEngine *_vm; -private: // int _actorId; // int _combatOn; // int _field2; diff --git a/engines/bladerunner/adq.cpp b/engines/bladerunner/actor_dialogue_queue.cpp index 71315e8492..1dc7acc859 100644 --- a/engines/bladerunner/adq.cpp +++ b/engines/bladerunner/actor_dialogue_queue.cpp @@ -20,7 +20,7 @@ * */ -#include "bladerunner/adq.h" +#include "bladerunner/actor_dialogue_queue.h" #include "bladerunner/bladerunner.h" @@ -32,55 +32,55 @@ namespace BladeRunner { -ADQEntry::ADQEntry() { - this->_isNotPause = false; - this->_isPause = false; - this->_actorId = -1; - this->_delay = -1; - this->_sentenceId = -1; - this->_animationMode = -1; +ActorDialogueQueue::Entry::Entry() { + isNotPause = false; + isPause = false; + actorId = -1; + delay = -1; + sentenceId = -1; + animationMode = -1; } -ADQ::ADQ(BladeRunnerEngine *vm) { +ActorDialogueQueue::ActorDialogueQueue(BladeRunnerEngine *vm) { _vm = vm; clear(); } -ADQ::~ADQ() { +ActorDialogueQueue::~ActorDialogueQueue() { } -void ADQ::add(int actorId, int sentenceId, int animationMode) { - if (actorId == 0 || actorId == VOICEOVER_ACTOR) { +void ActorDialogueQueue::add(int actorId, int sentenceId, int animationMode) { + if (actorId == 0 || actorId == BladeRunnerEngine::kActorVoiceOver) { animationMode = -1; } if (_entries.size() < 25) { - ADQEntry entry; - entry._isNotPause = true; - entry._isPause = false; - entry._actorId = actorId; - entry._sentenceId = sentenceId; - entry._animationMode = animationMode; - entry._delay = -1; + Entry entry; + entry.isNotPause = true; + entry.isPause = false; + entry.actorId = actorId; + entry.sentenceId = sentenceId; + entry.animationMode = animationMode; + entry.delay = -1; _entries.push_back(entry); } } -void ADQ::addPause(int delay) { +void ActorDialogueQueue::addPause(int delay) { if (_entries.size() < 25) { - ADQEntry entry; - entry._isNotPause = false; - entry._isPause = true; - entry._actorId = -1; - entry._sentenceId = -1; - entry._animationMode = -1; - entry._delay = delay; + Entry entry; + entry.isNotPause = false; + entry.isPause = true; + entry.actorId = -1; + entry.sentenceId = -1; + entry.animationMode = -1; + entry.delay = delay; _entries.push_back(entry); } } -void ADQ::flush(int a1, bool callScript) { +void ActorDialogueQueue::flush(int a1, bool callScript) { if (_isNotPause && _vm->_audioSpeech->isPlaying()) { _vm->_audioSpeech->stopSpeech(); if (_animationModePrevious >= 0) { @@ -103,7 +103,7 @@ void ADQ::flush(int a1, bool callScript) { } } -void ADQ::tick() { +void ActorDialogueQueue::tick() { if (!_vm->_audioSpeech->isPlaying()) { if (_isPause) { int time = _vm->getTotalPlayTime(); @@ -134,32 +134,32 @@ void ADQ::tick() { } } if (!_entries.empty()) { - ADQEntry firstEntry = _entries.remove_at(0); - if (firstEntry._isNotPause) { - _animationMode = firstEntry._animationMode; - if (_vm->_actors[firstEntry._actorId]->getSetId() != _vm->_scene->getSetId()) { + Entry firstEntry = _entries.remove_at(0); + if (firstEntry.isNotPause) { + _animationMode = firstEntry.animationMode; + if (_vm->_actors[firstEntry.actorId]->getSetId() != _vm->_scene->getSetId()) { _animationMode = -1; } - _vm->_actors[firstEntry._actorId]->speechPlay(firstEntry._sentenceId, false); + _vm->_actors[firstEntry.actorId]->speechPlay(firstEntry.sentenceId, false); _isNotPause = true; - _actorId = firstEntry._actorId; - _sentenceId = firstEntry._sentenceId; + _actorId = firstEntry.actorId; + _sentenceId = firstEntry.sentenceId; if (_animationMode >= 0) { - _animationModePrevious = _vm->_actors[firstEntry._actorId]->getAnimationMode(); - _vm->_actors[firstEntry._actorId]->changeAnimationMode(_animationMode, false); + _animationModePrevious = _vm->_actors[firstEntry.actorId]->getAnimationMode(); + _vm->_actors[firstEntry.actorId]->changeAnimationMode(_animationMode, false); } else { _animationModePrevious = -1; } - } else if (firstEntry._isPause) { + } else if (firstEntry.isPause) { _isPause = true; - _delay = firstEntry._delay; + _delay = firstEntry.delay; _timeLast = _vm->getTotalPlayTime(); } } } } -void ADQ::clear() { +void ActorDialogueQueue::clear() { _entries.clear(); _isNotPause = false; _actorId = -1; diff --git a/engines/bladerunner/adq.h b/engines/bladerunner/actor_dialogue_queue.h index f4e69df684..0a700217b9 100644 --- a/engines/bladerunner/adq.h +++ b/engines/bladerunner/actor_dialogue_queue.h @@ -20,44 +20,41 @@ * */ -#ifndef BLADERUNNER_ADQ_H -#define BLADERUNNER_ADQ_H +#ifndef BLADERUNNER_ACTOR_DIALOGUE_QUEUE_H +#define BLADERUNNER_ACTOR_DIALOGUE_QUEUE_H #include "common/array.h" namespace BladeRunner { class BladeRunnerEngine; -struct ADQEntry { - bool _isNotPause; - bool _isPause; - int _actorId; - int _sentenceId; - int _animationMode; - int _delay; +class ActorDialogueQueue { + struct Entry { + bool isNotPause; + bool isPause; + int actorId; + int sentenceId; + int animationMode; + int delay; - ADQEntry(); -}; + Entry(); + }; -// actor dialogue queue?? -class ADQ { BladeRunnerEngine *_vm; - Common::Array<ADQEntry> _entries; - - bool _isNotPause; - int _actorId; - int _sentenceId; - int _animationMode; - int _animationModePrevious; - bool _isPause; - int _delay; - int _timeLast; - + Common::Array<Entry> _entries; + bool _isNotPause; + int _actorId; + int _sentenceId; + int _animationMode; + int _animationModePrevious; + bool _isPause; + int _delay; + int _timeLast; public: - ADQ(BladeRunnerEngine *vm); - ~ADQ(); + ActorDialogueQueue(BladeRunnerEngine *vm); + ~ActorDialogueQueue(); void add(int actorId, int speechId, int animationMode); void addPause(int delay); diff --git a/engines/bladerunner/actor_walk.cpp b/engines/bladerunner/actor_walk.cpp index ddf8b4c61b..70624221f5 100644 --- a/engines/bladerunner/actor_walk.cpp +++ b/engines/bladerunner/actor_walk.cpp @@ -25,7 +25,7 @@ #include "bladerunner/bladerunner.h" #include "bladerunner/actor.h" -#include "bladerunner/gameinfo.h" +#include "bladerunner/game_info.h" #include "bladerunner/obstacles.h" #include "bladerunner/scene.h" #include "bladerunner/scene_objects.h" @@ -71,7 +71,7 @@ bool ActorWalk::setup(int actorId, bool run, const Vector3 &from, const Vector3 } _nearActors.clear(); - _vm->_sceneObjects->setMoving(actorId + SCENE_OBJECTS_ACTORS_OFFSET, true); + _vm->_sceneObjects->setMoving(actorId + kSceneObjectOffsetActors, true); _vm->_actors[actorId]->setMoving(true); if (_running) { @@ -124,7 +124,7 @@ bool ActorWalk::tick(int actorId, float stepDistance, bool inWalkLoop) { bool nearActorExists = addNearActors(actorId); if (_nearActors.size() > 0) { nearActorExists = true; - if (_vm->_sceneObjects->existsOnXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, _destination.x, _destination.z, true, true)) { + if (_vm->_sceneObjects->existsOnXZ(actorId + kSceneObjectOffsetActors, _destination.x, _destination.z, true, true)) { if (actorId > 0) { if (_vm->_actors[actorId]->inWalkLoop()) { stop(actorId, true, kAnimationModeCombatIdle, kAnimationModeIdle); @@ -207,7 +207,7 @@ void ActorWalk::getCurrentPosition(int actorId, Vector3 *pos, int *facing) const } void ActorWalk::stop(int actorId, bool immediately, int combatAnimationMode, int animationMode) { - _vm->_sceneObjects->setMoving(actorId + SCENE_OBJECTS_ACTORS_OFFSET, false); + _vm->_sceneObjects->setMoving(actorId + kSceneObjectOffsetActors, false); _vm->_actors[actorId]->setMoving(false); if (_vm->_actors[actorId]->inCombat()) { @@ -234,7 +234,7 @@ bool ActorWalk::isXYZEmpty(float x, float y, float z, int actorId) const { if (_vm->_actors[actorId]->isImmuneToObstacles()) { return false; } - return _vm->_sceneObjects->existsOnXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x, z, false, false); + return _vm->_sceneObjects->existsOnXZ(actorId + kSceneObjectOffsetActors, x, z, false, false); } bool ActorWalk::findNearestEmptyPosition(int actorId, const Vector3 &destination, int dist, Vector3 &out) const { @@ -267,14 +267,14 @@ bool ActorWalk::findNearestEmptyPosition(int actorId, const Vector3 &destination x = destination.x + sin_1024(facingRight) * dist; z = destination.z - cos_1024(facingRight) * dist; - if (!_vm->_sceneObjects->existsOnXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x, z, true, true) && _vm->_scene->_set->findWalkbox(x, z) >= 0) { + if (!_vm->_sceneObjects->existsOnXZ(actorId + kSceneObjectOffsetActors, x, z, true, true) && _vm->_scene->_set->findWalkbox(x, z) >= 0) { break; } x = destination.x + sin_1024(facingLeft) * dist; z = destination.z - cos_1024(facingLeft) * dist; - if (!_vm->_sceneObjects->existsOnXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x, z, true, true) && _vm->_scene->_set->findWalkbox(x, z) >= 0) { + if (!_vm->_sceneObjects->existsOnXZ(actorId + kSceneObjectOffsetActors, x, z, true, true) && _vm->_scene->_set->findWalkbox(x, z) >= 0) { break; } @@ -361,7 +361,7 @@ int ActorWalk::nextOnPath(int actorId, const Vector3 &from, const Vector3 &to, V if (_vm->_scene->_set->findWalkbox(to.x, to.z) == -1) { return 0; } - if (_vm->_sceneObjects->existsOnXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, to.x, to.z, false, false)) { + if (_vm->_sceneObjects->existsOnXZ(actorId + kSceneObjectOffsetActors, to.x, to.z, false, false)) { return 0; } Vector3 next1; diff --git a/engines/bladerunner/actor_walk.h b/engines/bladerunner/actor_walk.h index c6f2ed7478..07e383ac25 100644 --- a/engines/bladerunner/actor_walk.h +++ b/engines/bladerunner/actor_walk.h @@ -33,21 +33,20 @@ class BladeRunnerEngine; class ActorWalk { BladeRunnerEngine *_vm; -private: - int _walking; - int _running; - Vector3 _destination; - Vector3 _originalDestination; - Vector3 _current; - Vector3 _next; - int _facing; + int _walking; + int _running; + Vector3 _destination; + Vector3 _originalDestination; + Vector3 _current; + Vector3 _next; + int _facing; Common::HashMap<int, bool> _nearActors; - int _status; + int _status; public: ActorWalk(BladeRunnerEngine *vm); ~ActorWalk(); - + bool setup(int actorId, bool run, const Vector3 &from, const Vector3 &to, bool unk1, bool *arrived); void getCurrentPosition(int actorId, Vector3 *pos, int *facing) const; bool tick(int actorId, float stepDistance, bool flag); diff --git a/engines/bladerunner/ambient_sounds.cpp b/engines/bladerunner/ambient_sounds.cpp index a8a42537d1..31683f01c1 100644 --- a/engines/bladerunner/ambient_sounds.cpp +++ b/engines/bladerunner/ambient_sounds.cpp @@ -24,27 +24,25 @@ #include "bladerunner/audio_player.h" #include "bladerunner/bladerunner.h" -#include "bladerunner/gameinfo.h" +#include "bladerunner/game_info.h" #include "common/debug.h" #include "common/system.h" namespace BladeRunner { -#define NON_LOOPING_SOUNDS 25 -#define LOOPING_SOUNDS 3 - -AmbientSounds::AmbientSounds(BladeRunnerEngine *vm) : _vm(vm) { - _nonLoopingSounds = new NonLoopingSound[NON_LOOPING_SOUNDS]; - _loopingSounds = new LoopingSound[LOOPING_SOUNDS]; +AmbientSounds::AmbientSounds(BladeRunnerEngine *vm) { + _vm = vm; + _nonLoopingSounds = new NonLoopingSound[kNonLoopingSounds]; + _loopingSounds = new LoopingSound[kLoopingSounds]; _ambientVolume = 65; - for (int i = 0; i != NON_LOOPING_SOUNDS; ++i) { + for (int i = 0; i != kNonLoopingSounds; ++i) { NonLoopingSound &track = _nonLoopingSounds[i]; track.isActive = false; } - for (int i = 0; i != LOOPING_SOUNDS; ++i) { + for (int i = 0; i != kLoopingSounds; ++i) { LoopingSound &track = _loopingSounds[i]; track.isActive = false; } @@ -96,7 +94,7 @@ void AmbientSounds::removeNonLoopingSound(int sfxId, bool stopPlaying) { } void AmbientSounds::removeAllNonLoopingSounds(bool stopPlaying) { - for (int i = 0; i < NON_LOOPING_SOUNDS; i++) { + for (int i = 0; i < kNonLoopingSounds; i++) { removeNonLoopingSoundByIndex(i, stopPlaying); } } @@ -188,7 +186,7 @@ void AmbientSounds::removeLoopingSound(int sfxId, int delay) { } void AmbientSounds::removeAllLoopingSounds(int delay) { - for (int i = 0; i < LOOPING_SOUNDS; i++) { + for (int i = 0; i < kLoopingSounds; i++) { removeLoopingSoundByIndex(i, delay); } } @@ -196,7 +194,7 @@ void AmbientSounds::removeAllLoopingSounds(int delay) { void AmbientSounds::tick() { uint32 now = g_system->getMillis(); - for (int i = 0; i != NON_LOOPING_SOUNDS; ++i) { + for (int i = 0; i != kNonLoopingSounds; ++i) { NonLoopingSound &track = _nonLoopingSounds[i]; if (!track.isActive || track.nextPlayTime > now) { @@ -226,8 +224,37 @@ void AmbientSounds::tick() { } } -int AmbientSounds::findAvailableNonLoopingTrack() { - for (int i = 0; i != NON_LOOPING_SOUNDS; ++i) { +void AmbientSounds::setVolume(int volume) { + if (_loopingSounds) { + for (int i = 0; i < kLoopingSounds; i++) { + if (_loopingSounds[i].isActive && _loopingSounds[i].audioPlayerTrack != -1) { + int newVolume = _loopingSounds[i].volume * volume / 100; + if (_vm->_audioPlayer->isActive(_loopingSounds[i].audioPlayerTrack)) { + _vm->_audioPlayer->adjustVolume(_loopingSounds[i].audioPlayerTrack, newVolume, 1, false); + } else { + _loopingSounds[i].audioPlayerTrack = _vm->_audioPlayer->playAud(_loopingSounds[i].name, 1, _loopingSounds[i].pan, _loopingSounds[i].pan, 99, AudioPlayer::LOOP | AudioPlayer::OVERRIDE_VOLUME); + if (_loopingSounds[i].audioPlayerTrack == -1) { + removeLoopingSound(i, 0); + } else { + _vm->_audioPlayer->adjustVolume(_loopingSounds[i].audioPlayerTrack, newVolume, 1, false); + } + } + } + } + } + _ambientVolume = volume; +} + +int AmbientSounds::getVolume() const { + return _ambientVolume; +} + +void AmbientSounds::playSample() { + playSound(66, 100, 0, 0, 0); +} + +int AmbientSounds::findAvailableNonLoopingTrack() const { + for (int i = 0; i != kNonLoopingSounds; ++i) { if (!_nonLoopingSounds[i].isActive) { return i; } @@ -236,8 +263,8 @@ int AmbientSounds::findAvailableNonLoopingTrack() { return -1; } -int AmbientSounds::findNonLoopingTrackByHash(int32 hash) { - for (int i = 0; i != NON_LOOPING_SOUNDS; ++i) { +int AmbientSounds::findNonLoopingTrackByHash(int32 hash) const { + for (int i = 0; i != kNonLoopingSounds; ++i) { NonLoopingSound &track = _nonLoopingSounds[i]; if (track.isActive && track.hash == hash) { @@ -248,8 +275,8 @@ int AmbientSounds::findNonLoopingTrackByHash(int32 hash) { return -1; } -int AmbientSounds::findAvailableLoopingTrack() { - for (int i = 0; i != LOOPING_SOUNDS; ++i) { +int AmbientSounds::findAvailableLoopingTrack() const { + for (int i = 0; i != kLoopingSounds; ++i) { if (!_loopingSounds[i].isActive) { return i; } @@ -258,8 +285,8 @@ int AmbientSounds::findAvailableLoopingTrack() { return -1; } -int AmbientSounds::findLoopingTrackByHash(int32 hash) { - for (int i = 0; i != LOOPING_SOUNDS; ++i) { +int AmbientSounds::findLoopingTrackByHash(int32 hash) const { + for (int i = 0; i != kLoopingSounds; ++i) { LoopingSound &track = _loopingSounds[i]; if (track.isActive && track.hash == hash) { diff --git a/engines/bladerunner/ambient_sounds.h b/engines/bladerunner/ambient_sounds.h index 292d8173f2..e06726b183 100644 --- a/engines/bladerunner/ambient_sounds.h +++ b/engines/bladerunner/ambient_sounds.h @@ -30,6 +30,9 @@ namespace BladeRunner { class BladeRunnerEngine; class AmbientSounds { + static const int kNonLoopingSounds = 25; + static const int kLoopingSounds = 3; + struct NonLoopingSound { bool isActive; char name[13]; @@ -96,15 +99,16 @@ public: void tick(); - // setVolume - // getVolume + void setVolume(int volume); + int getVolume() const; + void playSample(); private: - int findAvailableNonLoopingTrack(); - int findNonLoopingTrackByHash(int32 hash); + int findAvailableNonLoopingTrack() const; + int findNonLoopingTrackByHash(int32 hash) const; - int findAvailableLoopingTrack(); - int findLoopingTrackByHash(int32 hash); + int findAvailableLoopingTrack() const; + int findLoopingTrackByHash(int32 hash) const; // stopNonLoopingTrack // stopLoopingTrack diff --git a/engines/bladerunner/archive.h b/engines/bladerunner/archive.h index 03eda4ea7f..f2809deeac 100644 --- a/engines/bladerunner/archive.h +++ b/engines/bladerunner/archive.h @@ -38,7 +38,7 @@ public: void close(); bool isOpen() const; - Common::String getName() { return _fd.getName(); } + Common::String getName() const { return _fd.getName(); } Common::SeekableReadStream *createReadStreamForMember(const Common::String &name); diff --git a/engines/bladerunner/aud_stream.cpp b/engines/bladerunner/aud_stream.cpp index 6e7152a848..f0ed05200b 100644 --- a/engines/bladerunner/aud_stream.cpp +++ b/engines/bladerunner/aud_stream.cpp @@ -118,7 +118,7 @@ bool AudStream::rewind() { return true; } -int AudStream::getLength() { +int AudStream::getLength() const { int bytesPerSecond = _frequency; if (_flags & 1) { // 16 bit bytesPerSecond *= 2; diff --git a/engines/bladerunner/aud_stream.h b/engines/bladerunner/aud_stream.h index f3117d7072..a13cdde84f 100644 --- a/engines/bladerunner/aud_stream.h +++ b/engines/bladerunner/aud_stream.h @@ -60,7 +60,7 @@ public: int getRate() const { return _frequency; }; bool endOfData() const { return _p == _end; } bool rewind(); - int getLength(); + int getLength() const; }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/audio_mixer.cpp b/engines/bladerunner/audio_mixer.cpp index d9d04e65d9..35e53e570d 100644 --- a/engines/bladerunner/audio_mixer.cpp +++ b/engines/bladerunner/audio_mixer.cpp @@ -47,7 +47,7 @@ AudioMixer::~AudioMixer() { _vm->getTimerManager()->removeTimerProc(timerCallback); } -int AudioMixer::play(Audio::Mixer::SoundType type, Audio::RewindableAudioStream *stream, int priority, bool loop, int volume, int pan, void (*endCallback)(int, void*), void *callbackData) { +int AudioMixer::play(Audio::Mixer::SoundType type, Audio::RewindableAudioStream *stream, int priority, bool loop, int volume, int pan, void (*endCallback)(int, void *), void *callbackData) { Common::StackLock lock(_mutex); int channel = -1; @@ -110,7 +110,7 @@ int AudioMixer::playInChannel(int channel, Audio::Mixer::SoundType type, Audio:: _channels[channel].endCallback = endCallback; _channels[channel].callbackData = callbackData; - Audio::AudioStream* audioStream = stream; + Audio::AudioStream *audioStream = stream; if (loop) { audioStream = new Audio::LoopingAudioStream(stream, 0, DisposeAfterUse::YES); @@ -127,14 +127,14 @@ int AudioMixer::playInChannel(int channel, Audio::Mixer::SoundType type, Audio:: return channel; } -bool AudioMixer::isActive(int channel) { +bool AudioMixer::isActive(int channel) const { Common::StackLock lock(_mutex); return _channels[channel].isPresent && _vm->_mixer->isSoundHandleActive(_channels[channel].handle); } void AudioMixer::timerCallback(void *self) { - ((AudioMixer*)self)->tick(); + ((AudioMixer *)self)->tick(); } void AudioMixer::adjustVolume(int channel, int newVolume, int time) diff --git a/engines/bladerunner/audio_mixer.h b/engines/bladerunner/audio_mixer.h index a221e681ec..ca4b4807d5 100644 --- a/engines/bladerunner/audio_mixer.h +++ b/engines/bladerunner/audio_mixer.h @@ -39,19 +39,19 @@ class AudioMixer { static const int kUpdatesPerSecond = 40; struct Channel { - bool isPresent; - int priority; - bool loop; + bool isPresent; + int priority; + bool loop; Audio::SoundHandle handle; Audio::AudioStream *stream; - float volume; - float volumeDelta; - float volumeTarget; - float pan; - float panDelta; - float panTarget; - void (*endCallback)(int channel, void *data); - void *callbackData; + float volume; + float volumeDelta; + float volumeTarget; + float pan; + float panDelta; + float panTarget; + void (*endCallback)(int channel, void *data); + void *callbackData; }; BladeRunnerEngine *_vm; @@ -76,7 +76,7 @@ public: private: int playInChannel(int channel, Audio::Mixer::SoundType type, Audio::RewindableAudioStream *stream, int priority, bool loop, int volume, int pan, void(*endCallback)(int, void *), void *callbackData); - bool isActive(int channel); + bool isActive(int channel) const; void tick(); static void timerCallback(void *refCon); }; diff --git a/engines/bladerunner/audio_player.cpp b/engines/bladerunner/audio_player.cpp index 1e459e9b86..7aeba9c188 100644 --- a/engines/bladerunner/audio_player.cpp +++ b/engines/bladerunner/audio_player.cpp @@ -22,14 +22,14 @@ #include "bladerunner/audio_player.h" -#include "bladerunner/bladerunner.h" - #include "bladerunner/archive.h" #include "bladerunner/aud_stream.h" #include "bladerunner/audio_mixer.h" +#include "bladerunner/bladerunner.h" #include "common/debug.h" #include "common/stream.h" +#include "common/random.h" namespace Common { class MemoryReadStream; @@ -43,7 +43,7 @@ AudioCache::~AudioCache() { } } -bool AudioCache::canAllocate(uint32 size) { +bool AudioCache::canAllocate(uint32 size) const { Common::StackLock lock(_mutex); return _maxSize - _totalSize >= size; @@ -84,7 +84,7 @@ void AudioCache::storeByHash(int32 hash, Common::SeekableReadStream *stream) { Common::StackLock lock(_mutex); uint32 size = stream->size(); - byte *data = (byte*)malloc(size); + byte *data = (byte *)malloc(size); stream->read(data, size); cacheItem item = { @@ -124,7 +124,8 @@ void AudioCache::decRef(int32 hash) { assert(false && "AudioCache::decRef: hash not found"); } -AudioPlayer::AudioPlayer(BladeRunnerEngine *vm) : _vm(vm) { +AudioPlayer::AudioPlayer(BladeRunnerEngine *vm) { + _vm = vm; _cache = new AudioCache(); for (int i = 0; i != 6; ++i) { @@ -177,6 +178,31 @@ void AudioPlayer::adjustPan(int track, int pan, int delay) { _vm->_audioMixer->adjustPan(_tracks[track].channel, pan, 60 * delay); } +void AudioPlayer::setVolume(int volume) { + _sfxVolume = volume; +} + +int AudioPlayer::getVolume() const { + return _sfxVolume; +} + +void AudioPlayer::playSample() { + Common::String name; + + int rnd = _vm->_rnd.getRandomNumber(3); + if (rnd == 0) { + name = "gunmiss1.aud"; + } else if (rnd == 1) { + name = "gunmiss2.aud"; + } else if (rnd == 2) { + name = "gunmiss3.aud"; + } else { + name = "gunmiss4.aud"; + } + + playAud(name, 100, 0, 0, 100, 0); +} + void AudioPlayer::remove(int channel) { Common::StackLock lock(_mutex); for (int i = 0; i != kTracks; ++i) { @@ -284,7 +310,7 @@ int AudioPlayer::playAud(const Common::String &name, int volume, int panFrom, in return track; } -bool AudioPlayer::isActive(int track) { +bool AudioPlayer::isActive(int track) const { Common::StackLock lock(_mutex); if (track < 0 || track >= kTracks) { return false; diff --git a/engines/bladerunner/audio_player.h b/engines/bladerunner/audio_player.h index 4934b43871..06949828ea 100644 --- a/engines/bladerunner/audio_player.h +++ b/engines/bladerunner/audio_player.h @@ -26,6 +26,7 @@ #include "common/array.h" #include "common/mutex.h" #include "common/str.h" + #include "audio/audiostream.h" namespace BladeRunner { @@ -60,7 +61,7 @@ public: } ~AudioCache(); - bool canAllocate(uint32 size); + bool canAllocate(uint32 size) const; bool dropOldest(); byte *findByHash(int32 hash); void storeByHash(int32 hash, Common::SeekableReadStream *stream); @@ -101,12 +102,16 @@ public: }; int playAud(const Common::String &name, int volume, int panStart, int panEnd, int priority, byte flags = 0); - bool isActive(int track); + bool isActive(int track) const; void stop(int track, bool immediately); void stopAll(); void adjustVolume(int track, int volume, int delay, bool overrideVolume); void adjustPan(int track, int pan, int delay); + void setVolume(int volume); + int getVolume() const; + void playSample(); + private: void remove(int channel); static void mixerChannelEnded(int channel, void *data); diff --git a/engines/bladerunner/audio_speech.cpp b/engines/bladerunner/audio_speech.cpp index 90fc213f2d..1f3465c7eb 100644 --- a/engines/bladerunner/audio_speech.cpp +++ b/engines/bladerunner/audio_speech.cpp @@ -22,6 +22,7 @@ #include "bladerunner/audio_speech.h" +#include "bladerunner/actor.h" #include "bladerunner/aud_stream.h" #include "bladerunner/audio_mixer.h" #include "bladerunner/bladerunner.h" @@ -30,7 +31,7 @@ namespace BladeRunner { -#define BUFFER_SIZE 200000 +const int AudioSpeech::kSpeechSamples[] = { 65, 355, 490, 465, 480, 485, 505, 760, 7655, 7770, 7740, 8170, 2705, 7200, 6460, 5560, 4870, 4555, 3880, 3525, 3595, 3250, 3070 }; void AudioSpeech::ended() { //Common::StackLock lock(_mutex); @@ -39,14 +40,15 @@ void AudioSpeech::ended() { } void AudioSpeech::mixerChannelEnded(int channel, void *data) { - AudioSpeech *audioSpeech = (AudioSpeech*)data; + AudioSpeech *audioSpeech = (AudioSpeech *)data; audioSpeech->ended(); } -AudioSpeech::AudioSpeech(BladeRunnerEngine *vm) : _vm(vm) { - _volume = 50; +AudioSpeech::AudioSpeech(BladeRunnerEngine *vm) { + _vm = vm; + _speechVolume = 50; _isActive = false; - _data = new byte[BUFFER_SIZE]; + _data = new byte[kBufferSize]; _channel = -1; } @@ -63,8 +65,8 @@ bool AudioSpeech::playSpeech(const char *name, int pan) { return false; } - if (r->size() > BUFFER_SIZE) { - warning("AudioSpeech::playSpeech: AUD larger than buffer size (%d > %d)", r->size(), BUFFER_SIZE); + if (r->size() > kBufferSize) { + warning("AudioSpeech::playSpeech: AUD larger than buffer size (%d > %d)", r->size(), kBufferSize); return false; } @@ -87,7 +89,7 @@ bool AudioSpeech::playSpeech(const char *name, int pan) { audioStream, 100, false, - _volume, + _speechVolume, pan, mixerChannelEnded, this); @@ -104,11 +106,23 @@ void AudioSpeech::stopSpeech() { } } -bool AudioSpeech::isPlaying() { +bool AudioSpeech::isPlaying() const { if (_channel == -1) { return false; } return _isActive; } +void AudioSpeech::setVolume(int volume) { + _speechVolume = volume; +} + +int AudioSpeech::getVolume() const { + return _speechVolume; +} + +void AudioSpeech::playSample() { + _vm->_playerActor->speechPlay(kSpeechSamples[_vm->_rnd.getRandomNumber(22)], true); +} + } // End of namespace BladeRunner diff --git a/engines/bladerunner/audio_speech.h b/engines/bladerunner/audio_speech.h index f3e4395d5d..5b94bc96d2 100644 --- a/engines/bladerunner/audio_speech.h +++ b/engines/bladerunner/audio_speech.h @@ -30,12 +30,15 @@ namespace BladeRunner { class BladeRunnerEngine; class AudioSpeech { - BladeRunnerEngine *_vm; + static const int kBufferSize = 200000; + static const int kSpeechSamples[]; - int _volume; - bool _isActive; - int _channel; - byte *_data; + BladeRunnerEngine *_vm; + + int _speechVolume; + bool _isActive; + int _channel; + byte *_data; public: AudioSpeech(BladeRunnerEngine *vm); @@ -43,8 +46,11 @@ public: bool playSpeech(const char *name, int balance = 0); void stopSpeech(); - bool isPlaying(); - void setVolume(int volume) { _volume = volume; } + bool isPlaying() const; + + void setVolume(int volume); + int getVolume() const; + void playSample(); private: void ended(); diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp index 653f159bb3..6f015d7044 100644 --- a/engines/bladerunner/bladerunner.cpp +++ b/engines/bladerunner/bladerunner.cpp @@ -23,7 +23,7 @@ #include "bladerunner/bladerunner.h" #include "bladerunner/actor.h" -#include "bladerunner/adq.h" +#include "bladerunner/actor_dialogue_queue.h" #include "bladerunner/ambient_sounds.h" #include "bladerunner/audio_mixer.h" #include "bladerunner/audio_player.h" @@ -32,10 +32,10 @@ #include "bladerunner/combat.h" #include "bladerunner/crimes_database.h" #include "bladerunner/dialogue_menu.h" -#include "bladerunner/elevator.h" #include "bladerunner/font.h" -#include "bladerunner/gameflags.h" -#include "bladerunner/gameinfo.h" +#include "bladerunner/game_constants.h" +#include "bladerunner/game_flags.h" +#include "bladerunner/game_info.h" #include "bladerunner/image.h" #include "bladerunner/item_pickup.h" #include "bladerunner/items.h" @@ -49,16 +49,20 @@ #include "bladerunner/scene.h" #include "bladerunner/scene_objects.h" #include "bladerunner/screen_effects.h" +#include "bladerunner/set.h" +#include "bladerunner/script/ai.h" #include "bladerunner/script/init.h" +#include "bladerunner/script/kia.h" #include "bladerunner/script/scene.h" -#include "bladerunner/script/ai.h" #include "bladerunner/settings.h" #include "bladerunner/shape.h" #include "bladerunner/slice_animations.h" #include "bladerunner/slice_renderer.h" -#include "bladerunner/spinner.h" #include "bladerunner/suspects_database.h" #include "bladerunner/text_resource.h" +#include "bladerunner/ui/elevator.h" +#include "bladerunner/ui/kia.h" +#include "bladerunner/ui/spinner.h" #include "bladerunner/vqa_decoder.h" #include "bladerunner/waypoints.h" #include "bladerunner/zbuffer.h" @@ -78,22 +82,11 @@ namespace BladeRunner { BladeRunnerEngine::BladeRunnerEngine(OSystem *syst, const ADGameDescription *desc) : Engine(syst), _rnd("bladerunner") { + _windowIsActive = true; _gameIsRunning = true; _playerLosesControlCounter = 0; - //TODO(peterkohaut): move these to init - - _crimesDatabase = nullptr; - _sceneScript = new SceneScript(this); - _settings = new Settings(this); - _lights = new Lights(this); - _screenEffects = new ScreenEffects(this, 0x8000); - _combat = new Combat(this); - _adq = new ADQ(this); - _obstacles = new Obstacles(this); - _itemPickup = new ItemPickup(this); - _playerActorIdle = false; _playerDead = false; _speechSkipped = false; @@ -106,6 +99,8 @@ BladeRunnerEngine::BladeRunnerEngine(OSystem *syst, const ADGameDescription *des _walkSoundVolume = 0; _walkSoundBalance = 0; + _crimesDatabase = nullptr; + switch (desc->language) { case Common::EN_ANY: this->_languageCode = "E"; @@ -131,30 +126,6 @@ BladeRunnerEngine::BladeRunnerEngine(OSystem *syst, const ADGameDescription *des } BladeRunnerEngine::~BladeRunnerEngine() { - // delete _sliceRenderer; - // delete _sliceAnimations; - // delete _settings; - // delete _script; - // delete _scene; - // delete[] _gameVars; - // delete _gameFlags; - // delete _gameInfo; - // delete _clues; - // delete _chapters; - // delete _audioSpeech; - // delete _audioPlayer; - // delete _ambientSounds; - - delete _zbuffer; - - delete _itemPickup; - delete _obstacles; - delete _adq; - delete _combat; - delete _screenEffects; - delete _lights; - delete _settings; - delete _sceneScript; } bool BladeRunnerEngine::hasFeature(EngineFeature f) const { @@ -185,10 +156,42 @@ Common::Error BladeRunnerEngine::run() { } bool BladeRunnerEngine::startup(bool hasSavegames) { + // These are static objects in original game + + _screenEffects = new ScreenEffects(this, 0x8000); + + _combat = new Combat(this); + + // TODO: end credits + + _actorDialogueQueue = new ActorDialogueQueue(this); + + // TODO: esper script + + _settings = new Settings(this); + + _itemPickup = new ItemPickup(this); + + _lights = new Lights(this); + + // TODO: outtake player - but this is done bit differently + + // TODO: police maze + + _obstacles = new Obstacles(this); + + // TODO: slice renderer shadow + + // TODO: voight-kampf script + + _sceneScript = new SceneScript(this); + + // This is the original startup in the game + bool r; - _surfaceGame.create(640, 480, createRGB555()); - _surfaceInterface.create(640, 480, createRGB555()); + _surfaceFront.create(640, 480, createRGB555()); + _surfaceBack.create(640, 480, createRGB555()); _surface4.create(640, 480, createRGB555()); r = openArchive("STARTUP.MIX"); @@ -272,12 +275,12 @@ bool BladeRunnerEngine::startup(bool hasSavegames) { _zbuffer->init(640, 480); int actorCount = (int)_gameInfo->getActorCount(); - assert(actorCount < ACTORS_COUNT); + assert(actorCount < kActorCount); for (int i = 0; i != actorCount; ++i) { _actors[i] = new Actor(this, i); _actors[i]->setup(i); } - _actors[VOICEOVER_ACTOR] = new Actor(this, VOICEOVER_ACTOR); + _actors[kActorVoiceOver] = new Actor(this, kActorVoiceOver); _playerActor = _actors[_gameInfo->getPlayerId()]; _playerActor->setFPS(15); @@ -296,8 +299,8 @@ bool BladeRunnerEngine::startup(bool hasSavegames) { if (!_textCrimes->open("CRIMES")) return false; - _textCluetype = new TextResource(this); - if (!_textCluetype->open("CLUETYPE")) + _textClueTypes = new TextResource(this); + if (!_textClueTypes->open("CLUETYPE")) return false; _textKIA = new TextResource(this); @@ -320,9 +323,9 @@ bool BladeRunnerEngine::startup(bool hasSavegames) { if (!_dialogueMenu->loadText("DLGMENU")) return false; - _suspectsDatabase = new SuspectsDatabase(this, _gameInfo->getSuspectsDatabaseSize()); + _suspectsDatabase = new SuspectsDatabase(this, _gameInfo->getSuspectCount()); - // TODO: KIA + _kia = new KIA(this); _spinner = new Spinner(this); @@ -446,8 +449,8 @@ void BladeRunnerEngine::shutdown() { delete _textCrimes; _textCrimes = nullptr; - delete _textCluetype; - _textCluetype = nullptr; + delete _textClueTypes; + _textClueTypes = nullptr; delete _textKIA; _textKIA = nullptr; @@ -535,7 +538,8 @@ void BladeRunnerEngine::shutdown() { delete _spinner; _spinner = nullptr; - // TODO: Delete KIA + delete _kia; + _kia = nullptr; delete _suspectsDatabase; _suspectsDatabase = nullptr; @@ -547,8 +551,8 @@ void BladeRunnerEngine::shutdown() { delete _actors[i]; _actors[i] = nullptr; } - delete _actors[VOICEOVER_ACTOR]; - _actors[VOICEOVER_ACTOR] = nullptr; + delete _actors[kActorVoiceOver]; + _actors[kActorVoiceOver] = nullptr; _playerActor = nullptr; @@ -560,8 +564,8 @@ void BladeRunnerEngine::shutdown() { // TODO: Delete graphics surfaces here _surface4.free(); - _surfaceInterface.free(); - _surfaceGame.free(); + _surfaceBack.free(); + _surfaceFront.free(); if (isArchiveOpen("STARTUP.MIX")) { closeArchive("STARTUP.MIX"); @@ -570,6 +574,37 @@ void BladeRunnerEngine::shutdown() { // TODO: Delete MIXArchives here // TODO: Delete Timer + + + + // These are static objects in original game + + delete _zbuffer; + _zbuffer = nullptr; + + delete _itemPickup; + _itemPickup = nullptr; + + delete _obstacles; + _obstacles = nullptr; + + delete _actorDialogueQueue; + _actorDialogueQueue = nullptr; + + delete _combat; + _combat = nullptr; + + delete _screenEffects; + _screenEffects = nullptr; + + delete _lights; + _lights = nullptr; + + delete _settings; + _settings = nullptr; + + delete _sceneScript; + _sceneScript = nullptr; } bool BladeRunnerEngine::loadSplash() { @@ -578,9 +613,9 @@ bool BladeRunnerEngine::loadSplash() { return false; } - img.copyToSurface(&_surfaceGame); + img.copyToSurface(&_surfaceFront); - blitToScreen(_surfaceGame); + blitToScreen(_surfaceFront); return true; } @@ -589,7 +624,7 @@ bool BladeRunnerEngine::init2() { return true; } -Common::Point BladeRunnerEngine::getMousePos() { +Common::Point BladeRunnerEngine::getMousePos() const { return _eventMan->getMousePos(); } @@ -601,7 +636,7 @@ void BladeRunnerEngine::gameLoop() { } while (_gameIsRunning); } -#if _DEBUG +#if BLADERUNNER_DEBUG_RENDERING void drawBBox(Vector3 start, Vector3 end, View *view, Graphics::Surface *surface, int color) { Vector3 bfl = view->calculateScreenPosition(Vector3(start.x, start.y, start.z)); @@ -645,7 +680,10 @@ void BladeRunnerEngine::gameTick() { //probably not needed, this version of tick is just loading data from buffer //_audioMixer->tick(); - // TODO: Kia + if (_kia->_currentSectionId) { + _kia->tick(); + return; + } if (_spinner->isOpen()) { _spinner->tick(); @@ -664,7 +702,7 @@ void BladeRunnerEngine::gameTick() { // TODO: Scores - _adq->tick(); + _actorDialogueQueue->tick(); if (_scene->didPlayerWalkIn()) { _sceneScript->PlayerWalkedIn(); } @@ -685,10 +723,10 @@ void BladeRunnerEngine::gameTick() { backgroundChanged = true; } (void)backgroundChanged; - blit(_surfaceInterface, _surfaceGame); + blit(_surfaceBack, _surfaceFront); // TODO: remove zbuffer draw - // _surfaceGame.copyRectToSurface(_zbuffer->getData(), 1280, 0, 0, 640, 480); + // _surfaceFront.copyRectToSurface(_zbuffer->getData(), 1280, 0, 0, 640, 480); _overlays->tick(); @@ -725,11 +763,11 @@ void BladeRunnerEngine::gameTick() { if (_dialogueMenu->isVisible()) { _dialogueMenu->tick(p.x, p.y); - _dialogueMenu->draw(_surfaceGame); + _dialogueMenu->draw(_surfaceFront); } _mouse->tick(p.x, p.y); - _mouse->draw(_surfaceGame, p.x, p.y); + _mouse->draw(_surfaceFront, p.x, p.y); // TODO: Process AUD @@ -739,69 +777,69 @@ void BladeRunnerEngine::gameTick() { _walkSoundId = -1; } -#if 0 +#if BLADERUNNER_DEBUG_RENDERING //draw scene objects int count = _sceneObjects->_count; if (count > 0) { for (int i = 0; i < count; i++) { - SceneObject *sceneObject = &_sceneObjects->_sceneObjects[_sceneObjects->_sceneObjectsSortedByDistance[i]]; + SceneObjects::SceneObject *sceneObject = &_sceneObjects->_sceneObjects[_sceneObjects->_sceneObjectsSortedByDistance[i]]; - BoundingBox *bbox = &sceneObject->_boundingBox; + BoundingBox *bbox = &sceneObject->boundingBox; Vector3 a, b; bbox->getXYZ(&a.x, &a.y, &a.z, &b.x, &b.y, &b.z); Vector3 pos = _view->calculateScreenPosition(0.5 * (a + b)); int color; - switch (sceneObject->_sceneObjectType) { - case SceneObjectTypeActor: + switch (sceneObject->sceneObjectType) { + case kSceneObjectTypeActor: color = 0b111110000000000; - drawBBox(a, b, _view, &_surfaceGame, color); - _mainFont->drawColor(_textActorNames->getText(sceneObject->_sceneObjectId - SCENE_OBJECTS_ACTORS_OFFSET), _surfaceGame, pos.x, pos.y, color); + drawBBox(a, b, _view, &_surfaceFront, color); + _mainFont->drawColor(_textActorNames->getText(sceneObject->sceneObjectId - kSceneObjectOffsetActors), _surfaceFront, pos.x, pos.y, color); break; - case SceneObjectTypeItem: + case kSceneObjectTypeItem: char itemText[40]; - drawBBox(a, b, _view, &_surfaceGame, color); - sprintf(itemText, "item %i", sceneObject->_sceneObjectId - SCENE_OBJECTS_ITEMS_OFFSET); - _mainFont->drawColor(itemText, _surfaceGame, pos.x, pos.y, color); + drawBBox(a, b, _view, &_surfaceFront, color); + sprintf(itemText, "item %i", sceneObject->sceneObjectId - kSceneObjectOffsetItems); + _mainFont->drawColor(itemText, _surfaceFront, pos.x, pos.y, color); break; - case SceneObjectTypeObject: + case kSceneObjectTypeObject: color = 0b011110111101111; //if (sceneObject->_isObstacle) // color += 0b100000000000000; - if (sceneObject->_isClickable) { + if (sceneObject->isClickable) { color = 0b000001111100000; } - drawBBox(a, b, _view, &_surfaceGame, color); - _mainFont->drawColor(_scene->objectGetName(sceneObject->_sceneObjectId - SCENE_OBJECTS_OBJECTS_OFFSET), _surfaceGame, pos.x, pos.y, color); + drawBBox(a, b, _view, &_surfaceFront, color); + _mainFont->drawColor(_scene->objectGetName(sceneObject->sceneObjectId - kSceneObjectOffsetObjects), _surfaceFront, pos.x, pos.y, color); break; } - _surfaceGame.frameRect(sceneObject->_screenRectangle, color); + _surfaceFront.frameRect(sceneObject->screenRectangle, color); } } //draw regions for (int i = 0; i < 10; i++) { - Region *region = &_scene->_regions->_regions[i]; - if (!region->_present) continue; - _surfaceGame.frameRect(region->_rectangle, 0b000000000011111); + Regions::Region *region = &_scene->_regions->_regions[i]; + if (!region->present) continue; + _surfaceFront.frameRect(region->rectangle, 0b000000000011111); } for (int i = 0; i < 10; i++) { - Region *region = &_scene->_exits->_regions[i]; - if (!region->_present) continue; - _surfaceGame.frameRect(region->_rectangle, 0b111111111111111); + Regions::Region *region = &_scene->_exits->_regions[i]; + if (!region->present) continue; + _surfaceFront.frameRect(region->rectangle, 0b111111111111111); } //draw walkboxes for (int i = 0; i < _scene->_set->_walkboxCount; i++) { - Walkbox *walkbox = &_scene->_set->_walkboxes[i]; + Set::Walkbox *walkbox = &_scene->_set->_walkboxes[i]; - for (int j = 0; j < walkbox->_vertexCount; j++) { - Vector3 start = _view->calculateScreenPosition(walkbox->_vertices[j]); - Vector3 end = _view->calculateScreenPosition(walkbox->_vertices[(j + 1) % walkbox->_vertexCount]); - _surfaceGame.drawLine(start.x, start.y, end.x, end.y, 0b111111111100000); + for (int j = 0; j < walkbox->vertexCount; j++) { + Vector3 start = _view->calculateScreenPosition(walkbox->vertices[j]); + Vector3 end = _view->calculateScreenPosition(walkbox->vertices[(j + 1) % walkbox->vertexCount]); + _surfaceFront.drawLine(start.x, start.y, end.x, end.y, 0b111111111100000); Vector3 pos = _view->calculateScreenPosition(0.5 * (start + end)); - _mainFont->drawColor(walkbox->_name, _surfaceGame, pos.x, pos.y, 0b111111111100000); + _mainFont->drawColor(walkbox->name, _surfaceFront, pos.x, pos.y, 0b111111111100000); } } @@ -827,30 +865,30 @@ void BladeRunnerEngine::gameTick() { int colorB = (light->_color.b * 31.0f); int color = (colorR << 10) + (colorG << 5) + colorB; - drawBBox(posOrigin - size, posOrigin + size, _view, &_surfaceGame, color); + drawBBox(posOrigin - size, posOrigin + size, _view, &_surfaceFront, color); Vector3 posOriginT = _view->calculateScreenPosition(posOrigin); Vector3 posTargetT = _view->calculateScreenPosition(posTarget); - _surfaceGame.drawLine(posOriginT.x, posOriginT.y, posTargetT.x, posTargetT.y, color); - _mainFont->drawColor(light->_name, _surfaceGame, posOriginT.x, posOriginT.y, color); + _surfaceFront.drawLine(posOriginT.x, posOriginT.y, posTargetT.x, posTargetT.y, color); + _mainFont->drawColor(light->_name, _surfaceFront, posOriginT.x, posOriginT.y, color); } //draw waypoints for(int i = 0; i < _waypoints->_count; i++) { - Waypoint *waypoint = &_waypoints->_waypoints[i]; - if(waypoint->_setId != _scene->getSetId()) + Waypoints::Waypoint *waypoint = &_waypoints->_waypoints[i]; + if(waypoint->setId != _scene->getSetId()) continue; - Vector3 pos = waypoint->_position; + Vector3 pos = waypoint->position; Vector3 size = Vector3(5.0f, 5.0f, 5.0f); int color = 0b111111111111111; - drawBBox(pos - size, pos + size, _view, &_surfaceGame, color); + drawBBox(pos - size, pos + size, _view, &_surfaceFront, color); Vector3 spos = _view->calculateScreenPosition(pos); char waypointText[40]; sprintf(waypointText, "waypoint %i", i); - _mainFont->drawColor(waypointText, _surfaceGame, spos.x, spos.y, color); + _mainFont->drawColor(waypointText, _surfaceFront, spos.x, spos.y, color); } #endif -#if 0 +#if BLADERUNNER_DEBUG_RENDERING //draw aesc for (uint i = 0; i < _screenEffects->_entries.size(); i++) { ScreenEffects::Entry &entry = _screenEffects->_entries[i]; @@ -868,13 +906,13 @@ void BladeRunnerEngine::gameTick() { CLIP(color.r * bladeToScummVmConstant, 0, 255), CLIP(color.g * bladeToScummVmConstant, 0, 255), CLIP(color.b * bladeToScummVmConstant, 0, 255)); - _surfaceGame.fillRect(r, color555); + _surfaceFront.fillRect(r, color555); } } } #endif - blitToScreen(_surfaceGame); + blitToScreen(_surfaceFront); _system->delayMillis(10); } } @@ -936,14 +974,48 @@ void BladeRunnerEngine::handleKeyUp(Common::Event &event) { if (event.kbd.keycode == Common::KEYCODE_RETURN) { _speechSkipped = true; } + + // TODO(peterkohaut): + if (!playerHasControl() /*|| ActorInWalkingLoop*/) { + return; + } + + if (_kia->_currentSectionId) { + _kia->handleKeyUp(event.kbd); + return; + } + + if (event.kbd.keycode == Common::KEYCODE_TAB) { + _kia->openLastOpened(); + } else if (event.kbd.keycode == Common::KEYCODE_ESCAPE) { + _kia->openOptions(); + } else if (event.kbd.keycode == Common::KEYCODE_SPACE) { + // TODO(peterkohaut): + // combat::switchCombatMode(&Combat); + } } void BladeRunnerEngine::handleKeyDown(Common::Event &event) { + // if ( PlayerHasControl <= 0 && ActorWalkingLoop != 1 && PlayingSpeechLine != 1 && VqaIsPlaying != 1 ) { + if (_kia->_currentSectionId) { + _kia->handleKeyDown(event.kbd); + } + // } } void BladeRunnerEngine::handleMouseAction(int x, int y, bool buttonLeft, bool buttonDown) { - if (!playerHasControl() || _mouse->isDisabled()) + if (!playerHasControl() || _mouse->isDisabled()) { return; + } + + if (_kia->_currentSectionId) { + if (buttonDown) { + _kia->handleMouseDown(x, y, buttonLeft); + } else { + _kia->handleMouseUp(x, y, buttonLeft); + } + return; + } if (_spinner->isOpen()) { if (buttonDown) { @@ -1086,14 +1158,16 @@ bool BladeRunnerEngine::openArchive(const Common::String &name) { // If archive is already open, return true for (i = 0; i != kArchiveCount; ++i) { - if (_archives[i].isOpen() && _archives[i].getName() == name) + if (_archives[i].isOpen() && _archives[i].getName() == name) { return true; + } } // Find first available slot for (i = 0; i != kArchiveCount; ++i) { - if (!_archives[i].isOpen()) + if (!_archives[i].isOpen()) { break; + } } if (i == kArchiveCount) { /* TODO: BLADE.EXE retires the least recently used @@ -1108,7 +1182,7 @@ bool BladeRunnerEngine::openArchive(const Common::String &name) { } bool BladeRunnerEngine::closeArchive(const Common::String &name) { - for (uint i = 0; i != 10; ++i) { + for (uint i = 0; i != kArchiveCount; ++i) { if (_archives[i].isOpen() && _archives[i].getName() == name) { _archives[i].close(); return true; @@ -1119,8 +1193,8 @@ bool BladeRunnerEngine::closeArchive(const Common::String &name) { return false; } -bool BladeRunnerEngine::isArchiveOpen(const Common::String &name) { - for (uint i = 0; i != 10; ++i) { +bool BladeRunnerEngine::isArchiveOpen(const Common::String &name) const { + for (uint i = 0; i != kArchiveCount; ++i) { if (_archives[i].isOpen() && _archives[i].getName() == name) return true; } @@ -1129,7 +1203,7 @@ bool BladeRunnerEngine::isArchiveOpen(const Common::String &name) { } Common::SeekableReadStream *BladeRunnerEngine::getResourceStream(const Common::String &name) { - for (uint i = 0; i != 10; ++i) { + for (uint i = 0; i != kArchiveCount; ++i) { if (!_archives[i].isOpen()) { continue; } diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h index 208c245e25..01636e8949 100644 --- a/engines/bladerunner/bladerunner.h +++ b/engines/bladerunner/bladerunner.h @@ -33,6 +33,9 @@ #include "graphics/surface.h" +#define BLADERUNNER_DEBUG_RENDERING 0 +#define BLADERUNNER_DEBUG_CONSOLE 0 + namespace Common { struct Event; } @@ -58,7 +61,7 @@ enum SceneLoopMode { }; class Actor; -class ADQ; +class ActorDialogueQueue; class ScreenEffects; class AIScripts; class AmbientSounds; @@ -75,6 +78,7 @@ class GameFlags; class GameInfo; class ItemPickup; class Items; +class KIA; class Lights; class Mouse; class Music; @@ -90,72 +94,75 @@ class SliceRenderer; class Spinner; class SuspectsDatabase; class TextResource; +class KIAShapes; class Vector3; class View; class Waypoints; class ZBuffer; -#define ACTORS_COUNT 100 -#define VOICEOVER_ACTOR (ACTORS_COUNT - 1) - class BladeRunnerEngine : public Engine { public: + static const int kArchiveCount = 10; + static const int kActorCount = 100; + static const int kActorVoiceOver = kActorCount - 1; + bool _gameIsRunning; bool _windowIsActive; int _playerLosesControlCounter; const char *_languageCode; - ADQ *_adq; - ScreenEffects *_screenEffects; - AIScripts *_aiScripts; - AmbientSounds *_ambientSounds; - AudioMixer *_audioMixer; - AudioPlayer *_audioPlayer; - AudioSpeech *_audioSpeech; - Chapters *_chapters; - CrimesDatabase *_crimesDatabase; - Combat *_combat; - DialogueMenu *_dialogueMenu; - Elevator *_elevator; - GameFlags *_gameFlags; - GameInfo *_gameInfo; - ItemPickup *_itemPickup; - Items *_items; - Lights *_lights; - Font *_mainFont; - Mouse *_mouse; - Music *_music; - Obstacles *_obstacles; - Overlays *_overlays; - Scene *_scene; - SceneObjects *_sceneObjects; - SceneScript *_sceneScript; - Settings *_settings; - SliceAnimations *_sliceAnimations; - SliceRenderer *_sliceRenderer; - Spinner *_spinner; - SuspectsDatabase *_suspectsDatabase; - View *_view; - Waypoints *_waypoints; - int *_gameVars; - - TextResource *_textActorNames; - TextResource *_textCrimes; - TextResource *_textCluetype; - TextResource *_textKIA; - TextResource *_textSpinnerDestinations; - TextResource *_textVK; - TextResource *_textOptions; + ActorDialogueQueue *_actorDialogueQueue; + ScreenEffects *_screenEffects; + AIScripts *_aiScripts; + AmbientSounds *_ambientSounds; + AudioMixer *_audioMixer; + AudioPlayer *_audioPlayer; + AudioSpeech *_audioSpeech; + Chapters *_chapters; + CrimesDatabase *_crimesDatabase; + Combat *_combat; + DialogueMenu *_dialogueMenu; + Elevator *_elevator; + GameFlags *_gameFlags; + GameInfo *_gameInfo; + ItemPickup *_itemPickup; + Items *_items; + KIA *_kia; + Lights *_lights; + Font *_mainFont; + Mouse *_mouse; + Music *_music; + Obstacles *_obstacles; + Overlays *_overlays; + Scene *_scene; + SceneObjects *_sceneObjects; + SceneScript *_sceneScript; + Settings *_settings; + SliceAnimations *_sliceAnimations; + SliceRenderer *_sliceRenderer; + Spinner *_spinner; + SuspectsDatabase *_suspectsDatabase; + View *_view; + Waypoints *_waypoints; + int *_gameVars; + + TextResource *_textActorNames; + TextResource *_textCrimes; + TextResource *_textClueTypes; + TextResource *_textKIA; + TextResource *_textSpinnerDestinations; + TextResource *_textVK; + TextResource *_textOptions; Common::Array<Shape*> _shapes; - Actor *_actors[ACTORS_COUNT]; + Actor *_actors[kActorCount]; Actor *_playerActor; int in_script_counter; - Graphics::Surface _surfaceGame; - Graphics::Surface _surfaceInterface; + Graphics::Surface _surfaceFront; + Graphics::Surface _surfaceBack; Graphics::Surface _surface4; ZBuffer *_zbuffer; @@ -174,8 +181,8 @@ public: int _walkSoundVolume; int _walkSoundBalance; int _walkingActorId; + private: - static const uint kArchiveCount = 10; MIXArchive _archives[kArchiveCount]; public: @@ -193,7 +200,7 @@ public: bool loadSplash(); bool init2(); - Common::Point getMousePos(); + Common::Point getMousePos() const; void gameLoop(); void gameTick(); @@ -215,7 +222,7 @@ public: bool openArchive(const Common::String &name); bool closeArchive(const Common::String &name); - bool isArchiveOpen(const Common::String &name); + bool isArchiveOpen(const Common::String &name) const; Common::SeekableReadStream *getResourceStream(const Common::String &name); diff --git a/engines/bladerunner/boundingbox.cpp b/engines/bladerunner/boundingbox.cpp index 029442668f..f7e7eca190 100644 --- a/engines/bladerunner/boundingbox.cpp +++ b/engines/bladerunner/boundingbox.cpp @@ -44,7 +44,7 @@ void BoundingBox::expand(float x0, float y0, float z0, float x1, float y1, float _vertices[1].z += z1; } -bool BoundingBox::inside(float x, float y, float z) { +bool BoundingBox::inside(float x, float y, float z) const { return x >= _vertices[0].x && x <= _vertices[1].x && y >= _vertices[0].y && y <= _vertices[1].y && z >= _vertices[0].z && z <= _vertices[1].z; @@ -60,7 +60,7 @@ void BoundingBox::setXYZ(float x0, float y0, float z0, float x1, float y1, float _vertices[1].z = z1; } -void BoundingBox::getXYZ(float *x0, float *y0, float *z0, float *x1, float *y1, float *z1) { +void BoundingBox::getXYZ(float *x0, float *y0, float *z0, float *x1, float *y1, float *z1) const { *x0 = _vertices[0].x; *y0 = _vertices[0].y; *z0 = _vertices[0].z; @@ -70,11 +70,11 @@ void BoundingBox::getXYZ(float *x0, float *y0, float *z0, float *x1, float *y1, *z1 = _vertices[1].z; } -float BoundingBox::getZ0() { +float BoundingBox::getZ0() const { return _vertices[0].z; } -float BoundingBox::getZ1() { +float BoundingBox::getZ1() const { return _vertices[1].z; } diff --git a/engines/bladerunner/boundingbox.h b/engines/bladerunner/boundingbox.h index da91489f25..3f42318cde 100644 --- a/engines/bladerunner/boundingbox.h +++ b/engines/bladerunner/boundingbox.h @@ -35,13 +35,13 @@ public: BoundingBox(float x0, float y0, float z0, float x1, float y1, float z1); void expand(float x0, float y0, float z0, float x1, float y1, float z1); - bool inside(float x, float y, float z); + bool inside(float x, float y, float z) const; void setXYZ(float x0, float y0, float z0, float x1, float y1, float z1); - void getXYZ(float* x0, float *y0, float* z0, float *x1, float* y1, float* z1); + void getXYZ(float *x0, float *y0, float *z0, float *x1, float *y1, float *z1) const; - float getZ0(); - float getZ1(); + float getZ0() const; + float getZ1() const; }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/chapters.h b/engines/bladerunner/chapters.h index 5d4da5713d..96b2d48179 100644 --- a/engines/bladerunner/chapters.h +++ b/engines/bladerunner/chapters.h @@ -35,7 +35,8 @@ class Chapters { bool _hasOpenResources; public: - Chapters(BladeRunnerEngine *vm) : _vm(vm), _chapter(0) { + Chapters(BladeRunnerEngine *vm) { + _vm = vm; _chapter = 0; _resourceIds[0] = 1; diff --git a/engines/bladerunner/combat.cpp b/engines/bladerunner/combat.cpp index 79ea2ad7bf..79491e702a 100644 --- a/engines/bladerunner/combat.cpp +++ b/engines/bladerunner/combat.cpp @@ -22,14 +22,14 @@ #include "bladerunner/combat.h" -#include "bladerunner/bladerunner.h" #include "bladerunner/actor.h" +#include "bladerunner/bladerunner.h" #include "bladerunner/settings.h" namespace BladeRunner { -Combat::Combat(BladeRunnerEngine* vm) { +Combat::Combat(BladeRunnerEngine *vm) { _vm = vm; _active = false; @@ -74,12 +74,20 @@ void Combat::disable() { _enabled = false; } -void Combat::setHitSoundId(int row, int column, int soundId) { - _hitSoundId[row * 3 + column] = soundId; +void Combat::setHitSound(int ammoType, int column, int soundId) { + _hitSoundId[ammoType * 3 + column] = soundId; +} + +void Combat::setMissSound(int ammoType, int column, int soundId) { + _missSoundId[ammoType * 3 + column] = soundId; +} + +int Combat::getHitSound() { + return _hitSoundId[3 * _vm->_settings->getAmmoType() + _vm->_rnd.getRandomNumber(2)]; } -void Combat::setMissSoundId(int row, int column, int soundId) { - _missSoundId[row * 3 + column] = soundId; +int Combat::getMissSound() { + return _hitSoundId[3 * _vm->_settings->getAmmoType() + _vm->_rnd.getRandomNumber(2)]; } } // End of namespace BladeRunner diff --git a/engines/bladerunner/combat.h b/engines/bladerunner/combat.h index abb2a328ba..8f0119a854 100644 --- a/engines/bladerunner/combat.h +++ b/engines/bladerunner/combat.h @@ -51,8 +51,10 @@ public: void enable(); void disable(); - void setHitSoundId(int row, int column, int soundId); - void setMissSoundId(int row, int column, int soundId); + void setHitSound(int ammoType, int column, int soundId); + void setMissSound(int ammoType, int column, int soundId); + int getHitSound(); + int getMissSound(); }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/crimes_database.cpp b/engines/bladerunner/crimes_database.cpp index 0caa683665..c309005d28 100644 --- a/engines/bladerunner/crimes_database.cpp +++ b/engines/bladerunner/crimes_database.cpp @@ -28,32 +28,30 @@ namespace BladeRunner { -CrimesDatabase::CrimesDatabase(BladeRunnerEngine *vm, const char *cluesResource, int crimesCount) : _crimesCount(crimesCount) { - // reset(); +CrimesDatabase::CrimesDatabase(BladeRunnerEngine *vm, const char *cluesResource, int crimeCount) { + _crimeCount = crimeCount; - _crimes = new int[_crimesCount]; - _assetTypes = new int[_crimesCount]; + _crimes.resize(_crimeCount); + _assetTypes.resize(_crimeCount); _cluesText = new TextResource(vm); _cluesText->open(cluesResource); - for (int i = 0; i != _crimesCount; ++i) { + for (int i = 0; i != _crimeCount; ++i) { _crimes[i] = -1; _assetTypes[i] = -1; } } CrimesDatabase::~CrimesDatabase() { - delete _cluesText; - delete[] _assetTypes; - delete[] _crimes; + delete _cluesText; } void CrimesDatabase::setCrime(int clueId, int crimeId) { _crimes[clueId] = crimeId; } -int CrimesDatabase::getCrime(int clueId) { +int CrimesDatabase::getCrime(int clueId) const { return _crimes[clueId]; } @@ -61,11 +59,11 @@ void CrimesDatabase::setAssetType(int clueId, int assetType) { _assetTypes[clueId] = assetType; } -int CrimesDatabase::getAssetType(int clueId) { +int CrimesDatabase::getAssetType(int clueId) const { return _assetTypes[clueId]; } -const char *CrimesDatabase::getClueText(int clueId) { +const char *CrimesDatabase::getClueText(int clueId) const { return _cluesText->getText(clueId); } diff --git a/engines/bladerunner/crimes_database.h b/engines/bladerunner/crimes_database.h index 830b58db67..40e46cb356 100644 --- a/engines/bladerunner/crimes_database.h +++ b/engines/bladerunner/crimes_database.h @@ -23,28 +23,30 @@ #ifndef BLADERUNNER_CRIMES_DATABASE_H #define BLADERUNNER_CRIMES_DATABASE_H +#include "common/array.h" + namespace BladeRunner { class BladeRunnerEngine; class TextResource; class CrimesDatabase { - int _crimesCount; - int *_crimes; - int *_assetTypes; - TextResource *_cluesText; + int _crimeCount; + Common::Array<int> _crimes; + Common::Array<int> _assetTypes; + TextResource *_cluesText; public: - CrimesDatabase(BladeRunnerEngine *vm, const char *cluesResource, int crimesCount); + CrimesDatabase(BladeRunnerEngine *vm, const char *cluesResource, int crimeCount); ~CrimesDatabase(); void setCrime(int clueId, int crimeId); - int getCrime(int clueId); + int getCrime(int clueId) const; void setAssetType(int clueId, int assetType); - int getAssetType(int clueId); + int getAssetType(int clueId) const; - const char *getClueText(int clueId); + const char *getClueText(int clueId) const; }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/dialogue_menu.cpp b/engines/bladerunner/dialogue_menu.cpp index e13e69cbd0..2d55deee3f 100644 --- a/engines/bladerunner/dialogue_menu.cpp +++ b/engines/bladerunner/dialogue_menu.cpp @@ -33,14 +33,10 @@ #include "common/rect.h" #include "common/util.h" -#define LINE_HEIGHT 9 -#define BORDER_SIZE 10 - namespace BladeRunner { -DialogueMenu::DialogueMenu(BladeRunnerEngine *vm) - : _vm(vm) -{ +DialogueMenu::DialogueMenu(BladeRunnerEngine *vm) { + _vm = vm; reset(); _textResource = new TextResource(_vm); _shapes.reserve(8); @@ -56,7 +52,7 @@ DialogueMenu::~DialogueMenu() { delete _textResource; } -bool DialogueMenu::loadText(const char *name) { +bool DialogueMenu::loadText(const Common::String &name) { bool r = _textResource->open(name); if (!r) { error("Failed to load dialogue menu text"); @@ -104,15 +100,15 @@ bool DialogueMenu::clearList() { } bool DialogueMenu::addToList(int answer, bool done, int priorityPolite, int priorityNormal, int prioritySurly) { - if (_listSize >= 10) { + if (_listSize >= kMaxItems) { return false; } if (getAnswerIndex(answer) != -1) { return false; } - const char *text = _textResource->getText(answer); - if (!text || strlen(text) >= 50) { + const Common::String &text = _textResource->getText(answer); + if (text.empty() || text.size() >= 50) { return false; } @@ -145,8 +141,9 @@ bool DialogueMenu::addToListNeverRepeatOnceSelected(int answer, int priorityPoli } int DialogueMenu::queryInput() { - if (!_isVisible || _listSize == 0) + if (!_isVisible || _listSize == 0) { return -1; + } int answer = -1; if (_listSize == 1) { @@ -230,15 +227,15 @@ int DialogueMenu::queryInput() { return answer; } -int DialogueMenu::listSize() { +int DialogueMenu::listSize() const { return _listSize; } -bool DialogueMenu::isVisible() { +bool DialogueMenu::isVisible() const { return _isVisible; } -bool DialogueMenu::isOpen() { +bool DialogueMenu::isOpen() const { return _isVisible || _waitingForInput; } @@ -247,7 +244,7 @@ void DialogueMenu::tick(int x, int y) { return; } - int line = (y - (_screenY + BORDER_SIZE)) / LINE_HEIGHT; + int line = (y - (_screenY + kBorderSize)) / kLineHeight; line = CLIP(line, 0, _listSize - 1); _selectedItemIndex = line; @@ -289,13 +286,13 @@ void DialogueMenu::draw(Graphics::Surface &s) { const int x1 = _screenX; const int y1 = _screenY; - const int x2 = _screenX + BORDER_SIZE + _maxItemWidth; - const int y2 = _screenY + BORDER_SIZE + _listSize * LINE_HEIGHT; + const int x2 = _screenX + kBorderSize + _maxItemWidth; + const int y2 = _screenY + kBorderSize + _listSize * kLineHeight; darkenRect(s, x1 + 8, y1 + 8, x2 + 2, y2 + 2); - int x = x1 + BORDER_SIZE; - int y = y1 + BORDER_SIZE; + int x = x1 + kBorderSize; + int y = y1 + kBorderSize; Common::Point mouse = _vm->getMousePos(); if (mouse.x >= x && mouse.x < x2) { @@ -315,7 +312,7 @@ void DialogueMenu::draw(Graphics::Surface &s) { _shapes[4].draw(s, x2, y); uint16 color = ((_items[i].colorIntensity >> 1) << 10) | ((_items[i].colorIntensity >> 1) << 6) | _items[i].colorIntensity; _vm->_mainFont->drawColor(_items[i].text, s, x, y, color); - y += LINE_HEIGHT; + y += kLineHeight; } for (; x != x2; ++x) { _shapes[6].draw(s, x, y1); @@ -323,7 +320,7 @@ void DialogueMenu::draw(Graphics::Surface &s) { } } -int DialogueMenu::getAnswerIndex(int answer) { +int DialogueMenu::getAnswerIndex(int answer) const { for (int i = 0; i != _listSize; ++i) { if (_items[i].answerValue == answer) { return i; @@ -333,7 +330,7 @@ int DialogueMenu::getAnswerIndex(int answer) { return -1; } -const char *DialogueMenu::getText(int id) { +const char *DialogueMenu::getText(int id) const { return _textResource->getText((uint32)id); } @@ -344,8 +341,8 @@ void DialogueMenu::calculatePosition(int unusedX, int unusedY) { } _maxItemWidth += 2; - int w = BORDER_SIZE + _shapes[4].getWidth() + _maxItemWidth; - int h = BORDER_SIZE + _shapes[7].getHeight() + LINE_HEIGHT * _listSize; + int w = kBorderSize + _shapes[4].getWidth() + _maxItemWidth; + int h = kBorderSize + _shapes[7].getHeight() + kLineHeight * _listSize; _screenX = _centerX - w / 2; _screenY = _centerY - h / 2; @@ -361,7 +358,7 @@ void DialogueMenu::mouseUp() { _waitingForInput = false; } -bool DialogueMenu::waitingForInput() { +bool DialogueMenu::waitingForInput() const { return _waitingForInput; } @@ -370,7 +367,7 @@ void DialogueMenu::clear() { _waitingForInput = false; _selectedItemIndex = 0; _listSize = 0; - for (int i = 0; i != 10; ++i) { + for (int i = 0; i != kMaxItems; ++i) { _items[i].text.clear(); _items[i].answerValue = -1; _items[i].isDone = 0; @@ -380,7 +377,7 @@ void DialogueMenu::clear() { _items[i].colorIntensity = 0; } _neverRepeatListSize = 0; - for (int i = 0; i != 100; ++i) { + for (int i = 0; i != kMaxRepeatHistory; ++i) { _neverRepeatValues[i] = -1; _neverRepeatWasSelected[i] = false; } @@ -402,7 +399,7 @@ void DialogueMenu::darkenRect(Graphics::Surface &s, int x1, int y1, int x2, int if (x1 < x2 && y1 < y2) { for (int y = y1; y != y2; ++y) { for (int x = x1; x != x2; ++x) { - uint16 *p = (uint16*)s.getBasePtr(x, y); + uint16 *p = (uint16 *)s.getBasePtr(x, y); *p = (*p & 0x739C) >> 1; // 0 11100 11100 11100 } } diff --git a/engines/bladerunner/dialogue_menu.h b/engines/bladerunner/dialogue_menu.h index 61ddcf1ae0..63e23d8ada 100644 --- a/engines/bladerunner/dialogue_menu.h +++ b/engines/bladerunner/dialogue_menu.h @@ -35,17 +35,22 @@ namespace BladeRunner { class BladeRunnerEngine; class TextResource; -struct DialogueItem { - Common::String text; - int answerValue; - int colorIntensity; - int priorityPolite; - int priorityNormal; - int prioritySurly; - int isDone; -}; - class DialogueMenu { + static const int kMaxItems = 10; + static const int kMaxRepeatHistory = 100; + static const int kLineHeight = 9; + static const int kBorderSize = 10; + + struct DialogueItem { + Common::String text; + int answerValue; + int colorIntensity; + int priorityPolite; + int priorityNormal; + int prioritySurly; + int isDone; + }; + BladeRunnerEngine *_vm; TextResource *_textResource; @@ -58,15 +63,15 @@ class DialogueMenu { // These track whether a dialogue option // has previously been selected int _neverRepeatListSize; - int _neverRepeatValues[100]; - bool _neverRepeatWasSelected[100]; + int _neverRepeatValues[kMaxRepeatHistory]; + bool _neverRepeatWasSelected[kMaxRepeatHistory]; int _centerX; int _centerY; int _screenX; int _screenY; int _maxItemWidth; - DialogueItem _items[10]; + DialogueItem _items[kMaxItems]; int _fadeInItemIndex; @@ -74,7 +79,7 @@ public: DialogueMenu(BladeRunnerEngine *vm); ~DialogueMenu(); - bool loadText(const char *name); + bool loadText(const Common::String &name); bool show(); bool hide(); @@ -82,22 +87,21 @@ public: bool addToListNeverRepeatOnceSelected(int answer, int priorityPolite, int priorityNormal, int prioritySurly); bool clearList(); int queryInput(); - int listSize(); - bool isVisible(); - bool isOpen(); + int listSize() const; + bool isVisible() const; + bool isOpen() const; void tick(int x, int y); void draw(Graphics::Surface &s); void mouseUp(); - bool waitingForInput(); + bool waitingForInput() const; private: bool showAt(int x, int y); - int getAnswerIndex(int answer); - const char *getText(int id); + int getAnswerIndex(int answer) const; + const char *getText(int id) const; void calculatePosition(int unusedX = 0, int unusedY = 0); - void clear(); void reset(); diff --git a/engines/bladerunner/fog.cpp b/engines/bladerunner/fog.cpp index 73e802667f..06166bb30b 100644 --- a/engines/bladerunner/fog.cpp +++ b/engines/bladerunner/fog.cpp @@ -45,24 +45,24 @@ int Fog::readCommon(Common::ReadStream *stream) { void Fog::readAnimationData(Common::ReadStream *stream, int size) { _animatedParameters = stream->readUint32LE(); - int floatsCount = size / 4; - _animationData = new float[floatsCount]; - for (int i = 0; i < floatsCount; i++) { + int floatCount = size / 4; + _animationData = new float[floatCount]; + for (int i = 0; i < floatCount; i++) { _animationData[i] = stream->readFloatLE(); } _m11ptr = _animationData; - _m12ptr = _m11ptr + (_animatedParameters & 0x1 ? _framesCount : 1); - _m13ptr = _m12ptr + (_animatedParameters & 0x2 ? _framesCount : 1); - _m14ptr = _m13ptr + (_animatedParameters & 0x4 ? _framesCount : 1); - _m21ptr = _m14ptr + (_animatedParameters & 0x08 ? _framesCount : 1); - _m22ptr = _m21ptr + (_animatedParameters & 0x10 ? _framesCount : 1); - _m23ptr = _m22ptr + (_animatedParameters & 0x20 ? _framesCount : 1); - _m24ptr = _m23ptr + (_animatedParameters & 0x40 ? _framesCount : 1); - _m31ptr = _m24ptr + (_animatedParameters & 0x80 ? _framesCount : 1); - _m32ptr = _m31ptr + (_animatedParameters & 0x100 ? _framesCount : 1); - _m33ptr = _m32ptr + (_animatedParameters & 0x200 ? _framesCount : 1); - _m34ptr = _m33ptr + (_animatedParameters & 0x400 ? _framesCount : 1); + _m12ptr = _m11ptr + (_animatedParameters & 0x1 ? _frameCount : 1); + _m13ptr = _m12ptr + (_animatedParameters & 0x2 ? _frameCount : 1); + _m14ptr = _m13ptr + (_animatedParameters & 0x4 ? _frameCount : 1); + _m21ptr = _m14ptr + (_animatedParameters & 0x08 ? _frameCount : 1); + _m22ptr = _m21ptr + (_animatedParameters & 0x10 ? _frameCount : 1); + _m23ptr = _m22ptr + (_animatedParameters & 0x20 ? _frameCount : 1); + _m24ptr = _m23ptr + (_animatedParameters & 0x40 ? _frameCount : 1); + _m31ptr = _m24ptr + (_animatedParameters & 0x80 ? _frameCount : 1); + _m32ptr = _m31ptr + (_animatedParameters & 0x100 ? _frameCount : 1); + _m33ptr = _m32ptr + (_animatedParameters & 0x200 ? _frameCount : 1); + _m34ptr = _m33ptr + (_animatedParameters & 0x400 ? _frameCount : 1); setupFrame(0); } @@ -71,7 +71,7 @@ void Fog::reset() { } void Fog::setupFrame(int frame) { - int offset = frame % _framesCount; + int offset = frame % _frameCount; _matrix._m[0][0] = (_animatedParameters & 0x1 ? _m11ptr[offset] : *_m11ptr); _matrix._m[0][1] = (_animatedParameters & 0x2 ? _m12ptr[offset] : *_m12ptr); _matrix._m[0][2] = (_animatedParameters & 0x4 ? _m13ptr[offset] : *_m13ptr); @@ -87,8 +87,8 @@ void Fog::setupFrame(int frame) { _inverted = invertMatrix(_matrix); } -void FogCone::read(Common::ReadStream *stream, int framesCount) { - _framesCount = framesCount; +void FogCone::read(Common::ReadStream *stream, int frameCount) { + _frameCount = frameCount; int size = readCommon(stream); _parameter1 = stream->readFloatLE(); readAnimationData(stream, size - 52); @@ -133,8 +133,8 @@ void FogCone::calculateCoeficient(Vector3 position, Vector3 viewPosition, float } } -void FogSphere::read(Common::ReadStream *stream, int framesCount) { - _framesCount = framesCount; +void FogSphere::read(Common::ReadStream *stream, int frameCount) { + _frameCount = frameCount; int size = readCommon(stream); _parameter1 = stream->readFloatLE(); readAnimationData(stream, size - 52); @@ -261,8 +261,8 @@ void FogSphere::calculateCoeficient(Vector3 position, Vector3 viewPosition, floa } } -void FogBox::read(Common::ReadStream *stream, int framesCount) { - _framesCount = framesCount; +void FogBox::read(Common::ReadStream *stream, int frameCount) { + _frameCount = frameCount; int size = readCommon(stream); _parameter1 = stream->readFloatLE(); _parameter2 = stream->readFloatLE(); diff --git a/engines/bladerunner/fog.h b/engines/bladerunner/fog.h index 445308d540..95ac550fd1 100644 --- a/engines/bladerunner/fog.h +++ b/engines/bladerunner/fog.h @@ -39,7 +39,7 @@ class Fog { protected: char _name[20]; - int _framesCount; + int _frameCount; int _animatedParameters; Matrix4x3 _matrix; Matrix4x3 _inverted; @@ -69,7 +69,7 @@ public: Fog(); virtual ~Fog(); - virtual void read(Common::ReadStream *stream, int framesCount) = 0; + virtual void read(Common::ReadStream *stream, int frameCount) = 0; virtual void calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient) = 0; void reset(); @@ -82,17 +82,17 @@ protected: }; class FogCone : public Fog { - void read(Common::ReadStream *stream, int framesCount); + void read(Common::ReadStream *stream, int frameCount); void calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient); }; class FogSphere : public Fog { - void read(Common::ReadStream *stream, int framesCount); + void read(Common::ReadStream *stream, int frameCount); void calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient); }; class FogBox : public Fog { - void read(Common::ReadStream *stream, int framesCount); + void read(Common::ReadStream *stream, int frameCount); void calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient); }; diff --git a/engines/bladerunner/font.cpp b/engines/bladerunner/font.cpp index 2f56b3f12d..3af8fc2f7f 100644 --- a/engines/bladerunner/font.cpp +++ b/engines/bladerunner/font.cpp @@ -28,7 +28,8 @@ namespace BladeRunner { -Font::Font(BladeRunnerEngine *vm) : _vm(vm) { +Font::Font(BladeRunnerEngine *vm) { + _vm = vm; reset(); } @@ -62,11 +63,11 @@ bool Font::open(const Common::String &fileName, int screenWidth, int screenHeigh } for (int i = 0; i < _characterCount; i++) { - _characters[i]._x = stream->readUint32LE(); - _characters[i]._y = stream->readUint32LE(); - _characters[i]._width = stream->readUint32LE(); - _characters[i]._height = stream->readUint32LE(); - _characters[i]._dataOffset = stream->readUint32LE(); + _characters[i].x = stream->readUint32LE(); + _characters[i].y = stream->readUint32LE(); + _characters[i].width = stream->readUint32LE(); + _characters[i].height = stream->readUint32LE(); + _characters[i].dataOffset = stream->readUint32LE(); } for (int i = 0; i < _dataSize; i++) { _data[i] = stream->readUint16LE(); @@ -95,7 +96,7 @@ void Font::setColor(uint16 color) { } } -void Font::draw(const Common::String &text, Graphics::Surface &surface, int x, int y) { +void Font::draw(const Common::String &text, Graphics::Surface &surface, int x, int y) const { if (!_data) { return; } @@ -106,7 +107,7 @@ void Font::draw(const Common::String &text, Graphics::Surface &surface, int x, i const char *character = text.c_str(); while (*character != 0) { drawCharacter(*character, surface, x, y); - x += _spacing1 + _characters[*character + 1]._width; + x += _spacing1 + _characters[*character + 1].width; character++; } @@ -119,7 +120,7 @@ void Font::drawColor(const Common::String &text, Graphics::Surface &surface, int draw(text, surface, x, y); } -int Font::getTextWidth(const Common::String &text) { +int Font::getTextWidth(const Common::String &text) const { const char *character = text.c_str(); if (!_data) { @@ -130,13 +131,13 @@ int Font::getTextWidth(const Common::String &text) { return 0; } while (*character != 0) { - totalWidth += _spacing1 + _characters[*character + 1]._width; + totalWidth += _spacing1 + _characters[*character + 1].width; character++; } return totalWidth - _spacing1; } -int Font::getTextHeight(const Common::String &text) { +int Font::getTextHeight(const Common::String &text) const { return _maxHeight; } @@ -153,7 +154,7 @@ void Font::reset() { _color = 0x7FFF; _intersperse = 0; - memset(_characters, 0, 256 * sizeof(FontCharacter)); + memset(_characters, 0, 256 * sizeof(Character)); } void Font::replaceColor(uint16 oldColor, uint16 newColor) { @@ -167,16 +168,16 @@ void Font::replaceColor(uint16 oldColor, uint16 newColor) { } } -void Font::drawCharacter(const char character, Graphics::Surface &surface, int x, int y) { +void Font::drawCharacter(const char character, Graphics::Surface &surface, int x, int y) const { uint8 characterIndex = (uint8)character + 1; if (x < 0 || x >= _screenWidth || y < 0 || y >= _screenHeight || !_data || characterIndex >= _characterCount) { return; } - uint16 *dstPtr = (uint16*)surface.getBasePtr(x + _characters[characterIndex]._x, y + _characters[characterIndex]._y); - uint16 *srcPtr = &_data[_characters[characterIndex]._dataOffset]; - int width = _characters[characterIndex]._width; - int height = _characters[characterIndex]._height; + uint16 *dstPtr = (uint16 *)surface.getBasePtr(x + _characters[characterIndex].x, y + _characters[characterIndex].y); + uint16 *srcPtr = &_data[_characters[characterIndex].dataOffset]; + int width = _characters[characterIndex].width; + int height = _characters[characterIndex].height; if (_intersperse && y & 1) { dstPtr += surface.pitch / 2; } @@ -203,4 +204,5 @@ void Font::drawCharacter(const char character, Graphics::Surface &surface, int x currentY++; } } + } // End of namespace BladeRunner diff --git a/engines/bladerunner/font.h b/engines/bladerunner/font.h index 91a8184e4b..e51a3deb2d 100644 --- a/engines/bladerunner/font.h +++ b/engines/bladerunner/font.h @@ -33,21 +33,21 @@ namespace BladeRunner { class BladeRunnerEngine; -struct FontCharacter { - int _x; - int _y; - int _width; - int _height; - int _dataOffset; -}; - class Font { + struct Character { + int x; + int y; + int width; + int height; + int dataOffset; + }; + BladeRunnerEngine *_vm; int _characterCount; int _maxWidth; int _maxHeight; - FontCharacter _characters[256]; + Character _characters[256]; int _dataSize; uint16 *_data; int _screenWidth; @@ -67,17 +67,17 @@ public: void setSpacing(int spacing1, int spacing2); void setColor(uint16 color); - void draw(const Common::String &text, Graphics::Surface &surface, int x, int y); + void draw(const Common::String &text, Graphics::Surface &surface, int x, int y) const; void drawColor(const Common::String &text, Graphics::Surface &surface, int x, int y, uint16 color); - int getTextWidth(const Common::String &text); - int getTextHeight(const Common::String &text); + int getTextWidth(const Common::String &text) const; + int getTextHeight(const Common::String &text) const; private: void reset(); void replaceColor(uint16 oldColor, uint16 newColor); - void drawCharacter(const char character, Graphics::Surface &surface, int x, int y); + void drawCharacter(const char character, Graphics::Surface &surface, int x, int y) const; }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/game_constants.h b/engines/bladerunner/game_constants.h new file mode 100644 index 0000000000..043a07ff91 --- /dev/null +++ b/engines/bladerunner/game_constants.h @@ -0,0 +1,463 @@ +/* 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_GAME_CONSTANTS_H +#define BLADERUNNER_GAME_CONSTANTS_H + +namespace BladeRunner { + +enum Actors { + kActorMcCoy = 0, + kActorSteele = 1, + kActorGordo = 2, + kActorDektora = 3, + kActorGuzza = 4, + kActorClovis = 5, + kActorLucy = 6, + kActorIzo = 7, + kActorSadik = 8, + kActorCrazylegs = 9, + kActorLuther = 10, + kActorGrigorian = 11, + kActorTransient = 12, + kActorLance = 13, + kActorBulletBob = 14, + kActorRunciter = 15, + kActorInsectDealer = 16, + kActorTyrellGuard = 17, + kActorEarlyQ = 18, + kActorZuben = 19, + kActorHasan = 20, + kActorMarcus = 21, + kActorMia = 22, + kActorOfficerLeary = 23, + kActorOfficerGrayford = 24, + kActorHanoi = 25, + kActorBaker = 26, + kActorDeskClerk = 27, + kActorHowieLee = 28, + kActorFishDealer = 29, + kActorKlein = 30, + kActorMurray = 31, + kActorHawkersBarkeep = 32, + kActorHolloway = 33, + kActorSergeantWalls = 34, + kActorMoraji = 35, + kActorTheBard = 36, + kActorPhotographer = 37, + kActorDispatcher = 38, + kActorAnsweringMachine = 39, + kActorRajif = 40, + kActorGovernorKolvig = 41, + kActorEarlyQBartender = 42, + kActorHawkersParrot = 43, + kActorTaffyPatron = 44, + kActorLockupGuard = 45, + kActorTeenager = 46, + kActorHysteriaPatron1 = 47, + kActorHysteriaPatron2 = 48, + kActorHysteriaPatron3 = 49, + kActorShoeshineMan = 50, + kActorTyrell = 51, + kActorChew = 52, + kActorGaff = 53, + kActorBryant = 54, + kActorTaffy = 55, + kActorSebastian = 56, + kActorRachael = 57, + kActorGeneralDoll = 58, + kActorIsabella = 59, + kActorBlimpGuy = 60, + kActorNewscaster = 61, + kActorLeon = 62, + kActorMaleAnnouncer = 63, + kActorFreeSlotA = 64, + kActorFreeSlotB = 65, + kActorMaggie = 66, + kActorGenwalkerA = 67, + kActorGenwalkerB = 68, + kActorGenwalkerC = 69, + kActorMutant1 = 70, + kActorMutant2 = 71, + kActorMutant3 = 72, + kActorVoiceOver = 99 +}; + +enum Clues { + kClueOfficersStatement = 0, + kClueDoorForced1 = 1, + kClueDoorForced2 = 2, + kClueLimpingFootprints = 3, + kClueGracefulFootprints = 4, + kClueShellCasings = 5, + kClueCandy = 6, + kClueToyDog = 7, + kClueChopstickWrapper = 8, + kClueSushiMenu = 9, + kClueLabCorpses = 10, + kClueLabShellCasings = 11, + kClueRuncitersVideo = 12, + kClueLucy = 13, + kClueDragonflyAnklet = 14, + kClueReferenceLetter = 15, + kClueCrowdInterviewA = 16, + kClueCrowdInterviewB = 17, + kClueZubenRunsAway = 18, + kClueZubenInterview = 19, + kClueZuben = 20, + kClueBigManLimping = 21, + kClueRunciterInterviewA = 22, + kClueRunciterInterviewB1 = 23, + kClueRunciterInterviewB2 = 24, + kClueHowieLeeInterview = 25, + kCluePaintTransfer = 26, + kClueChromeDebris = 27, + kClueRuncitersViewA = 28, + kClueRuncitersViewB = 29, + kClueCarColorAndMake = 30, + kCluePartialLicenseNumber = 31, + kClueBriefcase = 32, + kClueGaffsInformation = 33, + kClueCrystalVisitedRunciters = 34, + kClueCrystalVisitedChinatown = 35, + kClueWantedPoster = 36, + kClueLicensePlate = 37, + kClueLicensePlateMatch = 38, + kClueLabPaintTransfer = 39, + kClueDispatchHitAndRun = 40, + kClueInceptShotRoy = 41, + kClueInceptShotsLeon = 42, + kCluePhoneCallGuzza = 43, + kClueDragonflyEarring = 44, + kClueTyrellSecurity = 45, + kClueTyrellGuardInterview = 46, + kClueBombingSuspect = 47, + kClueSadiksGun = 48, + kClueDetonatorWire = 49, + kClueVictimInformation = 50, + kClueAttemptedFileAccess = 51, + kClueCrystalsCase = 52, + kClueKingstonKitchenBox1 = 53, + kClueTyrellSalesPamphlet1 = 54, + kClueTyrellSalesPamphlet2 = 55, + kCluePeruvianLadyInterview = 56, + kClueHasanInterview = 57, + kClueBobInterview1 = 58, + kClueBobInterview2 = 59, + kClueIzoInterview = 60, + kClueIzosWarning = 61, + kClueRadiationGoggles = 62, + kClueGogglesReplicantIssue = 63, + kClueFishLadyInterview = 64, + kClueDogCollar1 = 65, + kClueWeaponsCache = 66, + kClueChewInterview = 67, + kClueMorajiInterview = 68, + kClueGordoInterview1 = 69, + kClueGordoInterview2 = 70, + kClueAnsweringMachineMessage = 71, + kClueChessTable = 72, + kClueSightingSadikBradbury = 73, + kClueStaggeredbyPunches = 74, + kClueMaggieBracelet = 75, + kClueEnvelope = 76, + kClueIzosFriend = 77, + kClueChinaBarSecurityPhoto = 78, + kCluePurchasedScorpions = 79, + kClueWeaponsOrderForm = 80, + kClueShippingForm = 81, + kClueGuzzasCash = 82, + kCluePoliceIssueWeapons = 83, + kClueHysteriaToken = 84, + kClueRagDoll = 85, + kClueMoonbus1 = 86, + kClueCheese = 87, + kClueDektorasDressingRoom = 88, + kClueEarlyQsClub = 89, + kClueDragonflyCollection = 90, + kClueDragonflyBelt = 91, + kClueEarlyQInterview = 92, + kClueStrangeScale1 = 93, + kClueDektoraInterview1 = 94, + kClueSuspectDektora = 95, + kClueDektoraInterview2 = 96, + kClueDektoraInterview3 = 97, + kClueDektorasCard = 98, + kClueGrigoriansNote = 99, + kClueCollectionReceipt = 100, + kClueSpecialIngredient = 101, + kClueStolenCheese = 102, + kClueGordoInterview3 = 103, + kClueGordoConfession = 104, + kClueGordosLighter1 = 105, + kClueGordosLighter2 = 106, + kClueDektoraInterview4 = 107, + kClueHollowayInterview = 108, + kClueBakersBadge = 109, + kClueHoldensBadge = 110, + kClueCar = 111, + kClueCarIdentified = 112, + kClueCarRegistration1 = 113, + kClueCarRegistration2 = 114, + kClueCarRegistration3 = 115, + kClueCrazylegsInterview1 = 116, + kClueCrazylegsInterview2 = 117, + kClueLichenDogWrapper = 118, + kClueRequisitionForm = 119, + kClueScaryChair = 120, + kClueIzosStashRaided = 121, + kClueHomelessManInterview1 = 122, + kClueHomelessManInterview2 = 123, + kClueHomelessManKid = 124, + kClueFolder = 125, + kClueGuzzaFramedMcCoy = 126, + kClueOriginalShippingForm = 127, + kClueOriginalRequisitionForm = 128, + kClueCandyWrapper = 129, + kClueGordoBlabs = 130, + kClueFlaskOfAbsinthe = 131, + kClueGuzzaAgreesToMeet = 132, + kClueDektoraConfession = 133, + kClueRunciterConfession1 = 134, + kClueRunciterConfession2 = 135, + kClueLutherLanceInterview = 136, + kClueMoonbus2 = 137, + kClueMoonbusCloseup = 138, + kCluePhoneCallDektora1 = 139, + kCluePhoneCallDektora2 = 140, + kCluePhoneCallLucy1 = 141, + kCluePhoneCallLucy2 = 142, + kCluePhoneCallClovis = 143, + kCluePhoneCallCrystal = 144, + kCluePowerSource = 145, + kClueBomb = 146, + kClueDNATyrell = 147, + kClueDNASebastian = 148, + kClueDNAChew = 149, + kClueDNAMoraji = 150, + kClueDNALutherLance = 151, + kClueDNAMarcus = 152, + kClueGarterSnake = 153, + kClueSlug = 154, + kClueGoldfish = 155, + kClueZubenTalksAboutLucy1 = 156, + kClueZubenTalksAboutLucy2 = 157, + kClueZubensMotive = 158, + kClueSightingBulletBob = 159, + kClueSightingClovis = 160, + kClueSightingDektora = 161, + kClueVKDektoraReplicant = 162, + kClueVKDektoraHuman = 163, + kClueVKBobGorskyReplicant = 164, + kClueVKBobGorskyHuman = 165, + kClueVKLutherLanceReplicant = 166, + kClueVKLutherLanceHuman = 167, + kClueVKGrigorianReplicant = 168, + kClueVKGrigorianHuman = 169, + kClueVKIzoReplicant = 170, + kClueVKIzoHuman = 171, + kClueVKCrazylegsReplicant = 172, + kClueVKCrazylegsHuman = 173, + kClueVKRunciterReplicant = 174, + kClueVKRunciterHuman = 175, + kClueVKEarlyQReplicant = 176, + kClueVKEarlyQHuman = 177, + kClueCrimeSceneNotes = 178, + kClueGrigorianInterviewA = 179, + kClueGrigorianInterviewB1 = 180, + kClueGrigorianInterviewB2 = 181, + kClueLabAnalysisGoldChain = 182, + kClueSightingZuben = 183, + kClueCrystalRetiredZuben = 184, + kClueCrystalRetiredGordo = 185, + kClueSightingGordo = 186, + kClueCrystalRetiredIzo = 187, + kClueClovisIncept = 188, + kClueDektoraIncept = 189, + kClueLucyIncept = 190, + kClueGordoIncept = 191, + kClueIzoIncept = 192, + kClueSadikIncept = 193, + kClueZubenIncept = 194, + kClueMcCoyIncept = 195, + kClueWarRecordsGordoFrizz = 196, + kCluePoliceWeaponUsed = 197, + kClueMcCoysWeaponUsedonBob = 198, + kClueBobRobbed = 199, + kClueBobShotInSelfDefense = 200, + kClueBobShotInColdBlood = 201, + kClueMcCoyRecoveredHoldensBadge = 202, + kClueCrystalTestedBulletBob = 203, + kClueCrystalRetiredBob = 204, + kClueCrystalTestedCrazylegs = 205, + kClueCrystalRetiredCrazylegs = 206, + kClueCrystalArrestedCrazylegs = 207, + kClueCrystalTestedRunciter = 208, + kClueCrystalRetiredRunciter1 = 209, + kClueCrystalRetiredRunciter2 = 210, + kClueSightingMcCoyRuncitersShop = 211, + kClueMcCoyKilledRunciter1 = 212, + kClueMcCoysDescription = 213, + kClueMcCoyIsABladeRunner = 214, + kClueMcCoyLetZubenEscape = 215, + kClueMcCoyWarnedIzo = 216, + kClueMcCoyHelpedIzoIzoIsAReplicant = 217, + kClueMcCoyHelpedDektora = 218, + kClueMcCoyHelpedLucy = 219, + kClueMcCoyHelpedGordo = 220, + kClueMcCoyShotGuzza = 221, + kClueMcCoyRetiredZuben = 222, + kClueMcCoyRetiredLucy = 223, + kClueMcCoyRetiredDektora = 224, + kClueMcCoyRetiredGordo = 225, + kClueMcCoyRetiredSadik = 226, + kClueMcCoyShotZubenintheback = 227, + kClueMcCoyRetiredLutherLance = 228, + kClueMcCoyBetrayal = 229, + kClueMcCoyKilledRunciter2 = 230, + kClueClovisOrdersMcCoysDeath = 231, + kClueEarlyAttemptedToSeduceLucy = 232, + kClueCarWasStolen = 233, + kClueGrigoriansResponse1 = 234, + kClueGrigoriansResponse2 = 235, + kClueCrazysInvolvement = 236, + kClueGrigoriansResources = 237, + kClueMcCoyPulledAGun = 238, + kClueMcCoyIsStupid = 239, + kClueMcCoyIsAnnoying = 240, + kClueMcCoyIsKind = 241, + kClueMcCoyIsInsane = 242, + kClueAnimalMurderSuspect = 243, + kClueMilitaryBoots = 244, + kClueOuterDressingRoom = 245, + kCluePhotoOfMcCoy1 = 246, + kCluePhotoOfMcCoy2 = 247, + kClueEarlyQAndLucy = 248, + kClueClovisflowers = 249, + kClueLucyWithDektora = 250, + kClueWomanInAnimoidRow = 251, + kClueScorpions = 252, + kClueStrangeScale2 = 253, + kClueChinaBarSecurityCamera = 254, + kClueIzo = 255, + kClueGuzza = 256, + kClueChinaBarSecurityDisc = 257, + kClueScorpionbox = 258, + kClueTyrellSecurityPhoto = 259, + kClueChinaBar = 260, + kCluePlasticExplosive = 261, + kClueDogCollar2 = 262, + kClueKingstonKitchenBox2 = 263, + kClueCrystalsCigarette = 264, + kClueSpinnerKeys = 265, + kClueAct2Ended = 266, + kClueAct3Ended = 267, + kClueAct4Ended = 268, + kClueExpertBomber = 269, + kClueAmateurBomber = 270, + kClueVKLucyReplicant = 271, + kClueVKLucyHuman = 272, + kClueLucyInterview = 273, + kClueMoonbusReflection = 274, + kClueMcCoyAtMoonbus = 275, + kClueClovisAtMoonbus = 276, + kClueSadikAtMoonbus = 277, + kClueRachaelInterview = 278, + kClueTyrellInterview = 279, + kClueRuncitersConfession1 = 280, + kClueRuncitersConfession2 = 281, + kClueRuncitersConfession3 = 282, + kClueEarlyInterviewA = 283, + kClueEarlyInterviewB1 = 284, + kClueEarlyInterviewB2 = 285, + kClueCrazylegsInterview3 = 286, + kClueCrazylegGgrovels = 287 +}; + +enum ClueTypes { + kClueTypePhotograph = 0, + kClueTypeVideoClip = 1, + kClueTypeAudioRecording = 2, + kClueTypeObject = 3 +}; + +enum Crimes { + kCrimeAnimalMurder = 0, + kCrimeEisendullerMurder = 1, + kCrimeArmsDealing = 2, + kCrimeMorajiMurder = 3, + kCrimeBradburyAssault = 4, + kCrimeFactoryBombing = 5, + kCrimeBobMurder = 6, + kCrimeRunciterMurder = 7, + kCrimeMoonbusHijacking = 8 +}; + +enum SpinnerDestinations { + kSpinnerDestinationPoliceStation = 0, + kSpinnerDestinationMcCoysApartment = 1, + kSpinnerDestinationRuncitersAnimals = 2, + kSpinnerDestinationChinatown = 3, + kSpinnerDestinationAnimoidRow = 4, + kSpinnerDestinationTyrellBuilding = 5, + kSpinnerDestinationDNARow = 6, + kSpinnerDestinationBradburyBuilding = 7, + kSpinnerDestinationNightclubRow = 8, + kSpinnerDestinationHysteriaHall = 9 +}; + +enum Flags { + kFlagRC02toRC01 = 9, + kFlagIntroPlayed = 24, + kFlagMA02toMA06 = 33, + kFlagMA06ToMA02 = 34, + kFlagMA02ToMA04 = 35, + kFlagMA04ToMA02 = 36, + kFlagMA01toMA06 = 37, + kFlagMA06toMA01 = 38, + kFlagMA07toMA06 = 57, + kFlagMA06toMA07 = 58, + kFlagMA04toMA05 = 62, + kFlagMA05toMA04 = 63, + kFlagRC03toRC01 = 114, + kFlagRC01PoliceDone = 186, + kFlagMA01Locked = 250, + kFlagDirectorsCut = 378, + kFlagKIAPrivacyAddon = 487, + kFlagKIAPrivacyAddonIntro = 599 +}; + +enum Variables { + kVariableWalkLoopActor = 37, + kVariableWalkLoopRun = 38 +}; + +enum Outtakes { + kOuttakeIntro = 0, + kOuttakeWestwood = 28, + kOuttakeDescent = 33, + kOuttakeBladeRunner = 41 +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/gameflags.cpp b/engines/bladerunner/game_flags.cpp index 261eff9547..81fe6a0a4f 100644 --- a/engines/bladerunner/gameflags.cpp +++ b/engines/bladerunner/game_flags.cpp @@ -20,49 +20,55 @@ * */ -#include "bladerunner/gameflags.h" +#include "bladerunner/game_flags.h" #include "common/debug.h" namespace BladeRunner { GameFlags::GameFlags() - : flags(nullptr), flagCount(0) { + : _flags(nullptr), _flagCount(0) { } GameFlags::~GameFlags() { - delete[] flags; + delete[] _flags; } void GameFlags::setFlagCount(int count) { assert(count > 0); - flagCount = count; - flags = new uint32[count / 32 + 1]; + _flagCount = count; + _flags = new uint32[count / 32 + 1]; - for (int i = 0; i <= flagCount; ++i) + for (int i = 0; i <= _flagCount; ++i) reset(i); } void GameFlags::set(int flag) { +#if BLADERUNNER_DEBUG_CONSOLE debug("GameFlags::set(%d)", flag); - assert(flag >= 0 && flag <= flagCount); +#endif - flags[flag / 32] |= (1 << (flag % 32)); + assert(flag >= 0 && flag <= _flagCount); + + _flags[flag / 32] |= (1 << (flag % 32)); } void GameFlags::reset(int flag) { +#if BLADERUNNER_DEBUG_CONSOLE debug("GameFlags::reset(%d)", flag); - assert(flag >= 0 && flag <= flagCount); +#endif + + assert(flag >= 0 && flag <= _flagCount); - flags[flag / 32] &= ~(1 << (flag % 32)); + _flags[flag / 32] &= ~(1 << (flag % 32)); } -bool GameFlags::query(int flag) { +bool GameFlags::query(int flag) const { //debug("GameFlags::query(%d): %d", flag, !!(flags[flag / 32] & (1 << (flag % 32)))); - assert(flag >= 0 && flag <= flagCount); + assert(flag >= 0 && flag <= _flagCount); - return !!(flags[flag / 32] & (1 << (flag % 32))); + return !!(_flags[flag / 32] & (1 << (flag % 32))); } } // End of namespace BladeRunner diff --git a/engines/bladerunner/gameflags.h b/engines/bladerunner/game_flags.h index ea858191d1..83cbdbc086 100644 --- a/engines/bladerunner/gameflags.h +++ b/engines/bladerunner/game_flags.h @@ -20,16 +20,16 @@ * */ -#ifndef BLADERUNNER_GAMEFLAGS_H -#define BLADERUNNER_GAMEFLAGS_H +#ifndef BLADERUNNER_GAME_FLAGS_H +#define BLADERUNNER_GAME_FLAGS_H -#include <common/scummsys.h> +#include "common/scummsys.h" namespace BladeRunner { class GameFlags { - uint32 *flags; - int flagCount; + uint32 *_flags; + int _flagCount; public: GameFlags(); @@ -39,7 +39,7 @@ public: void set(int flag); void reset(int flag); - bool query(int flag); + bool query(int flag) const; }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/game_info.cpp b/engines/bladerunner/game_info.cpp new file mode 100644 index 0000000000..baffb87428 --- /dev/null +++ b/engines/bladerunner/game_info.cpp @@ -0,0 +1,111 @@ +/* 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/game_info.h" + +#include "bladerunner/bladerunner.h" + +#include "common/debug.h" +#include "common/substream.h" + +namespace BladeRunner { + +GameInfo::GameInfo(BladeRunnerEngine *vm) { + _vm = vm; + _sceneNames = nullptr; + _sfxTracks = nullptr; + _musicTracks = nullptr; + _outtakes = nullptr; +} + +GameInfo::~GameInfo() { + delete[] _sceneNames; + delete[] _sfxTracks; + delete[] _musicTracks; + delete[] _outtakes; +} + +bool GameInfo::open(const Common::String &name) { + Common::SeekableReadStream *s = _vm->getResourceStream(name); + + if (!s) + return false; + + uint32 unk; + _actorCount = s->readUint32LE(); /* 00 */ + _playerId = s->readUint32LE(); /* 01 */ + _flagCount = s->readUint32LE(); /* 02 */ + _clueCount = s->readUint32LE(); /* 03 */ + _globalVarCount = s->readUint32LE(); /* 04 */ + _setNamesCount = s->readUint32LE(); /* 05 */ + _initialSceneId = s->readUint32LE(); /* 06 */ + unk = s->readUint32LE(); /* 07 */ + _initialSetId = s->readUint32LE(); /* 08 */ + unk = s->readUint32LE(); /* 09 */ + _waypointCount = s->readUint32LE(); /* 10 */ + _sfxTrackCount = s->readUint32LE(); /* 11 */ + _musicTrackCount = s->readUint32LE(); /* 12 */ + _outtakeCount = s->readUint32LE(); /* 13 */ + _crimeCount = s->readUint32LE(); /* 14 */ + _suspectCount = s->readUint32LE(); /* 15 */ + _coverWaypointCount = s->readUint32LE(); /* 16 */ + _fleeWaypointCount = s->readUint32LE(); /* 17 */ + + (void)unk; + + _sceneNames = new char[_setNamesCount][5]; + for (uint32 i = 0; i != _setNamesCount; ++i) + s->read(_sceneNames[i], 5); + + _sfxTracks = new char[_sfxTrackCount][13]; + for (uint32 i = 0; i != _sfxTrackCount; ++i) { + s->read(_sfxTracks[i], 9); + strcat(_sfxTracks[i], ".AUD"); + } + + _musicTracks = new char[_musicTrackCount][13]; + for (uint32 i = 0; i != _musicTrackCount; ++i) { + s->read(_musicTracks[i], 9); + strcat(_musicTracks[i], ".AUD"); + } + + _outtakes = new char[_outtakeCount][13]; + for (uint32 i = 0; i != _outtakeCount; ++i) + s->read(_outtakes[i], 9); + + if (false) { + for (uint32 i = 0; i != _setNamesCount; ++i) + debug("%3d: %s", i, _sceneNames[i]); + for (uint32 i = 0; i != _sfxTrackCount; ++i) + debug("%3d: %s", i, _sfxTracks[i]); + for (uint32 i = 0; i != _musicTrackCount; ++i) + debug("%s", _musicTracks[i]); + for (uint32 i = 0; i != _outtakeCount; ++i) + debug("%2d: %s.VQA", i, _outtakes[i]); + } + + bool err = s->err(); + delete s; + return !err; +} + +} // End of namespace BladeRunner diff --git a/engines/bladerunner/game_info.h b/engines/bladerunner/game_info.h new file mode 100644 index 0000000000..f0eec99409 --- /dev/null +++ b/engines/bladerunner/game_info.h @@ -0,0 +1,88 @@ +/* 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_GAME_INFO_H +#define BLADERUNNER_GAME_INFO_H + +#include "common/str.h" + +namespace BladeRunner { + +class BladeRunnerEngine; + +class GameInfo { + BladeRunnerEngine *_vm; + + uint32 _actorCount; + uint32 _playerId; + uint32 _flagCount; + uint32 _clueCount; + uint32 _globalVarCount; + uint32 _setNamesCount; + uint32 _initialSceneId; + uint32 _initialSetId; + uint32 _waypointCount; + uint32 _sfxTrackCount; + uint32 _musicTrackCount; + uint32 _outtakeCount; + uint32 _crimeCount; + uint32 _suspectCount; + uint32 _coverWaypointCount; + uint32 _fleeWaypointCount; + + char (*_sceneNames)[5]; + char (*_sfxTracks)[13]; + char (*_musicTracks)[13]; + char (*_outtakes)[13]; + +public: + GameInfo(BladeRunnerEngine *vm); + ~GameInfo(); + + bool open(const Common::String &name); + + uint32 getActorCount() const { return _actorCount; } + uint32 getPlayerId() const { return _playerId; } + uint32 getFlagCount() const { return _flagCount; } + uint32 getClueCount() const { return _clueCount; } + uint32 getGlobalVarCount() const { return _globalVarCount; } + uint32 getSetNamesCount() const { return _setNamesCount; } + uint32 getInitialSceneId() const { return _initialSceneId; } + uint32 getInitialSetId() const { return _initialSetId; } + uint32 getWaypointCount() const { return _waypointCount; } + uint32 getSfxTrackCount() const { return _sfxTrackCount; } + uint32 getMusicTrackCount() const { return _musicTrackCount; } + uint32 getOuttakeCount() const { return _outtakeCount; } + uint32 getCrimeCount() const { return _crimeCount; } + uint32 getSuspectCount() const { return _suspectCount; } + uint32 getCoverWaypointCount() const { return _coverWaypointCount; } + uint32 getFleeWaypointCount() const { return _fleeWaypointCount; } + + const char *getSceneName(int i) const { return _sceneNames[i]; } + const char *getSfxTrack(int i) const { return _sfxTracks[i]; } + const char *getMusicTrack(int i) const { return _musicTracks[i]; } + const char *getOuttake(int i) const { return _outtakes[i]; } +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/gameinfo.cpp b/engines/bladerunner/gameinfo.cpp deleted file mode 100644 index 487c39d046..0000000000 --- a/engines/bladerunner/gameinfo.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* 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/gameinfo.h" - -#include "bladerunner/bladerunner.h" - -#include "common/debug.h" -#include "common/substream.h" - -namespace BladeRunner { - -GameInfo::GameInfo(BladeRunnerEngine *vm) - : _vm(vm) { - _scene_names = nullptr; - _sfx_tracks = nullptr; - _music_tracks = nullptr; - _outtakes = nullptr; -} - -GameInfo::~GameInfo() { - delete[] _scene_names; - delete[] _sfx_tracks; - delete[] _music_tracks; - delete[] _outtakes; -} - -bool GameInfo::open(const Common::String &name) { - Common::SeekableReadStream *s = _vm->getResourceStream(name); - - if (!s) - return false; - - uint32 unk; - _actor_count = s->readUint32LE(); /* 00 */ - _player_id = s->readUint32LE(); /* 01 */ - _flag_count = s->readUint32LE(); /* 02 */ - _clue_count = s->readUint32LE(); /* 03 */ - _global_var_count = s->readUint32LE(); /* 04 */ - _set_names_count = s->readUint32LE(); /* 05 */ - _initial_scene_id = s->readUint32LE(); /* 06 */ - unk = s->readUint32LE(); /* 07 */ - _initial_set_id = s->readUint32LE(); /* 08 */ - unk = s->readUint32LE(); /* 09 */ - _waypoint_count = s->readUint32LE(); /* 10 */ - _sfx_track_count = s->readUint32LE(); /* 11 */ - _music_track_count = s->readUint32LE(); /* 12 */ - _outtake_count = s->readUint32LE(); /* 13 */ - unk = s->readUint32LE(); /* 14 */ - _suspectsDatabaseSize = s->readUint32LE(); /* 15 */ - _cover_waypoint_count = s->readUint32LE(); /* 16 */ - _flee_waypoint_count = s->readUint32LE(); /* 17 */ - - (void)unk; - - _scene_names = new char[_set_names_count][5]; - for (uint32 i = 0; i != _set_names_count; ++i) - s->read(_scene_names[i], 5); - - _sfx_tracks = new char[_sfx_track_count][13]; - for (uint32 i = 0; i != _sfx_track_count; ++i) { - s->read(_sfx_tracks[i], 9); - strcat(_sfx_tracks[i], ".AUD"); - } - - _music_tracks = new char[_music_track_count][13]; - for (uint32 i = 0; i != _music_track_count; ++i) { - s->read(_music_tracks[i], 9); - strcat(_music_tracks[i], ".AUD"); - } - - _outtakes = new char[_outtake_count][13]; - for (uint32 i = 0; i != _outtake_count; ++i) - s->read(_outtakes[i], 9); - - if (false) { - for (uint32 i = 0; i != _set_names_count; ++i) - debug("%3d: %s", i, _scene_names[i]); - for (uint32 i = 0; i != _sfx_track_count; ++i) - debug("%3d: %s", i, _sfx_tracks[i]); - for (uint32 i = 0; i != _music_track_count; ++i) - debug("%s", _music_tracks[i]); - for (uint32 i = 0; i != _outtake_count; ++i) - debug("%2d: %s.VQA", i, _outtakes[i]); - } - - bool err = s->err(); - delete s; - return !err; -} - -} // End of namespace BladeRunner diff --git a/engines/bladerunner/gameinfo.h b/engines/bladerunner/gameinfo.h deleted file mode 100644 index 6f9aab5c20..0000000000 --- a/engines/bladerunner/gameinfo.h +++ /dev/null @@ -1,88 +0,0 @@ -/* 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_GAMEINFO_H -#define BLADERUNNER_GAMEINFO_H - -#include "common/str.h" - -#include "common/str.h" - -namespace BladeRunner { - -class BladeRunnerEngine; - -class GameInfo { - BladeRunnerEngine *_vm; - - uint32 _actor_count; - uint32 _player_id; - uint32 _flag_count; - uint32 _clue_count; - uint32 _global_var_count; - uint32 _set_names_count; - uint32 _initial_scene_id; - uint32 _initial_set_id; - uint32 _waypoint_count; - uint32 _sfx_track_count; - uint32 _music_track_count; - uint32 _outtake_count; - uint32 _suspectsDatabaseSize; - uint32 _cover_waypoint_count; - uint32 _flee_waypoint_count; - - char (*_scene_names)[5]; - char (*_sfx_tracks)[13]; - char (*_music_tracks)[13]; - char (*_outtakes)[13]; - -public: - GameInfo(BladeRunnerEngine *vm); - ~GameInfo(); - - bool open(const Common::String &name); - - uint32 getActorCount() { return _actor_count; } - uint32 getPlayerId() { return _player_id; } - uint32 getFlagCount() { return _flag_count; } - uint32 getClueCount() { return _clue_count; } - uint32 getGlobalVarCount() { return _global_var_count; } - uint32 getSetNamesCount() { return _set_names_count; } - uint32 getInitialSceneId() { return _initial_scene_id; } - uint32 getInitialSetId() { return _initial_set_id; } - uint32 getWaypointCount() { return _waypoint_count; } - uint32 getSfxTrackCount() { return _sfx_track_count; } - uint32 getMusicTrackCount() { return _music_track_count; } - uint32 getOuttakeCount() { return _outtake_count; } - uint32 getSuspectsDatabaseSize() { return _suspectsDatabaseSize; } - uint32 getCoverWaypointCount() { return _cover_waypoint_count; } - uint32 getFleeWaypointCount() { return _flee_waypoint_count; } - - const char *getSceneName(int i) { return _scene_names[i]; } - const char *getSfxTrack(int i) { return _sfx_tracks[i]; } - const char *getMusicTrack(int i) { return _music_tracks[i]; } - const char *getOuttake(int i) { return _outtakes[i]; } -}; - -} // End of namespace BladeRunner - -#endif diff --git a/engines/bladerunner/image.cpp b/engines/bladerunner/image.cpp index 1a23823b31..cc11e5b956 100644 --- a/engines/bladerunner/image.cpp +++ b/engines/bladerunner/image.cpp @@ -30,8 +30,8 @@ namespace BladeRunner { -Image::Image(BladeRunnerEngine *vm) - : _vm(vm) { +Image::Image(BladeRunnerEngine *vm) { + _vm = vm; } Image::~Image() { @@ -64,7 +64,7 @@ bool Image::open(const Common::String &name) { if (strcmp(tag, "LZO") == 0) { debug("LZO"); } else if (strcmp(tag, "LCW") == 0) { - decompress_lcw(buf, bufSize, (uint8*)data, dataSize); + decompress_lcw(buf, bufSize, (uint8 *)data, dataSize); } const Graphics::PixelFormat pixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); diff --git a/engines/bladerunner/item.cpp b/engines/bladerunner/item.cpp index 0b84aae30c..eafc99c80f 100644 --- a/engines/bladerunner/item.cpp +++ b/engines/bladerunner/item.cpp @@ -58,21 +58,18 @@ Item::Item(BladeRunnerEngine *vm) { _screenRectangle.left = -1; } -Item::~Item() { -} - -void Item::getXYZ(float *x, float *y, float *z) { +void Item::getXYZ(float *x, float *y, float *z) const { *x = _position.x; *y = _position.y; *z = _position.z; } -void Item::getWidthHeight(int *width, int *height) { +void Item::getWidthHeight(int *width, int *height) const { *width = _width; *height = _height; } -bool Item::isTargetable() { +bool Item::isTargetable() const { return _isTargetable; } @@ -86,7 +83,7 @@ bool Item::tick(Common::Rect *screenRect, bool special) { Vector3 position(_position.x, -_position.z, _position.y); int animationId = _animationId + (special ? 1 : 0); - _vm->_sliceRenderer->drawInWorld(animationId, 0, position, M_PI - _angle, 1.0f, _vm->_surfaceGame, _vm->_zbuffer->getData()); + _vm->_sliceRenderer->drawInWorld(animationId, 0, position, M_PI - _angle, 1.0f, _vm->_surfaceFront, _vm->_zbuffer->getData()); _vm->_sliceRenderer->getScreenRectangle(&_screenRectangle, animationId, 0, position, M_PI - _angle, 1.0f); if (!_screenRectangle.isEmpty()) { diff --git a/engines/bladerunner/item.h b/engines/bladerunner/item.h index 76d49ac614..e14aaa5c4f 100644 --- a/engines/bladerunner/item.h +++ b/engines/bladerunner/item.h @@ -34,11 +34,10 @@ class BladeRunnerEngine; class Items; class Item { - BladeRunnerEngine *_vm; - friend class Items; -private: + BladeRunnerEngine *_vm; + int _itemId; int _setId; @@ -61,13 +60,12 @@ private: public: Item(BladeRunnerEngine *vm); - ~Item(); - void getXYZ(float *x, float *y, float *z); + void getXYZ(float *x, float *y, float *z) const; void setXYZ(Vector3 position); - void getWidthHeight(int *width, int *height); + void getWidthHeight(int *width, int *height) const; - bool isTargetable(); + bool isTargetable() const; bool tick(Common::Rect *screenRect, bool special); void setup(int itemId, int setId, int animationId, Vector3 position, int facing, int height, int width, bool isTargetableFlag, bool isVisibleFlag, bool isPoliceMazeEnemyFlag); diff --git a/engines/bladerunner/item_pickup.cpp b/engines/bladerunner/item_pickup.cpp index b1f557d344..ffaeb79f33 100644 --- a/engines/bladerunner/item_pickup.cpp +++ b/engines/bladerunner/item_pickup.cpp @@ -22,10 +22,9 @@ #include "bladerunner/item_pickup.h" -#include "bladerunner/bladerunner.h" - #include "bladerunner/audio_player.h" -#include "bladerunner/gameinfo.h" +#include "bladerunner/bladerunner.h" +#include "bladerunner/game_info.h" #include "bladerunner/slice_animations.h" #include "bladerunner/slice_renderer.h" #include "bladerunner/zbuffer.h" @@ -104,6 +103,6 @@ void ItemPickup::draw() { return; } - _vm->_sliceRenderer->drawOnScreen(_animationId, _animationFrame, _screenX, _screenY, _facing, _scale, _vm->_surfaceGame, _vm->_zbuffer->getData()); + _vm->_sliceRenderer->drawOnScreen(_animationId, _animationFrame, _screenX, _screenY, _facing, _scale, _vm->_surfaceFront); } } // End of namespace BladeRunner diff --git a/engines/bladerunner/items.cpp b/engines/bladerunner/items.cpp index dda284f67d..a5298ca8de 100644 --- a/engines/bladerunner/items.cpp +++ b/engines/bladerunner/items.cpp @@ -38,14 +38,14 @@ Items::~Items() { } } -void Items::getXYZ(int itemId, float *x, float *y, float *z) { +void Items::getXYZ(int itemId, float *x, float *y, float *z) const { int itemIndex = findItem(itemId); assert(itemIndex != -1); _items[itemIndex]->getXYZ(x, y, z); } -void Items::getWidthHeight(int itemId, int *width, int *height) { +void Items::getWidthHeight(int itemId, int *width, int *height) const { int itemIndex = findItem(itemId); assert(itemIndex != -1); @@ -80,20 +80,20 @@ bool Items::addToWorld(int itemId, int animationId, int setId, Vector3 position, _items.push_back(item); if (addToSetFlag && setId == _vm->_scene->getSetId()) { - return _vm->_sceneObjects->addItem(itemId + SCENE_OBJECTS_ITEMS_OFFSET, &item->_boundingBox, &item->_screenRectangle, isTargetableFlag, isVisibleFlag); + return _vm->_sceneObjects->addItem(itemId + kSceneObjectOffsetItems, &item->_boundingBox, &item->_screenRectangle, isTargetableFlag, isVisibleFlag); } return true; } bool Items::addToSet(int setId) { - int itemsCount = _vm->_items->_items.size(); - if (itemsCount == 0) { + int itemCount = _vm->_items->_items.size(); + if (itemCount == 0) { return true; } - for (int i = 0; i < itemsCount; i++) { + for (int i = 0; i < itemCount; i++) { Item *item = _vm->_items->_items[i]; if (item->_setId == setId) { - _vm->_sceneObjects->addItem(item->_itemId + SCENE_OBJECTS_ITEMS_OFFSET, &item->_boundingBox, &item->_screenRectangle, item->isTargetable(), item->_isVisible); + _vm->_sceneObjects->addItem(item->_itemId + kSceneObjectOffsetItems, &item->_boundingBox, &item->_screenRectangle, item->isTargetable(), item->_isVisible); } } return true; @@ -109,13 +109,13 @@ bool Items::remove(int itemId) { } if (_items[itemIndex]->_setId == _vm->_scene->getSetId()) { - _vm->_sceneObjects->remove(itemId + SCENE_OBJECTS_ITEMS_OFFSET); + _vm->_sceneObjects->remove(itemId + kSceneObjectOffsetItems); } _items.remove_at(itemIndex); return true; } -int Items::findItem(int itemId) { +int Items::findItem(int itemId) const { for (int i = 0; i < (int)_items.size(); i++) { if (_items[i]->_itemId == itemId) return i; diff --git a/engines/bladerunner/items.h b/engines/bladerunner/items.h index c288e93bae..c49231f30e 100644 --- a/engines/bladerunner/items.h +++ b/engines/bladerunner/items.h @@ -33,14 +33,14 @@ namespace BladeRunner { class Items { BladeRunnerEngine *_vm; - Common::Array<Item*> _items; + Common::Array<Item *> _items; public: Items(BladeRunnerEngine *vm); ~Items(); - void getXYZ(int itemId, float *x, float *y, float *z); - void getWidthHeight(int itemId, int *width, int *height); + void getXYZ(int itemId, float *x, float *y, float *z) const; + void getWidthHeight(int itemId, int *width, int *height) const; void tick(); bool addToWorld(int itemId, int animationId, int setId, Vector3 position, int facing, int height, int width, bool isTargetableFlag, bool isVisibleFlag, bool isPoliceMazeEnemyFlag, bool addToSetFlag); @@ -48,7 +48,7 @@ public: bool remove(int itemId); private: - int findItem(int itemId); + int findItem(int itemId) const; }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/light.cpp b/engines/bladerunner/light.cpp index c447920601..93481fe9aa 100644 --- a/engines/bladerunner/light.cpp +++ b/engines/bladerunner/light.cpp @@ -36,8 +36,8 @@ Light::~Light() { } } -void Light::read(Common::ReadStream *stream, int framesCount, int frame, int animated) { - _framesCount = framesCount; +void Light::read(Common::ReadStream *stream, int frameCount, int frame, int animated) { + _frameCount = frameCount; _animated = animated; int size = stream->readUint32LE(); @@ -50,37 +50,37 @@ void Light::read(Common::ReadStream *stream, int framesCount, int frame, int ani if (_animationData != nullptr) { delete[] _animationData; } - int floatsCount = size / 4; - _animationData = new float[floatsCount]; - for (int i = 0; i < floatsCount; i++) { + int floatCount = size / 4; + _animationData = new float[floatCount]; + for (int i = 0; i < floatCount; i++) { _animationData[i] = stream->readFloatLE(); } _m11ptr = _animationData; - _m12ptr = _m11ptr + (_animatedParameters & 0x1 ? framesCount : 1); - _m13ptr = _m12ptr + (_animatedParameters & 0x2 ? framesCount : 1); - _m14ptr = _m13ptr + (_animatedParameters & 0x4 ? framesCount : 1); - _m21ptr = _m14ptr + (_animatedParameters & 0x8 ? framesCount : 1); - _m22ptr = _m21ptr + (_animatedParameters & 0x10 ? framesCount : 1); - _m23ptr = _m22ptr + (_animatedParameters & 0x20 ? framesCount : 1); - _m24ptr = _m23ptr + (_animatedParameters & 0x40 ? framesCount : 1); - _m31ptr = _m24ptr + (_animatedParameters & 0x80 ? framesCount : 1); - _m32ptr = _m31ptr + (_animatedParameters & 0x100 ? framesCount : 1); - _m33ptr = _m32ptr + (_animatedParameters & 0x200 ? framesCount : 1); - _m34ptr = _m33ptr + (_animatedParameters & 0x400 ? framesCount : 1); - _colorRPtr = _m34ptr + (_animatedParameters & 0x800 ? framesCount : 1); - _colorGPtr = _colorRPtr + (_animatedParameters & 0x1000 ? framesCount : 1); - _colorBPtr = _colorGPtr + (_animatedParameters & 0x2000 ? framesCount : 1); - _falloffStartPtr = _colorBPtr + (_animatedParameters & 0x4000 ? framesCount : 1); - _falloffEndPtr = _falloffStartPtr + (_animatedParameters & 0x8000 ? framesCount : 1); - _angleStartPtr = _falloffEndPtr + (_animatedParameters & 0x10000 ? framesCount : 1); - _angleEndPtr = _angleStartPtr + (_animatedParameters & 0x20000 ? framesCount : 1); + _m12ptr = _m11ptr + (_animatedParameters & 0x1 ? frameCount : 1); + _m13ptr = _m12ptr + (_animatedParameters & 0x2 ? frameCount : 1); + _m14ptr = _m13ptr + (_animatedParameters & 0x4 ? frameCount : 1); + _m21ptr = _m14ptr + (_animatedParameters & 0x8 ? frameCount : 1); + _m22ptr = _m21ptr + (_animatedParameters & 0x10 ? frameCount : 1); + _m23ptr = _m22ptr + (_animatedParameters & 0x20 ? frameCount : 1); + _m24ptr = _m23ptr + (_animatedParameters & 0x40 ? frameCount : 1); + _m31ptr = _m24ptr + (_animatedParameters & 0x80 ? frameCount : 1); + _m32ptr = _m31ptr + (_animatedParameters & 0x100 ? frameCount : 1); + _m33ptr = _m32ptr + (_animatedParameters & 0x200 ? frameCount : 1); + _m34ptr = _m33ptr + (_animatedParameters & 0x400 ? frameCount : 1); + _colorRPtr = _m34ptr + (_animatedParameters & 0x800 ? frameCount : 1); + _colorGPtr = _colorRPtr + (_animatedParameters & 0x1000 ? frameCount : 1); + _colorBPtr = _colorGPtr + (_animatedParameters & 0x2000 ? frameCount : 1); + _falloffStartPtr = _colorBPtr + (_animatedParameters & 0x4000 ? frameCount : 1); + _falloffEndPtr = _falloffStartPtr + (_animatedParameters & 0x8000 ? frameCount : 1); + _angleStartPtr = _falloffEndPtr + (_animatedParameters & 0x10000 ? frameCount : 1); + _angleEndPtr = _angleStartPtr + (_animatedParameters & 0x20000 ? frameCount : 1); setupFrame(frame); } -void Light::readVqa(Common::ReadStream *stream, int framesCount, int frame, int animated) { - _framesCount = framesCount; +void Light::readVqa(Common::ReadStream *stream, int frameCount, int frame, int animated) { + _frameCount = frameCount; _animated = animated; _animatedParameters = stream->readUint32LE(); @@ -91,37 +91,37 @@ void Light::readVqa(Common::ReadStream *stream, int framesCount, int frame, int delete[] _animationData; } - int floatsCount = size / 4; - _animationData = new float[floatsCount]; - for (int i = 0; i < floatsCount; i++) { + int floatCount = size / 4; + _animationData = new float[floatCount]; + for (int i = 0; i < floatCount; i++) { _animationData[i] = stream->readFloatLE(); } _m11ptr = _animationData; - _m12ptr = _m11ptr + (_animatedParameters & 0x1 ? framesCount : 1); - _m13ptr = _m12ptr + (_animatedParameters & 0x2 ? framesCount : 1); - _m14ptr = _m13ptr + (_animatedParameters & 0x4 ? framesCount : 1); - _m21ptr = _m14ptr + (_animatedParameters & 0x8 ? framesCount : 1); - _m22ptr = _m21ptr + (_animatedParameters & 0x10 ? framesCount : 1); - _m23ptr = _m22ptr + (_animatedParameters & 0x20 ? framesCount : 1); - _m24ptr = _m23ptr + (_animatedParameters & 0x40 ? framesCount : 1); - _m31ptr = _m24ptr + (_animatedParameters & 0x80 ? framesCount : 1); - _m32ptr = _m31ptr + (_animatedParameters & 0x100 ? framesCount : 1); - _m33ptr = _m32ptr + (_animatedParameters & 0x200 ? framesCount : 1); - _m34ptr = _m33ptr + (_animatedParameters & 0x400 ? framesCount : 1); - _colorRPtr = _m34ptr + (_animatedParameters & 0x800 ? framesCount : 1); - _colorGPtr = _colorRPtr + (_animatedParameters & 0x1000 ? framesCount : 1); - _colorBPtr = _colorGPtr + (_animatedParameters & 0x2000 ? framesCount : 1); - _falloffStartPtr = _colorBPtr + (_animatedParameters & 0x4000 ? framesCount : 1); - _falloffEndPtr = _falloffStartPtr + (_animatedParameters & 0x8000 ? framesCount : 1); - _angleStartPtr = _falloffEndPtr + (_animatedParameters & 0x10000 ? framesCount : 1); - _angleEndPtr = _angleStartPtr + (_animatedParameters & 0x20000 ? framesCount : 1); + _m12ptr = _m11ptr + (_animatedParameters & 0x1 ? frameCount : 1); + _m13ptr = _m12ptr + (_animatedParameters & 0x2 ? frameCount : 1); + _m14ptr = _m13ptr + (_animatedParameters & 0x4 ? frameCount : 1); + _m21ptr = _m14ptr + (_animatedParameters & 0x8 ? frameCount : 1); + _m22ptr = _m21ptr + (_animatedParameters & 0x10 ? frameCount : 1); + _m23ptr = _m22ptr + (_animatedParameters & 0x20 ? frameCount : 1); + _m24ptr = _m23ptr + (_animatedParameters & 0x40 ? frameCount : 1); + _m31ptr = _m24ptr + (_animatedParameters & 0x80 ? frameCount : 1); + _m32ptr = _m31ptr + (_animatedParameters & 0x100 ? frameCount : 1); + _m33ptr = _m32ptr + (_animatedParameters & 0x200 ? frameCount : 1); + _m34ptr = _m33ptr + (_animatedParameters & 0x400 ? frameCount : 1); + _colorRPtr = _m34ptr + (_animatedParameters & 0x800 ? frameCount : 1); + _colorGPtr = _colorRPtr + (_animatedParameters & 0x1000 ? frameCount : 1); + _colorBPtr = _colorGPtr + (_animatedParameters & 0x2000 ? frameCount : 1); + _falloffStartPtr = _colorBPtr + (_animatedParameters & 0x4000 ? frameCount : 1); + _falloffEndPtr = _falloffStartPtr + (_animatedParameters & 0x8000 ? frameCount : 1); + _angleStartPtr = _falloffEndPtr + (_animatedParameters & 0x10000 ? frameCount : 1); + _angleEndPtr = _angleStartPtr + (_animatedParameters & 0x20000 ? frameCount : 1); setupFrame(frame); } void Light::setupFrame(int frame) { - int offset = frame % _framesCount; + int offset = frame % _frameCount; _matrix._m[0][0] = (_animatedParameters & 0x1 ? _m11ptr[offset] : *_m11ptr); _matrix._m[0][1] = (_animatedParameters & 0x2 ? _m12ptr[offset] : *_m12ptr); _matrix._m[0][2] = (_animatedParameters & 0x4 ? _m13ptr[offset] : *_m13ptr); @@ -143,11 +143,11 @@ void Light::setupFrame(int frame) { _angleEnd = (_animatedParameters & 0x40000 ? _angleEndPtr[offset] : *_angleEndPtr); } -float Light::calculate(Vector3 start, Vector3 end) { +float Light::calculate(Vector3 start, Vector3 end) const { return calculateFalloutCoefficient(_matrix * start, _matrix * end, _falloffStart, _falloffEnd); } -void Light::calculateColor(Color *outColor, Vector3 position) { +void Light::calculateColor(Color *outColor, Vector3 position) const { Vector3 positionT = _matrix * position; float att = attenuation(_falloffStart, _falloffEnd, positionT.length()); outColor->r = _color.r * att; @@ -155,7 +155,7 @@ void Light::calculateColor(Color *outColor, Vector3 position) { outColor->b = _color.b * att; } -float Light::calculateFalloutCoefficient(Vector3 start, Vector3 end, float falloffStart, float falloffEnd) { +float Light::calculateFalloutCoefficient(Vector3 start, Vector3 end, float falloffStart, float falloffEnd) const { if (falloffEnd == 0.0f) { return 1.0e30f; } @@ -177,7 +177,7 @@ float Light::calculateFalloutCoefficient(Vector3 start, Vector3 end, float fallo return 1.0e30f; } -float Light::attenuation(float min, float max, float distance) { +float Light::attenuation(float min, float max, float distance) const { if (max == 0.0f) { return 1.0f; } @@ -192,7 +192,7 @@ float Light::attenuation(float min, float max, float distance) { return 0.0f; } -float Light1::calculate(Vector3 start, Vector3 end) { +float Light1::calculate(Vector3 start, Vector3 end) const { start = _matrix * start; end = _matrix * end; @@ -217,7 +217,7 @@ float Light1::calculate(Vector3 start, Vector3 end) { } } -void Light1::calculateColor(Color *outColor, Vector3 position) { +void Light1::calculateColor(Color *outColor, Vector3 position) const { Vector3 positionT = _matrix * position; outColor->r = 0.0f; @@ -234,7 +234,7 @@ void Light1::calculateColor(Color *outColor, Vector3 position) { } } -float Light2::calculate(Vector3 start, Vector3 end) { +float Light2::calculate(Vector3 start, Vector3 end) const { start = _matrix * start; end = _matrix * end; @@ -261,7 +261,7 @@ float Light2::calculate(Vector3 start, Vector3 end) { } } -void Light2::calculateColor(Color *outColor, Vector3 position) { +void Light2::calculateColor(Color *outColor, Vector3 position) const { Vector3 positionT = _matrix * position; outColor->r = 0.0f; @@ -279,7 +279,7 @@ void Light2::calculateColor(Color *outColor, Vector3 position) { } } -void Light3::calculateColor(Color *outColor, Vector3 position) { +void Light3::calculateColor(Color *outColor, Vector3 position) const { Vector3 positionT = _matrix * position; outColor->r = 0.0f; @@ -296,7 +296,7 @@ void Light3::calculateColor(Color *outColor, Vector3 position) { } } -void Light4::calculateColor(Color *outColor, Vector3 position) { +void Light4::calculateColor(Color *outColor, Vector3 position) const { Vector3 positionT = _matrix * position; outColor->r = 0.0f; @@ -314,11 +314,11 @@ void Light4::calculateColor(Color *outColor, Vector3 position) { } } -float LightAmbient::calculate(Vector3 start, Vector3 end) { +float LightAmbient::calculate(Vector3 start, Vector3 end) const { return 1.0e30f; } -void LightAmbient::calculateColor(Color *outColor, Vector3 position) { +void LightAmbient::calculateColor(Color *outColor, Vector3 position) const { outColor->r = _color.r; outColor->g = _color.g; outColor->b = _color.b; diff --git a/engines/bladerunner/light.h b/engines/bladerunner/light.h index 7b05378be2..8ad86368ea 100644 --- a/engines/bladerunner/light.h +++ b/engines/bladerunner/light.h @@ -37,84 +37,84 @@ namespace BladeRunner { class Lights; class Light { -#if _DEBUG +#if BLADERUNNER_DEBUG_RENDERING friend class BladeRunnerEngine; #endif friend class Lights; friend class SliceRenderer; protected: - char _name[20]; - int _framesCount; - int _animated; - int _animatedParameters; + char _name[20]; + int _frameCount; + int _animated; + int _animatedParameters; Matrix4x3 _matrix; - Color _color; - float _falloffStart; - float _falloffEnd; - float _angleStart; - float _angleEnd; - float *_animationData; - float *_m11ptr; - float *_m12ptr; - float *_m13ptr; - float *_m14ptr; - float *_m21ptr; - float *_m22ptr; - float *_m23ptr; - float *_m24ptr; - float *_m31ptr; - float *_m32ptr; - float *_m33ptr; - float *_m34ptr; - float *_colorRPtr; - float *_colorGPtr; - float *_colorBPtr; - float *_falloffStartPtr; - float *_falloffEndPtr; - float *_angleStartPtr; - float *_angleEndPtr; -// Light *_next; + Color _color; + float _falloffStart; + float _falloffEnd; + float _angleStart; + float _angleEnd; + float *_animationData; + float *_m11ptr; + float *_m12ptr; + float *_m13ptr; + float *_m14ptr; + float *_m21ptr; + float *_m22ptr; + float *_m23ptr; + float *_m24ptr; + float *_m31ptr; + float *_m32ptr; + float *_m33ptr; + float *_m34ptr; + float *_colorRPtr; + float *_colorGPtr; + float *_colorBPtr; + float *_falloffStartPtr; + float *_falloffEndPtr; + float *_angleStartPtr; + float *_angleEndPtr; public: Light(); virtual ~Light(); - void read(Common::ReadStream *stream, int framesCount, int frame, int animated); - void readVqa(Common::ReadStream *stream, int framesCount, int frame, int animated); + void read(Common::ReadStream *stream, int frameCount, int frame, int animated); + void readVqa(Common::ReadStream *stream, int frameCount, int frame, int animated); void setupFrame(int frame); - virtual float calculate(Vector3 start, Vector3 end); - virtual void calculateColor(Color *outColor, Vector3 position); + virtual float calculate(Vector3 start, Vector3 end) const; + virtual void calculateColor(Color *outColor, Vector3 position) const; protected: - float calculateFalloutCoefficient(Vector3 start, Vector3 end, float a3, float a4); - float attenuation(float min, float max, float distance); + float calculateFalloutCoefficient(Vector3 start, Vector3 end, float a3, float a4) const; + float attenuation(float min, float max, float distance) const; }; class Light1 : public Light { - float calculate(Vector3 start, Vector3 end); - void calculateColor(Color *outColor, Vector3 position); + float calculate(Vector3 start, Vector3 end) const; + void calculateColor(Color *outColor, Vector3 position) const; }; class Light2 : public Light { - float calculate(Vector3 start, Vector3 end); - void calculateColor(Color *outColor, Vector3 position); + float calculate(Vector3 start, Vector3 end) const; + void calculateColor(Color *outColor, Vector3 position) const; }; class Light3 : public Light { - void calculateColor(Color *outColor, Vector3 position); + void calculateColor(Color *outColor, Vector3 position) const; }; class Light4 : public Light { - void calculateColor(Color *outColor, Vector3 position); + void calculateColor(Color *outColor, Vector3 position) const; }; class LightAmbient : public Light { - float calculate(Vector3 start, Vector3 end); - void calculateColor(Color *outColor, Vector3 position); + float calculate(Vector3 start, Vector3 end) const; + void calculateColor(Color *outColor, Vector3 position) const; }; } // End of namespace BladeRunner + #endif diff --git a/engines/bladerunner/lights.cpp b/engines/bladerunner/lights.cpp index 811d72f31f..ccb339c4a8 100644 --- a/engines/bladerunner/lights.cpp +++ b/engines/bladerunner/lights.cpp @@ -39,13 +39,13 @@ Lights::~Lights() { reset(); } -void Lights::read(Common::ReadStream *stream, int framesCount) { +void Lights::read(Common::ReadStream *stream, int frameCount) { _ambientLightColor.r = stream->readFloatLE(); _ambientLightColor.g = stream->readFloatLE(); _ambientLightColor.b = stream->readFloatLE(); - uint _lightsCount = stream->readUint32LE(); - for (uint i = 0; i < _lightsCount; i++) { + uint _lightCount = stream->readUint32LE(); + for (uint i = 0; i < _lightCount; i++) { Light *light; int type = stream->readUint32LE(); switch (type) { @@ -68,7 +68,7 @@ void Lights::read(Common::ReadStream *stream, int framesCount) { light = new Light(); } - light->read(stream, framesCount, _frame, 0); + light->read(stream, frameCount, _frame, 0); _lights.push_back(light); } } @@ -86,7 +86,7 @@ void Lights::readVqa(Common::ReadStream *stream) { if (stream->eos()) return; - int framesCount = stream->readUint32LE(); + int frameCount = stream->readUint32LE(); int count = stream->readUint32LE(); for (int i = 0; i < count; i++) { int lightType = stream->readUint32LE(); @@ -110,7 +110,7 @@ void Lights::readVqa(Common::ReadStream *stream) { default: light = new Light(); } - light->readVqa(stream, framesCount, _frame, 1); + light->readVqa(stream, frameCount, _frame, 1); _lights.push_back(light); } } diff --git a/engines/bladerunner/lights.h b/engines/bladerunner/lights.h index a6f2a728ce..904a96f425 100644 --- a/engines/bladerunner/lights.h +++ b/engines/bladerunner/lights.h @@ -32,7 +32,7 @@ namespace BladeRunner { class Lights { -#if _DEBUG +#if BLADERUNNER_DEBUG_RENDERING friend class BladeRunnerEngine; #endif friend class SliceRendererLights; @@ -42,18 +42,18 @@ class Lights { Color _ambientLightColor; Common::Array<Light *> _lights; int _frame; - //char gap[28]; public: Lights(BladeRunnerEngine *vm); ~Lights(); - void read(Common::ReadStream *stream, int framesCount); + void read(Common::ReadStream *stream, int frameCount); void readVqa(Common::ReadStream *stream); void reset(); void setupFrame(int frame); + private: void removeAnimated(); }; diff --git a/engines/bladerunner/module.mk b/engines/bladerunner/module.mk index 89419d41d0..6aadb972db 100644 --- a/engines/bladerunner/module.mk +++ b/engines/bladerunner/module.mk @@ -1,10 +1,10 @@ MODULE := engines/bladerunner MODULE_OBJS = \ - adq.o \ actor.o \ actor_clues.o \ actor_combat.o \ + actor_dialogue_queue.o \ actor_walk.o \ adpcm_decoder.o \ ambient_sounds.o \ @@ -22,11 +22,10 @@ MODULE_OBJS = \ decompress_lzo.o \ detection.o \ dialogue_menu.o \ - elevator.o \ fog.o \ font.o \ - gameflags.o \ - gameinfo.o \ + game_flags.o \ + game_info.o \ image.o \ item.o \ item_pickup.o \ @@ -174,10 +173,24 @@ MODULE_OBJS = \ shape.o \ slice_animations.o \ slice_renderer.o \ - spinner.o \ suspects_database.o \ text_resource.o \ - ui_image_picker.o \ + ui/elevator.o \ + ui/kia.o \ + ui/kia_log.o \ + ui/kia_section_base.o \ + ui/kia_section_clues.o \ + ui/kia_section_crimes.o \ + ui/kia_section_help.o \ + ui/kia_section_settings.o \ + ui/kia_shapes.o \ + ui/spinner.o \ + ui/ui_check_box.o \ + ui/ui_container.o \ + ui/ui_image_picker.o \ + ui/ui_input_box.o \ + ui/ui_scroll_box.o \ + ui/ui_slider.o \ view.o \ vqa_decoder.o \ vqa_player.o \ diff --git a/engines/bladerunner/mouse.cpp b/engines/bladerunner/mouse.cpp index 8293cbc59c..35059f4e00 100644 --- a/engines/bladerunner/mouse.cpp +++ b/engines/bladerunner/mouse.cpp @@ -35,7 +35,8 @@ namespace BladeRunner { -Mouse::Mouse(BladeRunnerEngine *vm) : _vm(vm) { +Mouse::Mouse(BladeRunnerEngine *vm) { + _vm = vm; _cursor = 0; _frame = 3; _hotspotX = 0; @@ -149,7 +150,7 @@ void Mouse::setCursor(int cursor) { } } -void Mouse::getXY(int *x, int *y) { +void Mouse::getXY(int *x, int *y) const { *x = _x; *y = _y; } @@ -164,7 +165,7 @@ void Mouse::enable() { } } -bool Mouse::isDisabled() { +bool Mouse::isDisabled() const { return _disabledCounter > 0; } @@ -311,7 +312,7 @@ void Mouse::tick(int x, int y) { } // TEST: RC01 after intro: [290, 216] -> [-204.589249 51.450668 7.659241] -Vector3 Mouse::getXYZ(int x, int y) { +Vector3 Mouse::getXYZ(int x, int y) const { if (_vm->_scene->getSetId() == -1) return Vector3(); diff --git a/engines/bladerunner/mouse.h b/engines/bladerunner/mouse.h index 214089fed6..64b01992d0 100644 --- a/engines/bladerunner/mouse.h +++ b/engines/bladerunner/mouse.h @@ -26,7 +26,7 @@ #include "bladerunner/vector.h" namespace Graphics { - struct Surface; +struct Surface; } namespace BladeRunner { @@ -52,11 +52,11 @@ public: void setCursor(int cursor); - void getXY(int *x, int *y); + void getXY(int *x, int *y) const; void disable(); void enable(); - bool isDisabled(); + bool isDisabled() const; void draw(Graphics::Surface &surface, int x, int y); void updateCursorFrame(); @@ -64,7 +64,7 @@ public: void tick(int x, int y); // private: - Vector3 getXYZ(int x, int y); + Vector3 getXYZ(int x, int y) const; }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/movement_track.cpp b/engines/bladerunner/movement_track.cpp index 702a1187f1..13b60d1d93 100644 --- a/engines/bladerunner/movement_track.cpp +++ b/engines/bladerunner/movement_track.cpp @@ -37,7 +37,7 @@ void MovementTrack::reset() { _lastIndex = 0; _hasNext = false; _paused = false; - for (int i = 0; i < 100; i++) { + for (int i = 0; i < kSize; i++) { _entries[i].waypointId = -1; _entries[i].delay = -1; _entries[i].angle = -1; @@ -50,7 +50,7 @@ int MovementTrack::append(int waypointId, int delay, int running) { } int MovementTrack::append(int waypointId, int delay, int angle, int running) { - if (_lastIndex >= 100) { + if (_lastIndex >= kSize) { return 0; } @@ -82,11 +82,11 @@ void MovementTrack::unpause() { _paused = false; } -bool MovementTrack::isPaused() { +bool MovementTrack::isPaused() const { return _paused; } -bool MovementTrack::hasNext() { +bool MovementTrack::hasNext() const { return _hasNext; } diff --git a/engines/bladerunner/movement_track.h b/engines/bladerunner/movement_track.h index bffac4855a..174b222b1e 100644 --- a/engines/bladerunner/movement_track.h +++ b/engines/bladerunner/movement_track.h @@ -30,23 +30,21 @@ namespace BladeRunner { class BladeRunnerEngine; class BoundingBox; -struct MovementTrackEntry { - int waypointId; - int delay; - int angle; - int running; -}; - class MovementTrack { -// BladeRunnerEngine *_vm; + static const int kSize = 100; -private: - int _currentIndex; - int _lastIndex; - bool _hasNext; - bool _paused; - MovementTrackEntry _entries[100]; - void reset(); + struct Entry { + int waypointId; + int delay; + int angle; + int running; + }; + + int _currentIndex; + int _lastIndex; + bool _hasNext; + bool _paused; + Entry _entries[kSize]; public: MovementTrack(); @@ -57,11 +55,14 @@ public: void repeat(); void pause(); void unpause(); - bool isPaused(); - bool hasNext(); + bool isPaused() const; + bool hasNext() const; bool next(int *waypointId, int *delay, int *angle, int *running); //int saveGame(); + +private: + void reset(); }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/music.cpp b/engines/bladerunner/music.cpp index 6b7a733338..88fb3e0b55 100644 --- a/engines/bladerunner/music.cpp +++ b/engines/bladerunner/music.cpp @@ -25,15 +25,16 @@ #include "bladerunner/audio_mixer.h" #include "bladerunner/aud_stream.h" #include "bladerunner/bladerunner.h" +#include "bladerunner/game_info.h" #include "common/timer.h" namespace BladeRunner { -Music::Music(BladeRunnerEngine *vm) - : _vm(vm) { +Music::Music(BladeRunnerEngine *vm) { + _vm = vm; _channel = -1; - _volume = 65; + _musicVolume = 65; _isPlaying = false; _isPaused = false; _current.loop = false; @@ -52,14 +53,14 @@ Music::~Music() { _vm->getTimerManager()->removeTimerProc(timerCallbackNext); } -bool Music::play(const char *trackName, int volume, int pan, int timeFadeIn, int timePlay, int loop, int timeFadeOut) { +bool Music::play(const Common::String &trackName, int volume, int pan, int timeFadeIn, int timePlay, int loop, int timeFadeOut) { //Common::StackLock lock(_mutex); - if (_volume <= 0) { + if (_musicVolume <= 0) { return false; } - int volumeAdjusted = volume * _volume / 100; + int volumeAdjusted = volume * _musicVolume / 100; int volumeStart = volumeAdjusted; if (timeFadeIn > 0) { volumeStart = 1; @@ -134,7 +135,7 @@ void Music::stop(int delay) { void Music::adjust(int volume, int pan, int delay) { if (volume != -1) { - adjustVolume(_volume * volume/ 100, delay); + adjustVolume(_musicVolume * volume/ 100, delay); } if (pan != -101) { adjustPan(pan, delay); @@ -146,11 +147,21 @@ bool Music::isPlaying() { } void Music::setVolume(int volume) { - _volume = volume; + _musicVolume = volume; if (volume <= 0) { stop(2); } else if (isPlaying()) { - _vm->_audioMixer->adjustVolume(_channel, _volume * _current.volume / 100, 120); + _vm->_audioMixer->adjustVolume(_channel, _musicVolume * _current.volume / 100, 120); + } +} + +int Music::getVolume() { + return _musicVolume; +} + +void Music::playSample() { + if (!isPlaying()) { + play(_vm->_gameInfo->getSfxTrack(512), 100, 0, 2, -1, 0, 3); } } @@ -214,7 +225,7 @@ void Music::timerCallbackNext(void *refCon) { ((Music *)refCon)->next(); } -byte *Music::getData(const char *name) { +byte *Music::getData(const Common::String &name) { // NOTE: This is not part original game, loading data is done in the mixer and its using buffering to limit memory usage Common::SeekableReadStream *stream = _vm->getResourceStream(name); if (stream == nullptr) { diff --git a/engines/bladerunner/music.h b/engines/bladerunner/music.h index 3dcf969a8a..de19942a20 100644 --- a/engines/bladerunner/music.h +++ b/engines/bladerunner/music.h @@ -45,7 +45,7 @@ class Music { BladeRunnerEngine *_vm; Common::Mutex _mutex; - int _volume; + int _musicVolume; int _channel; int _isNextPresent; int _isPlaying; @@ -59,12 +59,14 @@ public: Music(BladeRunnerEngine *vm); ~Music(); - bool play(const char *trackName, int volume, int pan, int timeFadeIn, int timePlay, int loop, int timeFadeOut); + bool play(const Common::String &trackName, int volume, int pan, int timeFadeIn, int timePlay, int loop, int timeFadeOut); void stop(int delay); void adjust(int volume, int pan, int delay); bool isPlaying(); void setVolume(int volume); + int getVolume(); + void playSample(); private: void adjustVolume(int volume, int delay); @@ -78,7 +80,7 @@ private: static void timerCallbackFadeOut(void *refCon); static void timerCallbackNext(void *refCon); - byte *getData(const char* name); + byte *getData(const Common::String &name); }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/obstacles.cpp b/engines/bladerunner/obstacles.cpp index 9fbdc0ad5e..8061e782f2 100644 --- a/engines/bladerunner/obstacles.cpp +++ b/engines/bladerunner/obstacles.cpp @@ -28,28 +28,24 @@ namespace BladeRunner { Obstacles::Obstacles(BladeRunnerEngine *vm) { _vm = vm; - _polygons = new ObstaclesPolygon[50]; - _polygonsBackup = new ObstaclesPolygon[50]; _vertices = new Vector2[150]; clear(); } Obstacles::~Obstacles() { delete[] _vertices; - delete[] _polygonsBackup; - delete[] _polygons; } void Obstacles::clear() { - for (int i = 0; i < 50; i++) { - _polygons[i]._isPresent = false; - _polygons[i]._verticesCount = 0; - for (int j = 0; j < 160; j++) { - _polygons[i]._vertices[j].x = 0.0f; - _polygons[i]._vertices[j].y = 0.0f; + for (int i = 0; i < kPolygonCount; i++) { + _polygons[i].isPresent = false; + _polygons[i].verticeCount = 0; + for (int j = 0; j < kVertexCount; j++) { + _polygons[i].vertices[j].x = 0.0f; + _polygons[i].vertices[j].y = 0.0f; } } - _verticesCount = 0; + _verticeCount = 0; _backup = false; _count = 0; } @@ -57,7 +53,7 @@ void Obstacles::clear() { void Obstacles::add(float x0, float z0, float x1, float z1) { } -bool Obstacles::find(const Vector3 &from, const Vector3 &to, Vector3 *next) { +bool Obstacles::find(const Vector3 &from, const Vector3 &to, Vector3 *next) const { //TODO *next = to; return true; diff --git a/engines/bladerunner/obstacles.h b/engines/bladerunner/obstacles.h index f9641bfe6b..c2c84c3bfa 100644 --- a/engines/bladerunner/obstacles.h +++ b/engines/bladerunner/obstacles.h @@ -27,29 +27,31 @@ namespace BladeRunner { -struct ObstaclesPolygon { - bool _isPresent; - int _verticesCount; - float _left; - float _bottom; - float _right; - float _top; - Vector2 _vertices[160]; - int _vertexType[160]; -}; - class BladeRunnerEngine; class Obstacles { + static const int kPolygonCount = 50; + static const int kVertexCount = 160; + + struct Polygon { + bool isPresent; + int verticeCount; + float left; + float bottom; + float right; + float top; + Vector2 vertices[kVertexCount]; + int vertexType[kVertexCount]; + }; + BladeRunnerEngine *_vm; -private: - ObstaclesPolygon *_polygons; - ObstaclesPolygon *_polygonsBackup; - Vector2 *_vertices; - int _verticesCount; - int _count; - bool _backup; + Polygon _polygons[kPolygonCount]; + Polygon _polygonsBackup[kPolygonCount]; + Vector2 *_vertices; + int _verticeCount; + int _count; + bool _backup; public: Obstacles(BladeRunnerEngine *vm); @@ -57,7 +59,7 @@ public: void clear(); void add(float x0, float z0, float x1, float z1); - bool find(const Vector3 &from, const Vector3 &to, Vector3 *next); + bool find(const Vector3 &from, const Vector3 &to, Vector3 *next) const; void backup(); void restore(); }; diff --git a/engines/bladerunner/outtake.cpp b/engines/bladerunner/outtake.cpp index 4791259e32..6d76162dd9 100644 --- a/engines/bladerunner/outtake.cpp +++ b/engines/bladerunner/outtake.cpp @@ -44,7 +44,7 @@ void OuttakePlayer::play(const Common::String &name, bool noLocalization, int co resName = resName + ".VQA"; - VQAPlayer vqa_player(_vm, &_vm->_surfaceGame); + VQAPlayer vqa_player(_vm, &_vm->_surfaceFront); vqa_player.open(resName); @@ -60,7 +60,7 @@ void OuttakePlayer::play(const Common::String &name, bool noLocalization, int co break; if (frame >= 0) { - _vm->blitToScreen(_vm->_surfaceGame); + _vm->blitToScreen(_vm->_surfaceFront); } _vm->_system->delayMillis(10); diff --git a/engines/bladerunner/outtake.h b/engines/bladerunner/outtake.h index acbd00f6a6..8386965fdf 100644 --- a/engines/bladerunner/outtake.h +++ b/engines/bladerunner/outtake.h @@ -35,7 +35,9 @@ class OuttakePlayer { BladeRunnerEngine *_vm; public: - OuttakePlayer(BladeRunnerEngine *vm) : _vm(vm) {} + OuttakePlayer(BladeRunnerEngine *vm) { + _vm = vm; + } void play(const Common::String &name, bool noLocalization, int container); }; diff --git a/engines/bladerunner/overlays.cpp b/engines/bladerunner/overlays.cpp index 6e94b291e5..cd6afe8454 100644 --- a/engines/bladerunner/overlays.cpp +++ b/engines/bladerunner/overlays.cpp @@ -31,9 +31,8 @@ namespace BladeRunner { -Overlays::Overlays(BladeRunnerEngine *vm) - : _vm(vm) -{ +Overlays::Overlays(BladeRunnerEngine *vm) { + _vm = vm; } bool Overlays::init() { @@ -65,7 +64,7 @@ int Overlays::play(const Common::String &name, int loopId, int loopForever, int return index; } _videos[index].id = id; - _videos[index].vqaPlayer = new VQAPlayer(_vm, &_vm->_surfaceGame); + _videos[index].vqaPlayer = new VQAPlayer(_vm, &_vm->_surfaceFront); // repeat forever _videos[index].vqaPlayer->setBeginAndEndFrame(0, 0, -1, kLoopSetModeJustStart, nullptr, nullptr); diff --git a/engines/bladerunner/overlays.h b/engines/bladerunner/overlays.h index f547253269..5054051d87 100644 --- a/engines/bladerunner/overlays.h +++ b/engines/bladerunner/overlays.h @@ -27,7 +27,7 @@ #include "common/str.h" namespace Graphics { - struct Surface; +struct Surface; } namespace BladeRunner { @@ -35,21 +35,22 @@ namespace BladeRunner { class BladeRunnerEngine; class VQAPlayer; -struct OverlayVideo { - bool loaded; - VQAPlayer *vqaPlayer; - // char name[13]; - int32 id; - int field0; - int field1; - int field2; -}; class Overlays { static const int kOverlayVideos = 5; + struct Video { + bool loaded; + VQAPlayer *vqaPlayer; + // char name[13]; + int32 id; + int field0; + int field1; + int field2; + }; + BladeRunnerEngine *_vm; - Common::Array<OverlayVideo> _videos; + Common::Array<Video> _videos; public: Overlays(BladeRunnerEngine *vm); diff --git a/engines/bladerunner/regions.cpp b/engines/bladerunner/regions.cpp index 55a1aa14aa..80dabf2989 100644 --- a/engines/bladerunner/regions.cpp +++ b/engines/bladerunner/regions.cpp @@ -26,14 +26,10 @@ namespace BladeRunner { Regions::Regions() { _enabled = true; - _regions = new Region[10]; + _regions.resize(10); clear(); } -Regions::~Regions() { - delete[] _regions; -} - void BladeRunner::Regions::clear() { for (int i = 0; i < 10; ++i) remove(i); @@ -43,12 +39,12 @@ bool Regions::add(int index, Common::Rect rect, int type) { if (index < 0 || index >= 10) return false; - if (_regions[index]._present) + if (_regions[index].present) return false; - _regions[index]._rectangle = rect; - _regions[index]._type = type; - _regions[index]._present = 1; + _regions[index].rectangle = rect; + _regions[index].type = type; + _regions[index].present = 1; return true; } @@ -57,34 +53,34 @@ bool Regions::remove(int index) { if (index < 0 || index >= 10) return false; - _regions[index]._rectangle = Common::Rect(-1, -1, -1, -1); - _regions[index]._type = -1; - _regions[index]._present = 0; + _regions[index].rectangle = Common::Rect(-1, -1, -1, -1); + _regions[index].type = -1; + _regions[index].present = 0; return true; } -int Regions::getTypeAtXY(int x, int y) { +int Regions::getTypeAtXY(int x, int y) const { int index = getRegionAtXY(x, y); if (index == -1) return -1; - return _regions[index]._type; + return _regions[index].type; } -int Regions::getRegionAtXY(int x, int y) { +int Regions::getRegionAtXY(int x, int y) const { if (!_enabled) return -1; for (int i = 0; i != 10; ++i) { - if (!_regions[i]._present) + if (!_regions[i].present) continue; // Common::Rect::contains is exclusive of right and bottom but // Blade Runner wants inclusive, so we adjust the edges. // TODO: Roll our own rect class? - Common::Rect r = _regions[i]._rectangle; + Common::Rect r = _regions[i].rectangle; r.right++; r.bottom++; diff --git a/engines/bladerunner/regions.h b/engines/bladerunner/regions.h index 2dd6808a25..7dfb3ce8b7 100644 --- a/engines/bladerunner/regions.h +++ b/engines/bladerunner/regions.h @@ -25,34 +25,34 @@ #include "bladerunner/bladerunner.h" +#include "common/array.h" #include "common/rect.h" namespace BladeRunner { -struct Region { - Common::Rect _rectangle; - int _type; - int _present; -}; - class Regions { #ifdef _DEBUG friend class BladeRunnerEngine; #endif -private: - Region* _regions; - bool _enabled; + struct Region { + Common::Rect rectangle; + int type; + int present; + }; + + Common::Array<Region> _regions; + bool _enabled; + public: Regions(); - ~Regions(); void clear(); bool add(int index, Common::Rect rect, int type); bool remove(int index); - int getTypeAtXY(int x, int y); - int getRegionAtXY(int x, int y); + int getTypeAtXY(int x, int y) const; + int getRegionAtXY(int x, int y) const; void setEnabled(bool enabled); void enable(); diff --git a/engines/bladerunner/scene.cpp b/engines/bladerunner/scene.cpp index ebf8ed34ba..1c1952d742 100644 --- a/engines/bladerunner/scene.cpp +++ b/engines/bladerunner/scene.cpp @@ -23,10 +23,10 @@ #include "bladerunner/scene.h" #include "bladerunner/actor.h" -#include "bladerunner/adq.h" +#include "bladerunner/actor_dialogue_queue.h" #include "bladerunner/bladerunner.h" #include "bladerunner/chapters.h" -#include "bladerunner/gameinfo.h" +#include "bladerunner/game_info.h" #include "bladerunner/items.h" #include "bladerunner/overlays.h" #include "bladerunner/regions.h" @@ -35,9 +35,9 @@ #include "bladerunner/set.h" #include "bladerunner/settings.h" #include "bladerunner/slice_renderer.h" -#include "bladerunner/vqa_player.h" #include "bladerunner/script/scene.h" -#include "bladerunner/spinner.h" +#include "bladerunner/ui/spinner.h" +#include "bladerunner/vqa_player.h" #include "common/str.h" @@ -73,7 +73,7 @@ Scene::~Scene() { bool Scene::open(int setId, int sceneId, bool isLoadingGame) { if (!isLoadingGame) { - _vm->_adq->flush(1, false); + _vm->_actorDialogueQueue->flush(1, false); } _setId = setId; @@ -108,7 +108,7 @@ bool Scene::open(int setId, int sceneId, bool isLoadingGame) { delete _vqaPlayer; } - _vqaPlayer = new VQAPlayer(_vm, &_vm->_surfaceInterface); + _vqaPlayer = new VQAPlayer(_vm, &_vm->_surfaceBack); Common::String sceneName = _vm->_gameInfo->getSceneName(sceneId); if (!_vm->_sceneScript->Open(sceneName)) { @@ -157,7 +157,7 @@ bool Scene::open(int setId, int sceneId, bool isLoadingGame) { Actor *actor = _vm->_actors[i]; if (actor->getSetId() == setId) { _vm->_sceneObjects->addActor( - i + SCENE_OBJECTS_ACTORS_OFFSET, + i + kSceneObjectOffsetActors, actor->getBoundingBox(), actor->getScreenRectangle(), 1, @@ -208,7 +208,7 @@ bool Scene::close(bool isLoadingGame) { int Scene::advanceFrame() { int frame = _vqaPlayer->update(); if (frame >= 0) { - blit(_vm->_surfaceInterface, _vm->_surfaceGame); + blit(_vm->_surfaceBack, _vm->_surfaceFront); _vqaPlayer->updateZBuffer(_vm->_zbuffer); _vqaPlayer->updateView(_vm->_view); _vqaPlayer->updateScreenEffects(_vm->_screenEffects); @@ -288,14 +288,14 @@ bool Scene::objectGetBoundingBox(int objectId, BoundingBox *boundingBox) { void Scene::objectSetIsClickable(int objectId, bool isClickable, bool sceneLoaded) { _set->objectSetIsClickable(objectId, isClickable); if (sceneLoaded) { - _vm->_sceneObjects->setIsClickable(objectId + SCENE_OBJECTS_OBJECTS_OFFSET, isClickable); + _vm->_sceneObjects->setIsClickable(objectId + kSceneObjectOffsetObjects, isClickable); } } void Scene::objectSetIsObstacle(int objectId, bool isObstacle, bool sceneLoaded, bool updateWalkpath) { _set->objectSetIsObstacle(objectId, isObstacle); if (sceneLoaded) { - _vm->_sceneObjects->setIsObstacle(objectId + SCENE_OBJECTS_OBJECTS_OFFSET, isObstacle); + _vm->_sceneObjects->setIsObstacle(objectId + kSceneObjectOffsetObjects, isObstacle); if (updateWalkpath) { _vm->_sceneObjects->updateObstacles(); } @@ -307,7 +307,7 @@ void Scene::objectSetIsObstacleAll(bool isObstacle, bool sceneLoaded) { for (i = 0; i < (int)_set->getObjectCount(); i++) { _set->objectSetIsObstacle(i, isObstacle); if (sceneLoaded) { - _vm->_sceneObjects->setIsObstacle(i + SCENE_OBJECTS_OBJECTS_OFFSET, isObstacle); + _vm->_sceneObjects->setIsObstacle(i + kSceneObjectOffsetObjects, isObstacle); } } } @@ -315,7 +315,7 @@ void Scene::objectSetIsObstacleAll(bool isObstacle, bool sceneLoaded) { void Scene::objectSetIsTarget(int objectId, bool isTarget, bool sceneLoaded) { _set->objectSetIsTarget(objectId, isTarget); if (sceneLoaded) { - _vm->_sceneObjects->setIsTarget(objectId + SCENE_OBJECTS_OBJECTS_OFFSET, isTarget); + _vm->_sceneObjects->setIsTarget(objectId + kSceneObjectOffsetObjects, isTarget); } } @@ -353,6 +353,6 @@ void Scene::loopEnded(int frame, int loopId) { } void Scene::loopEndedStatic(void *data, int frame, int loopId) { - ((Scene*)data)->loopEnded(frame, loopId); + ((Scene *)data)->loopEnded(frame, loopId); } } // End of namespace BladeRunner diff --git a/engines/bladerunner/scene.h b/engines/bladerunner/scene.h index 70f648acea..cc38c2af4a 100644 --- a/engines/bladerunner/scene.h +++ b/engines/bladerunner/scene.h @@ -36,7 +36,6 @@ class VQAPlayer; class Scene { BladeRunnerEngine *_vm; -private: int _setId; int _sceneId; VQAPlayer *_vqaPlayer; @@ -60,9 +59,6 @@ public: Regions *_regions; Regions *_exits; - // _default_loop_id = 0; - // _scene_vqa_frame_number = -1; - public: Scene(BladeRunnerEngine *vm); ~Scene(); @@ -91,7 +87,7 @@ public: private: void loopEnded(int frame, int loopId); - static void loopEndedStatic(void* data, int frame, int loopId); + static void loopEndedStatic(void *data, int frame, int loopId); }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/scene_objects.cpp b/engines/bladerunner/scene_objects.cpp index b66467e859..d32cdd9cbd 100644 --- a/engines/bladerunner/scene_objects.cpp +++ b/engines/bladerunner/scene_objects.cpp @@ -27,7 +27,6 @@ #include "bladerunner/obstacles.h" #include "bladerunner/view.h" - namespace BladeRunner { SceneObjects::SceneObjects(BladeRunnerEngine *vm, View *view) { @@ -35,10 +34,8 @@ SceneObjects::SceneObjects(BladeRunnerEngine *vm, View *view) { _view = view; _count = 0; - _sceneObjects = new SceneObject[SCENE_OBJECTS_COUNT]; - _sceneObjectsSortedByDistance = new int[SCENE_OBJECTS_COUNT]; - for (int i = 0; i < SCENE_OBJECTS_COUNT; ++i) { + for (int i = 0; i < kSceneObjectCount; ++i) { _sceneObjectsSortedByDistance[i] = -1; } } @@ -47,38 +44,35 @@ SceneObjects::~SceneObjects() { _vm = nullptr; _view = nullptr; _count = 0; - - delete[] _sceneObjectsSortedByDistance; - delete[] _sceneObjects; } void SceneObjects::clear() { - for (int 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]._isTarget = 0; - _sceneObjects[i]._isMoving = 0; - _sceneObjects[i]._isRetired = 0; + for (int i = 0; i < kSceneObjectCount; ++i) { + _sceneObjects[i].sceneObjectId = -1; + _sceneObjects[i].sceneObjectType = kSceneObjectTypeUnknown; + _sceneObjects[i].distanceToCamera = 0; + _sceneObjects[i].present = 0; + _sceneObjects[i].isClickable = 0; + _sceneObjects[i].isObstacle = 0; + _sceneObjects[i].unknown1 = 0; + _sceneObjects[i].isTarget = 0; + _sceneObjects[i].isMoving = 0; + _sceneObjects[i].isRetired = 0; } _count = 0; } bool SceneObjects::addActor(int sceneObjectId, BoundingBox *boundingBox, Common::Rect *screenRectangle, uint8 isClickable, uint8 isMoving, uint8 isTarget, uint8 isRetired) { - return addSceneObject(sceneObjectId, SceneObjectTypeActor, boundingBox, screenRectangle, isClickable, 0, 0, isTarget, isMoving, isRetired); + return addSceneObject(sceneObjectId, kSceneObjectTypeActor, boundingBox, screenRectangle, isClickable, 0, 0, isTarget, isMoving, isRetired); } bool SceneObjects::addObject(int sceneObjectId, BoundingBox *boundingBox, uint8 isClickable, uint8 isObstacle, uint8 unknown1, uint8 isTarget) { Common::Rect rect(-1, -1, -1, -1); - return addSceneObject(sceneObjectId, SceneObjectTypeObject, boundingBox, &rect, isClickable, isObstacle, unknown1, isTarget, 0, 0); + return addSceneObject(sceneObjectId, kSceneObjectTypeObject, boundingBox, &rect, isClickable, isObstacle, unknown1, isTarget, 0, 0); } bool SceneObjects::addItem(int sceneObjectId, BoundingBox *boundingBox, Common::Rect *screenRectangle, uint8 isTarget, uint8 isObstacle) { - return addSceneObject(sceneObjectId, SceneObjectTypeItem, boundingBox, screenRectangle, isObstacle, 0, 0, isTarget, 0, 0); + return addSceneObject(sceneObjectId, kSceneObjectTypeItem, boundingBox, screenRectangle, isObstacle, 0, 0, isTarget, 0, 0); } bool SceneObjects::remove(int sceneObjectId) { @@ -86,7 +80,7 @@ bool SceneObjects::remove(int sceneObjectId) { if (i == -1) { return false; } - _sceneObjects[i]._present = 0; + _sceneObjects[i].present = 0; int j; for (j = 0; j < _count; ++j) { if (_sceneObjectsSortedByDistance[j] == i) { @@ -101,31 +95,31 @@ bool SceneObjects::remove(int sceneObjectId) { return true; } -int SceneObjects::findByXYZ(int *isClickable, int *isObstacle, int *isTarget, float x, float y, float z, int findClickables, int findObstacles, int findTargets) { +int SceneObjects::findByXYZ(int *isClickable, int *isObstacle, int *isTarget, float x, float y, float z, int findClickables, int findObstacles, int findTargets) const { *isClickable = 0; *isObstacle = 0; *isTarget = 0; for (int i = 0; i < _count; ++i) { - assert(_sceneObjectsSortedByDistance[i] < SCENE_OBJECTS_COUNT); + assert(_sceneObjectsSortedByDistance[i] < kSceneObjectCount); - SceneObject &sceneObject = _sceneObjects[_sceneObjectsSortedByDistance[i]]; + const SceneObject *sceneObject = &_sceneObjects[_sceneObjectsSortedByDistance[i]]; - if ((findClickables && sceneObject._isClickable) || - (findObstacles && sceneObject._isObstacle) || - (findTargets && sceneObject._isTarget)) { - BoundingBox boundingBox = sceneObject._boundingBox; + if ((findClickables && sceneObject->isClickable) || + (findObstacles && sceneObject->isObstacle) || + (findTargets && sceneObject->isTarget)) { + BoundingBox boundingBox = sceneObject->boundingBox; - if (sceneObject._sceneObjectType == SceneObjectTypeObject || sceneObject._sceneObjectType == SceneObjectTypeItem) { + if (sceneObject->sceneObjectType == kSceneObjectTypeObject || sceneObject->sceneObjectType == kSceneObjectTypeItem) { 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; - *isTarget = sceneObject._isTarget; + *isClickable = sceneObject->isClickable; + *isObstacle = sceneObject->isObstacle; + *isTarget = sceneObject->isTarget; - return sceneObject._sceneObjectId; + return sceneObject->sceneObjectId; } } } @@ -133,33 +127,33 @@ int SceneObjects::findByXYZ(int *isClickable, int *isObstacle, int *isTarget, fl return -1; } -bool SceneObjects::existsOnXZ(int exceptSceneObjectId, float x, float z, bool a5, bool a6) { +bool SceneObjects::existsOnXZ(int exceptSceneObjectId, float x, float z, bool a5, bool a6) const { float xMin = x - 12.5f; float xMax = x + 12.5f; float zMin = z - 12.5f; float zMax = z + 12.5f; - int count = this->_count; + int count = _count; if (count > 0) { for (int i = 0; i < count; i++) { - SceneObject *sceneObject = &this->_sceneObjects[this->_sceneObjectsSortedByDistance[i]]; + const SceneObject *sceneObject = &_sceneObjects[_sceneObjectsSortedByDistance[i]]; bool v13 = false; - if (sceneObject->_sceneObjectType == SceneObjectTypeActor) { - if (sceneObject->_isRetired) { + if (sceneObject->sceneObjectType == kSceneObjectTypeActor) { + if (sceneObject->isRetired) { v13 = false; - } else if (sceneObject->_isMoving) { + } else if (sceneObject->isMoving) { v13 = a5 != 0; } else { v13 = a6 != 0; } } else { - v13 = sceneObject->_isObstacle; + v13 = sceneObject->isObstacle; } - if (v13 && sceneObject->_sceneObjectId != exceptSceneObjectId) { + if (v13 && sceneObject->sceneObjectId != exceptSceneObjectId) { float x1, y1, z1, x2, y2, z2; - sceneObject->_boundingBox.getXYZ(&x1, &y1, &z1, &x2, &y2, &z2); + sceneObject->boundingBox.getXYZ(&x1, &y1, &z1, &x2, &y2, &z2); if (z1 <= zMax && z2 >= zMin && x1 <= xMax && x2 >= xMin) { return true; } @@ -169,11 +163,11 @@ bool SceneObjects::existsOnXZ(int exceptSceneObjectId, float x, float z, bool a5 return false; } -int SceneObjects::findById(int sceneObjectId) { +int SceneObjects::findById(int sceneObjectId) const { for (int i = 0; i < _count; ++i) { int j = this->_sceneObjectsSortedByDistance[i]; - if (_sceneObjects[j]._present && _sceneObjects[j]._sceneObjectId == sceneObjectId) { + if (_sceneObjects[j].present && _sceneObjects[j].sceneObjectId == sceneObjectId) { return j; } } @@ -186,31 +180,31 @@ bool SceneObjects::addSceneObject(int sceneObjectId, SceneObjectType sceneObject return false; } - _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]._isTarget = isTarget; - _sceneObjects[index]._isMoving = isMoving; - _sceneObjects[index]._isRetired = isRetired; + _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].isTarget = isTarget; + _sceneObjects[index].isMoving = isMoving; + _sceneObjects[index].isRetired = isRetired; - float centerZ = (_sceneObjects[index]._boundingBox.getZ0() + _sceneObjects[index]._boundingBox.getZ1()) / 2.0; + float centerZ = (_sceneObjects[index].boundingBox.getZ0() + _sceneObjects[index].boundingBox.getZ1()) / 2.0; float distanceToCamera = fabs(_view->_cameraPosition.z - centerZ); - _sceneObjects[index]._distanceToCamera = distanceToCamera; + _sceneObjects[index].distanceToCamera = distanceToCamera; // insert according to distance from camera int i; for (i = 0; i < _count; ++i) { - if (distanceToCamera < _sceneObjects[_sceneObjectsSortedByDistance[i]]._distanceToCamera) { + if (distanceToCamera < _sceneObjects[_sceneObjectsSortedByDistance[i]].distanceToCamera) { break; } } - for (int j = _count - 2; j >= i; --j) { + for (int j = CLIP(_count - 1, 0, kSceneObjectCount - 2); j >= i; --j) { _sceneObjectsSortedByDistance[j + 1] = _sceneObjectsSortedByDistance[j]; } @@ -219,9 +213,9 @@ bool SceneObjects::addSceneObject(int sceneObjectId, SceneObjectType sceneObject return true; } -int SceneObjects::findEmpty() { - for (int i = 0; i < SCENE_OBJECTS_COUNT; ++i) { - if (!_sceneObjects[i]._present) +int SceneObjects::findEmpty() const { + for (int i = 0; i < kSceneObjectCount; ++i) { + if (!_sceneObjects[i].present) return i; } return -1; @@ -232,7 +226,7 @@ void SceneObjects::setMoving(int sceneObjectId, bool isMoving) { if (i == -1) { return; } - _sceneObjects[i]._isMoving = isMoving; + _sceneObjects[i].isMoving = isMoving; } void SceneObjects::setRetired(int sceneObjectId, bool isRetired) { @@ -240,17 +234,17 @@ void SceneObjects::setRetired(int sceneObjectId, bool isRetired) { if (i == -1) { return; } - _sceneObjects[i]._isRetired = isRetired; + _sceneObjects[i].isRetired = isRetired; } -bool SceneObjects::isBetweenTwoXZ(int sceneObjectId, float x1, float z1, float x2, float z2) { +bool SceneObjects::isBetweenTwoXZ(int sceneObjectId, float x1, float z1, float x2, float z2) const { int i = findById(sceneObjectId); if (i == -1) { return false; } float objectX1, objectY1, objectZ1, objectX2, objectY2, objectZ2; - _sceneObjects[i]._boundingBox.getXYZ(&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) @@ -267,7 +261,7 @@ void SceneObjects::setIsClickable(int sceneObjectId, bool isClickable) { if (i == -1) { return; } - _sceneObjects[i]._isClickable = isClickable; + _sceneObjects[i].isClickable = isClickable; } void SceneObjects::setIsObstacle(int sceneObjectId, bool isObstacle) { @@ -275,7 +269,7 @@ void SceneObjects::setIsObstacle(int sceneObjectId, bool isObstacle) { if (i == -1) { return; } - _sceneObjects[i]._isObstacle = isObstacle; + _sceneObjects[i].isObstacle = isObstacle; } void SceneObjects::setIsTarget(int sceneObjectId, bool isTarget) { @@ -283,18 +277,17 @@ void SceneObjects::setIsTarget(int sceneObjectId, bool isTarget) { if (i == -1) { return; } - _sceneObjects[i]._isTarget = isTarget; + _sceneObjects[i].isTarget = isTarget; } - void SceneObjects::updateObstacles() { _vm->_obstacles->clear(); for(int i = 0; i < _count; i++) { int index = _sceneObjectsSortedByDistance[i]; SceneObject sceneObject = _sceneObjects[index]; - if(sceneObject._isObstacle) { + if(sceneObject.isObstacle) { float x0, y0, z0, x1, y1, z1; - sceneObject._boundingBox.getXYZ(&x0, &y0, &z0, &x1, &y1, &z1); + sceneObject.boundingBox.getXYZ(&x0, &y0, &z0, &x1, &y1, &z1); _vm->_obstacles->add(x0, z0, x1, z1); } } diff --git a/engines/bladerunner/scene_objects.h b/engines/bladerunner/scene_objects.h index 010dc43532..b873980d05 100644 --- a/engines/bladerunner/scene_objects.h +++ b/engines/bladerunner/scene_objects.h @@ -33,66 +33,69 @@ class BladeRunnerEngine; class View; enum SceneObjectType { - SceneObjectTypeUnknown = -1, - SceneObjectTypeActor = 0, - SceneObjectTypeObject = 1, - SceneObjectTypeItem = 2 + kSceneObjectTypeUnknown = -1, + kSceneObjectTypeActor = 0, + kSceneObjectTypeObject = 1, + kSceneObjectTypeItem = 2 }; -#define SCENE_OBJECTS_COUNT 115 -#define SCENE_OBJECTS_ACTORS_OFFSET 0 -#define SCENE_OBJECTS_ITEMS_OFFSET 74 -#define SCENE_OBJECTS_OBJECTS_OFFSET 198 - -struct SceneObject { - int _sceneObjectId; - SceneObjectType _sceneObjectType; - BoundingBox _boundingBox; - Common::Rect _screenRectangle; - float _distanceToCamera; - int _present; - int _isClickable; - int _isObstacle; - int _unknown1; - int _isTarget; - int _isMoving; - int _isRetired; +enum SceneObjectOffset { + kSceneObjectOffsetActors = 0, + kSceneObjectOffsetItems = 74, + kSceneObjectOffsetObjects = 198 }; class SceneObjects { -#if _DEBUG +#if BLADERUNNER_DEBUG_RENDERING friend class BladeRunnerEngine; #endif + static const int kSceneObjectCount = 115; + + struct SceneObject { + int sceneObjectId; + SceneObjectType sceneObjectType; + BoundingBox boundingBox; + Common::Rect screenRectangle; + float distanceToCamera; + int present; + int isClickable; + int isObstacle; + int unknown1; + int isTarget; + int isMoving; + int isRetired; + }; + BladeRunnerEngine *_vm; -private: View *_view; int _count; - SceneObject *_sceneObjects; - int *_sceneObjectsSortedByDistance; + SceneObject _sceneObjects[kSceneObjectCount]; + int _sceneObjectsSortedByDistance[kSceneObjectCount]; public: SceneObjects(BladeRunnerEngine *vm, View *view); ~SceneObjects(); + bool addActor(int sceneObjectId, BoundingBox *boundingBox, Common::Rect *screenRectangle, uint8 isClickable, uint8 unknown1, uint8 isTarget, uint8 isRetired); bool addObject(int sceneObjectId, BoundingBox *boundingBox, uint8 isClickable, uint8 isObstacle, uint8 unknown1, uint8 isTarget); bool addItem(int sceneObjectId, BoundingBox *boundingBox, Common::Rect *screenRectangle, uint8 isTarget, uint8 isObstacle); bool remove(int sceneObjectId); void clear(); - int findByXYZ(int *isClickable, int *isObstacle, int *isTarget, float x, float y, float z, int findClickables, int findObstacles, int findTargets); - bool existsOnXZ(int exceptSceneObjectId, float x, float z, bool a5, bool a6); + int findByXYZ(int *isClickable, int *isObstacle, int *isTarget, float x, float y, float z, int findClickables, int findObstacles, int findTargets) const; + bool existsOnXZ(int exceptSceneObjectId, float x, float z, bool a5, bool a6) const; void setMoving(int sceneObjectId, bool isMoving); void setRetired(int sceneObjectId, bool isRetired); - bool isBetweenTwoXZ(int sceneObjectId, float x1, float z1, float x2, float z2); + bool isBetweenTwoXZ(int sceneObjectId, float x1, float z1, float x2, float z2) const; void setIsClickable(int sceneObjectId, bool isClickable); void setIsObstacle(int sceneObjectId, bool isObstacle); void setIsTarget(int sceneObjectId, bool isTarget); void updateObstacles(); private: - int findById(int sceneObjectId); + int findById(int sceneObjectId) const; bool addSceneObject(int sceneObjectId, SceneObjectType sceneObjectType, BoundingBox *boundingBox, Common::Rect *screenRectangle, uint8 isClickable, uint8 isObstacle, uint8 unknown1, uint8 isTarget, uint unknown2, uint isRetired); - int findEmpty(); + int findEmpty() const; }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/screen_effects.cpp b/engines/bladerunner/screen_effects.cpp index 70c872b746..a65d4edcbd 100644 --- a/engines/bladerunner/screen_effects.cpp +++ b/engines/bladerunner/screen_effects.cpp @@ -26,7 +26,8 @@ namespace BladeRunner { -ScreenEffects::ScreenEffects(BladeRunnerEngine *vm, int size) : _vm(vm) { +ScreenEffects::ScreenEffects(BladeRunnerEngine *vm, int size) { + _vm = vm; _dataSize = size; _data = new uint8[size]; _entries.reserve(8); @@ -37,17 +38,17 @@ ScreenEffects::~ScreenEffects() { } void ScreenEffects::readVqa(Common::SeekableReadStream *stream) { - uint8* dataPtr = _data; + uint8 *dataPtr = _data; int dataSize = _dataSize; - int entriesCount = stream->readUint32LE(); + int entryCount = stream->readUint32LE(); - if (entriesCount == 0) { + if (entryCount == 0) { return; } - entriesCount = MIN(entriesCount, 7); - _entries.resize(entriesCount); + entryCount = MIN(entryCount, 7); + _entries.resize(entryCount); for (Common::Array<Entry>::iterator entry = _entries.begin(); entry != _entries.end(); entry++) { stream->read(&entry->palette, sizeof(Color256) * 16); @@ -120,12 +121,12 @@ void ScreenEffects::readVqa(Common::SeekableReadStream *stream) { // return false; //} -void ScreenEffects::getColor(Color256 *outColor, uint16 x, uint16 y, uint16 z) { +void ScreenEffects::getColor(Color256 *outColor, uint16 x, uint16 y, uint16 z) const { Color256 color = { 0, 0, 0 }; - for (Common::Array<Entry>::iterator entry = _entries.begin(); entry != _entries.end(); entry++) { + for (Common::Array<const Entry>::iterator entry = _entries.begin(); entry != _entries.end(); entry++) { uint16 x1 = (x / 2) - entry->x; uint16 y1 = (y / 2) - entry->y; - if ( x1 < entry->width && y1 < entry->height && z > entry->z) { + if (x1 < entry->width && y1 < entry->height && z > entry->z) { int colorIndex = entry->data[y1 * entry->width + x1]; Color256 entryColor = entry->palette[colorIndex]; color.r += entryColor.r; diff --git a/engines/bladerunner/screen_effects.h b/engines/bladerunner/screen_effects.h index 1ffb68413f..ad0fb5090f 100644 --- a/engines/bladerunner/screen_effects.h +++ b/engines/bladerunner/screen_effects.h @@ -37,8 +37,7 @@ class BladeRunnerEngine; class ScreenEffects { public: - struct Entry - { + struct Entry { Color256 palette[16]; uint16 x; uint16 y; @@ -59,7 +58,7 @@ public: ~ScreenEffects(); void readVqa(Common::SeekableReadStream *stream); - void getColor(Color256 *outColor, uint16 x, uint16 y, uint16 z); + void getColor(Color256 *outColor, uint16 x, uint16 y, uint16 z) const ; //TODO //bool isAffectingArea(int x, int y, int width, int height, int unk); diff --git a/engines/bladerunner/script/ai.cpp b/engines/bladerunner/script/ai.cpp index ade27e417f..f61b0212a7 100644 --- a/engines/bladerunner/script/ai.cpp +++ b/engines/bladerunner/script/ai.cpp @@ -28,11 +28,13 @@ namespace BladeRunner { -AIScripts::AIScripts(BladeRunnerEngine *vm, int actorsCount) : _vm(vm), _inScriptCounter(0) { - _actorsCount = actorsCount; - _actorUpdating = new bool[actorsCount]; - _AIScripts = new AIScriptBase*[actorsCount]; - for (int i = 0; i < actorsCount; ++i) { +AIScripts::AIScripts(BladeRunnerEngine *vm, int actorCount) { + _vm = vm; + _inScriptCounter = 0; + _actorCount = actorCount; + _actorUpdating = new bool[actorCount]; + _AIScripts = new AIScriptBase*[actorCount]; + for (int i = 0; i < actorCount; ++i) { _AIScripts[i] = nullptr; _actorUpdating[i] = false; } @@ -45,7 +47,7 @@ AIScripts::AIScripts(BladeRunnerEngine *vm, int actorsCount) : _vm(vm), _inScrip } AIScripts::~AIScripts() { - for (int i = 0; i < _actorsCount; ++i) { + for (int i = 0; i < _actorCount; ++i) { delete _AIScripts[i]; _AIScripts[i] = nullptr; } @@ -54,14 +56,14 @@ AIScripts::~AIScripts() { } void AIScripts::Initialize(int actor) { - assert(actor < _actorsCount); + assert(actor < _actorCount); if (_AIScripts[actor]) { _AIScripts[actor]->Initialize(); } } void AIScripts::Update(int actor) { - assert(actor < _actorsCount); + assert(actor < _actorCount); if (this->_actorUpdating[actor] != 1) { this->_actorUpdating[actor] = true; ++this->_inScriptCounter; @@ -73,7 +75,7 @@ void AIScripts::Update(int actor) { } void AIScripts::TimerExpired(int actor, int timer) { - assert(actor < _actorsCount); + assert(actor < _actorCount); _inScriptCounter++; if (_AIScripts[actor]) { _AIScripts[actor]->TimerExpired(timer); @@ -82,7 +84,7 @@ void AIScripts::TimerExpired(int actor, int timer) { } void AIScripts::CompletedMovementTrack(int actor) { - assert(actor < _actorsCount); + assert(actor < _actorCount); if (!_vm->_actors[actor]->inCombat()) { _inScriptCounter++; if (_AIScripts[actor]) { @@ -93,7 +95,7 @@ void AIScripts::CompletedMovementTrack(int actor) { } void AIScripts::ReceivedClue(int actor, int clueId, int fromActorId) { - assert(actor < _actorsCount); + assert(actor < _actorCount); _inScriptCounter++; if (_AIScripts[actor]) { _AIScripts[actor]->ReceivedClue(clueId, fromActorId); @@ -102,7 +104,7 @@ void AIScripts::ReceivedClue(int actor, int clueId, int fromActorId) { } void AIScripts::ClickedByPlayer(int actor) { - assert(actor < _actorsCount); + assert(actor < _actorCount); if(_vm->_actors[actor]->inCombat()) { return; @@ -116,7 +118,7 @@ void AIScripts::ClickedByPlayer(int actor) { } void AIScripts::EnteredScene(int actor, int setId) { - assert(actor < _actorsCount); + assert(actor < _actorCount); _inScriptCounter++; if (_AIScripts[actor]) { _AIScripts[actor]->EnteredScene(setId); @@ -125,7 +127,7 @@ void AIScripts::EnteredScene(int actor, int setId) { } void AIScripts::OtherAgentEnteredThisScene(int actor, int otherActorId) { - assert(actor < _actorsCount); + assert(actor < _actorCount); _inScriptCounter++; if (_AIScripts[actor]) { _AIScripts[actor]->OtherAgentEnteredThisScene(otherActorId); @@ -134,7 +136,7 @@ void AIScripts::OtherAgentEnteredThisScene(int actor, int otherActorId) { } void AIScripts::OtherAgentExitedThisScene(int actor, int otherActorId) { - assert(actor < _actorsCount); + assert(actor < _actorCount); _inScriptCounter++; if (_AIScripts[actor]) { _AIScripts[actor]->OtherAgentExitedThisScene(otherActorId); @@ -143,7 +145,7 @@ void AIScripts::OtherAgentExitedThisScene(int actor, int otherActorId) { } void AIScripts::Retired(int actor, int retiredByActorId) { - assert(actor < _actorsCount); + assert(actor < _actorCount); _inScriptCounter++; if (_AIScripts[actor]) { _AIScripts[actor]->Retired(retiredByActorId); @@ -152,7 +154,7 @@ void AIScripts::Retired(int actor, int retiredByActorId) { } void AIScripts::GoalChanged(int actor, int currentGoalNumber, int newGoalNumber) { - assert(actor < _actorsCount); + assert(actor < _actorCount); _inScriptCounter++; if (_AIScripts[actor]) { _AIScripts[actor]->GoalChanged(currentGoalNumber, newGoalNumber); @@ -161,7 +163,7 @@ void AIScripts::GoalChanged(int actor, int currentGoalNumber, int newGoalNumber) } bool AIScripts::ReachedMovementTrackWaypoint(int actor, int waypointId) { - assert(actor < _actorsCount); + assert(actor < _actorCount); bool result = false; if (!_vm->_actors[actor]->inCombat()) { _inScriptCounter++; @@ -174,7 +176,7 @@ bool AIScripts::ReachedMovementTrackWaypoint(int actor, int waypointId) { } void AIScripts::UpdateAnimation(int actor, int *animation, int *frame) { - assert(actor < _actorsCount); + assert(actor < _actorCount); _inScriptCounter++; if (_AIScripts[actor]) { _AIScripts[actor]->UpdateAnimation(animation, frame); @@ -183,7 +185,7 @@ void AIScripts::UpdateAnimation(int actor, int *animation, int *frame) { } void AIScripts::ChangeAnimationMode(int actor, int mode) { - assert(actor < _actorsCount); + assert(actor < _actorCount); _inScriptCounter++; if (_AIScripts[actor]) { _AIScripts[actor]->ChangeAnimationMode(mode); diff --git a/engines/bladerunner/script/ai.h b/engines/bladerunner/script/ai.h index 9f2caa094b..135aef5e9c 100644 --- a/engines/bladerunner/script/ai.h +++ b/engines/bladerunner/script/ai.h @@ -174,11 +174,11 @@ class AIScripts { private: BladeRunnerEngine *_vm; int _inScriptCounter; - int _actorsCount; + int _actorCount; AIScriptBase **_AIScripts; bool *_actorUpdating; public: - AIScripts(BladeRunnerEngine *vm, int actorsCount); + AIScripts(BladeRunnerEngine *vm, int actorCount); ~AIScripts(); void Initialize(int actor); diff --git a/engines/bladerunner/script/esper.cpp b/engines/bladerunner/script/esper.cpp index 873841b839..ca779d6e3d 100644 --- a/engines/bladerunner/script/esper.cpp +++ b/engines/bladerunner/script/esper.cpp @@ -26,7 +26,7 @@ namespace BladeRunner { -void ScriptESPER::SCRIPT_ESPER_DLL_Initialize() { +void ESPERScript::SCRIPT_ESPER_DLL_Initialize() { int v0 = 0; if (Actor_Clue_Query(kActorMcCoy, kClueRuncitersVideo)) { if (!Actor_Clue_Query(kActorMcCoy, kClueRuncitersViewA)) { @@ -88,7 +88,7 @@ void ScriptESPER::SCRIPT_ESPER_DLL_Initialize() { } } -void ScriptESPER::SCRIPT_ESPER_DLL_Photo_Selected(int photo) { +void ESPERScript::SCRIPT_ESPER_DLL_Photo_Selected(int photo) { switch (photo) { case 9: Actor_Says(kActorAnsweringMachine, 270, 3); @@ -151,7 +151,7 @@ void ScriptESPER::SCRIPT_ESPER_DLL_Photo_Selected(int photo) { } } -bool ScriptESPER::SCRIPT_ESPER_DLL_Special_Region_Selected(int photo, int region) { +bool ESPERScript::SCRIPT_ESPER_DLL_Special_Region_Selected(int photo, int region) { switch (photo) { case 9: switch (region) { diff --git a/engines/bladerunner/script/esper.h b/engines/bladerunner/script/esper.h index 9532e11b79..683ecf6998 100644 --- a/engines/bladerunner/script/esper.h +++ b/engines/bladerunner/script/esper.h @@ -29,9 +29,9 @@ namespace BladeRunner { class BladeRunnerEngine; -class ScriptESPER : ScriptBase { +class ESPERScript : ScriptBase { public: - ScriptESPER(BladeRunnerEngine *vm) + ESPERScript(BladeRunnerEngine *vm) : ScriptBase(vm) { } diff --git a/engines/bladerunner/script/kia.cpp b/engines/bladerunner/script/kia.cpp index 587e25d940..e0c875469d 100644 --- a/engines/bladerunner/script/kia.cpp +++ b/engines/bladerunner/script/kia.cpp @@ -23,10 +23,21 @@ #include "bladerunner/script/kia.h" #include "bladerunner/bladerunner.h" +#include "bladerunner/mouse.h" +#include "bladerunner/ui/kia.h" namespace BladeRunner { -void ScriptKIA::SCRIPT_KIA_DLL_Play_Clue_Asset_Script(int a1, int clueId) { +KIAScript::KIAScript(BladeRunnerEngine *vm) : ScriptBase(vm) {} + +void KIAScript::playClueAssetScript(int a1, int clueId) { + _vm->_kia->playerReset(); + _vm->_mouse->disable(); + SCRIPT_KIA_DLL_Play_Clue_Asset_Script(a1, clueId); + _vm->_mouse->enable(); +} + +void KIAScript::SCRIPT_KIA_DLL_Play_Clue_Asset_Script(int a1, int clueId) { int v1; switch (clueId) { case 0: diff --git a/engines/bladerunner/script/kia.h b/engines/bladerunner/script/kia.h index d7b5836e8d..9ad815b37b 100644 --- a/engines/bladerunner/script/kia.h +++ b/engines/bladerunner/script/kia.h @@ -29,15 +29,14 @@ namespace BladeRunner { class BladeRunnerEngine; -class ScriptKIA : ScriptBase { +class KIAScript : ScriptBase { public: - ScriptKIA(BladeRunnerEngine *vm) - : ScriptBase(vm) { - } + KIAScript(BladeRunnerEngine *vm); - void SCRIPT_KIA_DLL_Play_Clue_Asset_Script(int a1, int clueId); + void playClueAssetScript(int a1, int clueId); private: + void SCRIPT_KIA_DLL_Play_Clue_Asset_Script(int a1, int clueId); }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/script/scene/ct01.cpp b/engines/bladerunner/script/scene/ct01.cpp index 21e6fc7600..6a4d1e4c87 100644 --- a/engines/bladerunner/script/scene/ct01.cpp +++ b/engines/bladerunner/script/scene/ct01.cpp @@ -385,7 +385,7 @@ void SceneScriptCT01::PlayerWalkedIn() { Loop_Actor_Walk_To_XYZ(kActorMcCoy, -314.0f, -6.5f, 326.0f, 0, 0, false, 0); if (!Game_Flag_Query(25)) { Game_Flag_Set(25); - if (!Game_Flag_Query(378)) { + if (!Game_Flag_Query(kFlagDirectorsCut)) { Actor_Voice_Over(200, kActorVoiceOver); Actor_Voice_Over(210, kActorVoiceOver); Actor_Voice_Over(220, kActorVoiceOver); diff --git a/engines/bladerunner/script/scene/ct06.cpp b/engines/bladerunner/script/scene/ct06.cpp index e26b65c780..cebf9d1eef 100644 --- a/engines/bladerunner/script/scene/ct06.cpp +++ b/engines/bladerunner/script/scene/ct06.cpp @@ -99,7 +99,7 @@ bool SceneScriptCT06::ClickedOnActor(int actorId) { Actor_Voice_Over(350, kActorVoiceOver); Actor_Voice_Over(360, kActorVoiceOver); Actor_Voice_Over(370, kActorVoiceOver); - if (!Game_Flag_Query(378)) { + if (!Game_Flag_Query(kFlagDirectorsCut)) { Actor_Voice_Over(380, kActorVoiceOver); Actor_Voice_Over(390, kActorVoiceOver); Actor_Voice_Over(400, kActorVoiceOver); diff --git a/engines/bladerunner/script/scene/kp01.cpp b/engines/bladerunner/script/scene/kp01.cpp index 0a5dd24cd0..e70a8d5375 100644 --- a/engines/bladerunner/script/scene/kp01.cpp +++ b/engines/bladerunner/script/scene/kp01.cpp @@ -119,7 +119,7 @@ void SceneScriptKP01::SceneFrameAdvanced(int frame) { void SceneScriptKP01::ActorChangedGoal(int actorId, int newGoal, int oldGoal, bool currentSet) { if (actorId == 1) { if (newGoal == 422) { - if (Game_Flag_Query(378) == 1) { + if (Game_Flag_Query(kFlagDirectorsCut) == 1) { Delay(500); Actor_Change_Animation_Mode(kActorMcCoy, 75); Delay(4500); diff --git a/engines/bladerunner/script/scene/ma02.cpp b/engines/bladerunner/script/scene/ma02.cpp index add20cbcdf..62b5d68cf9 100644 --- a/engines/bladerunner/script/scene/ma02.cpp +++ b/engines/bladerunner/script/scene/ma02.cpp @@ -177,11 +177,11 @@ void SceneScriptMA02::PlayerWalkedIn() { Game_Flag_Set(60); Actor_Face_Actor(kActorMcCoy, kActorMaggie, true); Actor_Voice_Over(1210, kActorVoiceOver); - if (!Game_Flag_Query(378)) { + if (!Game_Flag_Query(kFlagDirectorsCut)) { Actor_Voice_Over(1220, kActorVoiceOver); } Actor_Voice_Over(1230, kActorVoiceOver); - if (!Game_Flag_Query(378)) { + if (!Game_Flag_Query(kFlagDirectorsCut)) { Actor_Voice_Over(1240, kActorVoiceOver); Actor_Voice_Over(1250, kActorVoiceOver); } diff --git a/engines/bladerunner/script/scene/ma04.cpp b/engines/bladerunner/script/scene/ma04.cpp index a7725f95e3..4b2e65ef98 100644 --- a/engines/bladerunner/script/scene/ma04.cpp +++ b/engines/bladerunner/script/scene/ma04.cpp @@ -177,7 +177,7 @@ bool SceneScriptMA04::ClickedOn2DRegion(int region) { Delay(500); Actor_Says(kActorClovis, 310, 3); Actor_Says(kActorClovis, 320, 3); - if (!Game_Flag_Query(378) && Global_Variable_Query(1) < 3) { + if (!Game_Flag_Query(kFlagDirectorsCut) && Global_Variable_Query(1) < 3) { Actor_Voice_Over(1300, kActorVoiceOver); Actor_Voice_Over(1310, kActorVoiceOver); Actor_Voice_Over(1320, kActorVoiceOver); @@ -193,7 +193,7 @@ bool SceneScriptMA04::ClickedOn2DRegion(int region) { Delay(500); Actor_Says(kActorLucy, 500, 3); Actor_Says(kActorLucy, 510, 3); - if (!Game_Flag_Query(378) && Global_Variable_Query(1) < 3) { + if (!Game_Flag_Query(kFlagDirectorsCut) && Global_Variable_Query(1) < 3) { Actor_Voice_Over(1330, kActorVoiceOver); Actor_Voice_Over(1340, kActorVoiceOver); Actor_Voice_Over(1350, kActorVoiceOver); @@ -204,7 +204,7 @@ bool SceneScriptMA04::ClickedOn2DRegion(int region) { return true; } Actor_Says(kActorMcCoy, 2670, 13); - if (!Game_Flag_Query(378)) { + if (!Game_Flag_Query(kFlagDirectorsCut)) { Actor_Says(kActorMcCoy, 2675, 17); } } @@ -400,7 +400,7 @@ void SceneScriptMA04::sub_402F2C() { if (Game_Flag_Query(165) || Actor_Query_Goal_Number(kActorCrazylegs) == 2) { Actor_Says(kActorLucy, 630, 3); Actor_Says_With_Pause(kActorMcCoy, 2575, 0.0f, 15); - if (!Game_Flag_Query(378)) { + if (!Game_Flag_Query(kFlagDirectorsCut)) { Actor_Says(kActorLucy, 640, 3); } Actor_Clue_Acquire(kActorMcCoy, kCluePhoneCallLucy2, true, -1); @@ -413,7 +413,7 @@ void SceneScriptMA04::sub_402F2C() { Actor_Says(kActorMcCoy, 2570, 13); Actor_Says_With_Pause(kActorLucy, 630, 0.0f, 3); Actor_Says_With_Pause(kActorMcCoy, 2575, 0.0f, 15); - if (!Game_Flag_Query(378)) { + if (!Game_Flag_Query(kFlagDirectorsCut)) { Actor_Says(kActorLucy, 640, 3); } Actor_Clue_Acquire(kActorMcCoy, kCluePhoneCallLucy1, true, -1); diff --git a/engines/bladerunner/script/scene/ma05.cpp b/engines/bladerunner/script/scene/ma05.cpp index 51ae26a7b4..a1f3288b0e 100644 --- a/engines/bladerunner/script/scene/ma05.cpp +++ b/engines/bladerunner/script/scene/ma05.cpp @@ -111,7 +111,7 @@ void SceneScriptMA05::PlayerWalkedIn() { Sound_Play(69, 100, 0, 0, 50); } if (Game_Flag_Query(146) && !Game_Flag_Query(61)) { - if (!Game_Flag_Query(378)) { + if (!Game_Flag_Query(kFlagDirectorsCut)) { Actor_Voice_Over(1260, kActorVoiceOver); Actor_Voice_Over(1270, kActorVoiceOver); Actor_Voice_Over(1280, kActorVoiceOver); diff --git a/engines/bladerunner/script/scene/nr08.cpp b/engines/bladerunner/script/scene/nr08.cpp index 70b8542173..b00daff531 100644 --- a/engines/bladerunner/script/scene/nr08.cpp +++ b/engines/bladerunner/script/scene/nr08.cpp @@ -184,7 +184,7 @@ void SceneScriptNR08::PlayerWalkedIn() { } if (Actor_Query_Goal_Number(kActorSteele) == 231) { Actor_Says(kActorSteele, 1640, 12); - if (!Game_Flag_Query(378)) { + if (!Game_Flag_Query(kFlagDirectorsCut)) { Actor_Says(kActorMcCoy, 3790, 13); Actor_Says(kActorSteele, 1650, 14); } diff --git a/engines/bladerunner/script/scene/rc01.cpp b/engines/bladerunner/script/scene/rc01.cpp index 8a5b728c86..79bf1045ce 100644 --- a/engines/bladerunner/script/scene/rc01.cpp +++ b/engines/bladerunner/script/scene/rc01.cpp @@ -27,20 +27,24 @@ namespace BladeRunner { void SceneScriptRC01::InitializeScene() { #if _DEBUG //TODO: not part of game, remove - //Game_Flag_Set(kFlagIntroPlayed); // force skip intro + // Game_Flag_Set(kFlagIntroPlayed); // force skip intro + // Game_Flag_Set(kFlagRC02toRC01); // no landing + // Game_Flag_Set(kFlagRC01PoliceDone); + // Game_Flag_Set(249); + // Game_Flag_Set(kFlagKIAPrivacyAddon); #endif if (!Game_Flag_Query(kFlagIntroPlayed)) { Ambient_Sounds_Remove_All_Non_Looping_Sounds(true); Ambient_Sounds_Remove_All_Looping_Sounds(1); - Outtake_Play(28, 1, -1); // WSTLGO_E.VQA - Outtake_Play(41, 1, -1); // BRLOGO_E.VQA - Outtake_Play(0, 0, -1); // INTRO_E.VQA - Outtake_Play(33, 1, -1); // DSCENT_E.VQA + Outtake_Play(kOuttakeWestwood, true, -1); + Outtake_Play(kOuttakeBladeRunner, true, -1); + Outtake_Play(kOuttakeIntro, false, -1); + Outtake_Play(kOuttakeDescent, true, -1); } - if (Game_Flag_Query(9)) { + if (Game_Flag_Query(kFlagRC02toRC01)) { Setup_Scene_Information(-171.16f, 5.55f, 27.28f, 616); - } else if (Game_Flag_Query(114)) { + } else if (Game_Flag_Query(kFlagRC03toRC01)) { Setup_Scene_Information(-471.98f, -0.30f, 258.15f, 616); } else { Setup_Scene_Information(-10.98f, -0.30f, 318.15f, 616); @@ -84,7 +88,7 @@ void SceneScriptRC01::InitializeScene() { Ambient_Sounds_Add_Sound(87, 20, 80, 20, 40, -100, 100, -101, -101, 0, 0); // SIREN2.AUD if (Game_Flag_Query(kFlagRC01PoliceDone)) { - if (!Game_Flag_Query(9) && !Game_Flag_Query(114)) { + if (!Game_Flag_Query(kFlagRC02toRC01) && !Game_Flag_Query(kFlagRC03toRC01)) { Scene_Loop_Start_Special(kSceneLoopModeLoseControl, 5, false); } if (Game_Flag_Query(249)) { @@ -93,7 +97,7 @@ void SceneScriptRC01::InitializeScene() { Scene_Loop_Set_Default(10); } } else { - if (!Game_Flag_Query(9) && !Game_Flag_Query(114)) { + if (!Game_Flag_Query(kFlagRC02toRC01) && !Game_Flag_Query(kFlagRC03toRC01)) { Scene_Loop_Start_Special(kSceneLoopModeLoseControl, 0, false); } Scene_Loop_Set_Default(1); @@ -185,7 +189,7 @@ void SceneScriptRC01::SceneLoaded() { ADQ_Flush(); Actor_Voice_Over(1830, kActorVoiceOver); Actor_Voice_Over(1850, kActorVoiceOver); - if (!Game_Flag_Query(378)) { + if (!Game_Flag_Query(kFlagDirectorsCut)) { Actor_Voice_Over(1860, kActorVoiceOver); I_Sez("MG: Is David Leary a self-respecting human or is he powered by rechargeable"); I_Sez("batteries?\n"); @@ -574,22 +578,22 @@ void SceneScriptRC01::ActorChangedGoal(int actorId, int newGoal, int oldGoal, bo } void SceneScriptRC01::PlayerWalkedIn() { - if (Game_Flag_Query(249) && !Game_Flag_Query(9) && !Game_Flag_Query(114)) { + if (Game_Flag_Query(249) && !Game_Flag_Query(kFlagRC02toRC01) && !Game_Flag_Query(kFlagRC03toRC01)) { walkToCenter(); } - if (Game_Flag_Query(114)) { + if (Game_Flag_Query(kFlagRC03toRC01)) { Player_Loses_Control(); Loop_Actor_Walk_To_XYZ(kActorMcCoy, -415.98f, -0.30f, 262.15f, 0, 0, false, 0); Player_Gains_Control(); - Game_Flag_Reset(114); + Game_Flag_Reset(kFlagRC03toRC01); } - if (Game_Flag_Query(9)) { + if (Game_Flag_Query(kFlagRC02toRC01)) { Player_Loses_Control(); Loop_Actor_Walk_To_XYZ(kActorMcCoy, -203.45f, 5.55f, 85.05f, 0, 0, false, 0); Player_Gains_Control(); - Game_Flag_Reset(9); + Game_Flag_Reset(kFlagRC02toRC01); if (Game_Flag_Query(1) && !Game_Flag_Query(4)) { Actor_Voice_Over(1910, kActorVoiceOver); diff --git a/engines/bladerunner/script/scene/rc02.cpp b/engines/bladerunner/script/scene/rc02.cpp index a518a489cd..18a08ad5b1 100644 --- a/engines/bladerunner/script/scene/rc02.cpp +++ b/engines/bladerunner/script/scene/rc02.cpp @@ -314,7 +314,7 @@ bool SceneScriptRC02::ClickedOnItem(int itemId, bool a2) { bool SceneScriptRC02::ClickedOnExit(int exitId) { if (exitId == 0) { if (!Loop_Actor_Walk_To_XYZ(kActorMcCoy, -71.51f, -1238.89f, 108587.15f, 0, 1, false, 0)) { - Game_Flag_Set(9); + Game_Flag_Set(kFlagRC02toRC01); Ambient_Sounds_Remove_All_Non_Looping_Sounds(1); Ambient_Sounds_Remove_Looping_Sound(71, true); Ambient_Sounds_Remove_Looping_Sound(75, true); diff --git a/engines/bladerunner/script/scene/rc03.cpp b/engines/bladerunner/script/scene/rc03.cpp index efdc54449e..2af0a8e8ef 100644 --- a/engines/bladerunner/script/scene/rc03.cpp +++ b/engines/bladerunner/script/scene/rc03.cpp @@ -140,7 +140,7 @@ bool SceneScriptRC03::ClickedOnExit(int exitId) { if (Game_Flag_Query(289)) { Game_Flag_Set(702); } - Game_Flag_Set(114); + Game_Flag_Set(kFlagRC03toRC01); Set_Enter(69, 78); Actor_Set_Goal_Number(kActorDektora, 100); } diff --git a/engines/bladerunner/script/scene/rc04.cpp b/engines/bladerunner/script/scene/rc04.cpp index fdd30cb4c1..827f836414 100644 --- a/engines/bladerunner/script/scene/rc04.cpp +++ b/engines/bladerunner/script/scene/rc04.cpp @@ -336,7 +336,7 @@ bool SceneScriptRC04::ClickedOnActor(int actorId) { Delay(3000); Item_Pickup_Spin_Effect(941, 405, 192); Actor_Says(kActorBulletBob, 2030, 30); - Game_Flag_Set(487); + Game_Flag_Set(kFlagKIAPrivacyAddon); } else { Actor_Says(kActorMcCoy, 8980, 16); Actor_Says(kActorBulletBob, 2040, 30); diff --git a/engines/bladerunner/script/script.cpp b/engines/bladerunner/script/script.cpp index aa3e23da52..8ef9b6a5ce 100644 --- a/engines/bladerunner/script/script.cpp +++ b/engines/bladerunner/script/script.cpp @@ -24,7 +24,7 @@ #include "bladerunner/actor.h" #include "bladerunner/actor_combat.h" -#include "bladerunner/adq.h" +#include "bladerunner/actor_dialogue_queue.h" #include "bladerunner/ambient_sounds.h" #include "bladerunner/audio_player.h" #include "bladerunner/audio_speech.h" @@ -32,9 +32,8 @@ #include "bladerunner/crimes_database.h" #include "bladerunner/combat.h" #include "bladerunner/dialogue_menu.h" -#include "bladerunner/elevator.h" -#include "bladerunner/gameflags.h" -#include "bladerunner/gameinfo.h" +#include "bladerunner/game_flags.h" +#include "bladerunner/game_info.h" #include "bladerunner/items.h" #include "bladerunner/item_pickup.h" #include "bladerunner/movement_track.h" @@ -48,9 +47,11 @@ #include "bladerunner/scene_objects.h" #include "bladerunner/slice_animations.h" #include "bladerunner/slice_renderer.h" -#include "bladerunner/spinner.h" #include "bladerunner/suspects_database.h" #include "bladerunner/text_resource.h" +#include "bladerunner/ui/elevator.h" +#include "bladerunner/ui/kia.h" +#include "bladerunner/ui/spinner.h" #include "bladerunner/vector.h" #include "bladerunner/waypoints.h" @@ -230,14 +231,14 @@ void ScriptBase::Actor_Set_Targetable(int actorId, bool targetable) { void ScriptBase::Actor_Says(int actorId, int sentenceId, int animationMode){ _vm->loopActorSpeaking(); - _vm->_adq->flush(1, true); + _vm->_actorDialogueQueue->flush(1, true); Actor_Says_With_Pause(actorId, sentenceId, 0.5f, animationMode); } void ScriptBase::Actor_Says_With_Pause(int actorId, int sentenceId, float pause, int animationMode) { _vm->gameWaitForActive(); _vm->loopActorSpeaking(); - _vm->_adq->flush(1, true); + _vm->_actorDialogueQueue->flush(1, true); Actor *actor = _vm->_actors[actorId]; @@ -285,35 +286,12 @@ void ScriptBase::Actor_Says_With_Pause(int actorId, int sentenceId, float pause, Player_Gains_Control(); } -#if 0 void ScriptBase::Actor_Voice_Over(int sentenceId, int actorId) { - // Wait for any existing speech to end - _vm->loopActorSpeaking(); - - // TODO: Hack - This needs to go through the actor class - char name[13]; - sprintf(name, "%02d-%04d.AUD", actorId, sentenceId); - _vm->_audioSpeech->playSpeech(name); - - // warning("start voice over loop"); - while (true) - { - _vm->gameTick(); - if (_vm->shouldQuit()) - break; - if (!_vm->_audioSpeech->isPlaying()) - break; - } - // warning("end voice over loop"); -} -#endif - -void ScriptBase::Actor_Voice_Over(int sentenceId, int actorId) { - assert(actorId < ACTORS_COUNT); + assert(actorId < BladeRunnerEngine::kActorCount); _vm->gameWaitForActive(); _vm->loopActorSpeaking(); - _vm->_adq->flush(1, true); + _vm->_actorDialogueQueue->flush(1, true); Actor *actor = _vm->_actors[actorId]; @@ -337,7 +315,7 @@ void ScriptBase::Actor_Start_Speech_Sample(int actorId, int sentenceId) { void ScriptBase::Actor_Start_Voice_Over_Sample(int sentenceId) { _vm->loopActorSpeaking(); - _vm->_actors[VOICEOVER_ACTOR]->speechPlay(sentenceId, true); + _vm->_actors[Actors::kActorVoiceOver]->speechPlay(sentenceId, true); } int ScriptBase::Actor_Query_Which_Set_In(int actorId) { @@ -380,11 +358,11 @@ bool ScriptBase::Actor_Query_In_Between_Two_Actors(int actorId, int otherActor1I float z1 = _vm->_actors[otherActor1Id]->getZ(); float x2 = _vm->_actors[otherActor2Id]->getX(); float z2 = _vm->_actors[otherActor2Id]->getZ(); - return _vm->_sceneObjects->isBetweenTwoXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x1, z1, x2, z1) - || _vm->_sceneObjects->isBetweenTwoXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x1 - 12.0f, z1 - 12.0f, x2 - 12.0f, z2 - 12.0f) - || _vm->_sceneObjects->isBetweenTwoXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x1 + 12.0f, z1 - 12.0f, x2 + 12.0f, z2 - 12.0f) - || _vm->_sceneObjects->isBetweenTwoXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x1 + 12.0f, z1 + 12.0f, x2 + 12.0f, z2 + 12.0f) - || _vm->_sceneObjects->isBetweenTwoXZ(actorId + SCENE_OBJECTS_ACTORS_OFFSET, x1 - 12.0f, z1 + 12.0f, x2 - 12.0f, z2 + 12.0f); + return _vm->_sceneObjects->isBetweenTwoXZ(actorId + kSceneObjectOffsetActors, x1, z1, x2, z1) + || _vm->_sceneObjects->isBetweenTwoXZ(actorId + kSceneObjectOffsetActors, x1 - 12.0f, z1 - 12.0f, x2 - 12.0f, z2 - 12.0f) + || _vm->_sceneObjects->isBetweenTwoXZ(actorId + kSceneObjectOffsetActors, x1 + 12.0f, z1 - 12.0f, x2 + 12.0f, z2 - 12.0f) + || _vm->_sceneObjects->isBetweenTwoXZ(actorId + kSceneObjectOffsetActors, x1 + 12.0f, z1 + 12.0f, x2 + 12.0f, z2 + 12.0f) + || _vm->_sceneObjects->isBetweenTwoXZ(actorId + kSceneObjectOffsetActors, x1 - 12.0f, z1 + 12.0f, x2 - 12.0f, z2 + 12.0f); } void ScriptBase::Actor_Set_Goal_Number(int actorId, int goalNumber) { @@ -594,11 +572,11 @@ bool ScriptBase::Actor_Clue_Query(int actorId, int clueId) { } void ScriptBase::Actor_Clues_Transfer_New_To_Mainframe(int actorId) { - _vm->_actors[actorId]->copyClues(VOICEOVER_ACTOR); + _vm->_actors[actorId]->copyClues(Actors::kActorVoiceOver); } void ScriptBase::Actor_Clues_Transfer_New_From_Mainframe(int actorId) { - _vm->_actors[VOICEOVER_ACTOR]->copyClues(actorId); + _vm->_actors[Actors::kActorVoiceOver]->copyClues(actorId); } void ScriptBase::Actor_Set_Invisible(int actorId, bool isInvisible) { @@ -1126,16 +1104,16 @@ void ScriptBase::Give_McCoy_Ammo(int ammoType, int ammo) { _vm->_settings->addAmmo(ammoType, ammo); } -void ScriptBase::Assign_Player_Gun_Hit_Sounds(int row, int soundId1, int soundId2, int soundId3) { - _vm->_combat->setHitSoundId(row, 0, soundId1); - _vm->_combat->setHitSoundId(row, 1, soundId2); - _vm->_combat->setHitSoundId(row, 2, soundId3); +void ScriptBase::Assign_Player_Gun_Hit_Sounds(int ammoType, int soundId1, int soundId2, int soundId3) { + _vm->_combat->setHitSound(ammoType, 0, soundId1); + _vm->_combat->setHitSound(ammoType, 1, soundId2); + _vm->_combat->setHitSound(ammoType, 2, soundId3); } -void ScriptBase::Assign_Player_Gun_Miss_Sounds(int row, int soundId1, int soundId2, int soundId3) { - _vm->_combat->setMissSoundId(row, 0, soundId1); - _vm->_combat->setMissSoundId(row, 1, soundId2); - _vm->_combat->setMissSoundId(row, 2, soundId3); +void ScriptBase::Assign_Player_Gun_Miss_Sounds(int ammoType, int soundId1, int soundId2, int soundId3) { + _vm->_combat->setMissSound(ammoType, 0, soundId1); + _vm->_combat->setMissSound(ammoType, 1, soundId2); + _vm->_combat->setMissSound(ammoType, 2, soundId3); } void ScriptBase::Disable_Shadows(int animationsIdsList[], int listSize) { @@ -1152,7 +1130,7 @@ void ScriptBase::Actor_Retired_Here(int actorId, int width, int height, int reti actor->getXYZ(&actorPosition.x, &actorPosition.y, &actorPosition.z); actor->retire(retired, width, height, retiredByActorId); actor->setAtXYZ(actorPosition, actor->getFacing(), true, false, true); - _vm->_sceneObjects->setRetired(actorId + SCENE_OBJECTS_ACTORS_OFFSET, true); + _vm->_sceneObjects->setRetired(actorId + kSceneObjectOffsetActors, true); } void ScriptBase::Clickable_Object(const char *objectName) { @@ -1209,24 +1187,24 @@ void ScriptBase::Set_Fade_Density(float density) { _vm->_scene->_set->_effects->setFadeDensity(density); } -void ScriptBase::Set_Fog_Color(const char* fogName, float r, float g, float b) { +void ScriptBase::Set_Fog_Color(const char *fogName, float r, float g, float b) { _vm->_scene->_set->_effects->setFogColor(fogName, r, g, b); } -void ScriptBase::Set_Fog_Density(const char* fogName, float density) { +void ScriptBase::Set_Fog_Density(const char *fogName, float density) { _vm->_scene->_set->_effects->setFogDensity(fogName, density); } void ScriptBase::ADQ_Flush() { - _vm->_adq->flush(0, true); + _vm->_actorDialogueQueue->flush(0, true); } void ScriptBase::ADQ_Add(int actorId, int sentenceId, int animationMode) { - _vm->_adq->add(actorId, sentenceId, animationMode); + _vm->_actorDialogueQueue->add(actorId, sentenceId, animationMode); } void ScriptBase::ADQ_Add_Pause(int delay) { - _vm->_adq->addPause(delay); + _vm->_actorDialogueQueue->addPause(delay); } bool ScriptBase::Game_Over() { @@ -1289,22 +1267,22 @@ void ScriptBase::AI_Movement_Track_Flush(int actorId) { _vm->_actors[actorId]->stopWalking(false); } -void ScriptBase::KIA_Play_Actor_Dialogue(int a1, int a2) { - //TODO - warning("KIA_Play_Actor_Dialogue(%d, %d)", a1, a2); +void ScriptBase::KIA_Play_Actor_Dialogue(int actorId, int sentenceId) { + _vm->gameWaitForActive(); + _vm->_kia->playActorDialogue(actorId, sentenceId); } -void ScriptBase::KIA_Play_Slice_Model(int a1) { - //TODO - warning("KIA_Play_Slice_Model(%d)", a1); +void ScriptBase::KIA_Play_Slice_Model(int sliceModelId) { + _vm->gameWaitForActive(); + _vm->_kia->playSliceModel(sliceModelId); } -void ScriptBase::KIA_Play_Photograph(int a1) { - //TODO - warning("KIA_Play_Photograph(%d)", a1); +void ScriptBase::KIA_Play_Photograph(int photographId) { + _vm->gameWaitForActive(); + _vm->_kia->playPhotograph(photographId); } -void ScriptBase::ESPER_Add_Photo(const char* fileName, int a2, int a3) { +void ScriptBase::ESPER_Add_Photo(const char *fileName, int a2, int a3) { //TODO warning("ESPER_Add_Photo(%s, %d, %d)", fileName, a2, a3); } diff --git a/engines/bladerunner/script/script.h b/engines/bladerunner/script/script.h index 48bda147d6..3b6e66ab5e 100644 --- a/engines/bladerunner/script/script.h +++ b/engines/bladerunner/script/script.h @@ -26,437 +26,10 @@ #include "common/str.h" #include "bladerunner/bladerunner.h" +#include "bladerunner/game_constants.h" namespace BladeRunner { -enum Actors { - kActorMcCoy = 0, - kActorSteele = 1, - kActorGordo = 2, - kActorDektora = 3, - kActorGuzza = 4, - kActorClovis = 5, - kActorLucy = 6, - kActorIzo = 7, - kActorSadik = 8, - kActorCrazylegs = 9, - kActorLuther = 10, - kActorGrigorian = 11, - kActorTransient = 12, - kActorLance = 13, - kActorBulletBob = 14, - kActorRunciter = 15, - kActorInsectDealer = 16, - kActorTyrellGuard = 17, - kActorEarlyQ = 18, - kActorZuben = 19, - kActorHasan = 20, - kActorMarcus = 21, - kActorMia = 22, - kActorOfficerLeary = 23, - kActorOfficerGrayford = 24, - kActorHanoi = 25, - kActorBaker = 26, - kActorDeskClerk = 27, - kActorHowieLee = 28, - kActorFishDealer = 29, - kActorKlein = 30, - kActorMurray = 31, - kActorHawkersBarkeep = 32, - kActorHolloway = 33, - kActorSergeantWalls = 34, - kActorMoraji = 35, - kActorTheBard = 36, - kActorPhotographer = 37, - kActorDispatcher = 38, - kActorAnsweringMachine = 39, - kActorRajif = 40, - kActorGovernorKolvig = 41, - kActorEarlyQBartender = 42, - kActorHawkersParrot = 43, - kActorTaffyPatron = 44, - kActorLockupGuard = 45, - kActorTeenager = 46, - kActorHysteriaPatron1 = 47, - kActorHysteriaPatron2 = 48, - kActorHysteriaPatron3 = 49, - kActorShoeshineMan = 50, - kActorTyrell = 51, - kActorChew = 52, - kActorGaff = 53, - kActorBryant = 54, - kActorTaffy = 55, - kActorSebastian = 56, - kActorRachael = 57, - kActorGeneralDoll = 58, - kActorIsabella = 59, - kActorBlimpGuy = 60, - kActorNewscaster = 61, - kActorLeon = 62, - kActorMaleAnnouncer = 63, - kActorFreeSlotA = 64, - kActorFreeSlotB = 65, - kActorMaggie = 66, - kActorGenwalkerA = 67, - kActorGenwalkerB = 68, - kActorGenwalkerC = 69, - kActorMutant1 = 70, - kActorMutant2 = 71, - kActorMutant3 = 72, - kActorVoiceOver = 99 -}; - -enum Clues { - kClueOfficersStatement = 0, - kClueDoorForced1 = 1, - kClueDoorForced2 = 2, - kClueLimpingFootprints = 3, - kClueGracefulFootprints = 4, - kClueShellCasings = 5, - kClueCandy = 6, - kClueToyDog = 7, - kClueChopstickWrapper = 8, - kClueSushiMenu = 9, - kClueLabCorpses = 10, - kClueLabShellCasings = 11, - kClueRuncitersVideo = 12, - kClueLucy = 13, - kClueDragonflyAnklet = 14, - kClueReferenceLetter = 15, - kClueCrowdInterviewA = 16, - kClueCrowdInterviewB = 17, - kClueZubenRunsAway = 18, - kClueZubenInterview = 19, - kClueZuben = 20, - kClueBigManLimping = 21, - kClueRunciterInterviewA = 22, - kClueRunciterInterviewB1 = 23, - kClueRunciterInterviewB2 = 24, - kClueHowieLeeInterview = 25, - kCluePaintTransfer = 26, - kClueChromeDebris = 27, - kClueRuncitersViewA = 28, - kClueRuncitersViewB = 29, - kClueCarColorAndMake = 30, - kCluePartialLicenseNumber = 31, - kClueBriefcase = 32, - kClueGaffsInformation = 33, - kClueCrystalVisitedRunciters = 34, - kClueCrystalVisitedChinatown = 35, - kClueWantedPoster = 36, - kClueLicensePlate = 37, - kClueLicensePlateMatch = 38, - kClueLabPaintTransfer = 39, - kClueDispatchHitAndRun = 40, - kClueInceptShotRoy = 41, - kClueInceptShotsLeon = 42, - kCluePhoneCallGuzza = 43, - kClueDragonflyEarring = 44, - kClueTyrellSecurity = 45, - kClueTyrellGuardInterview = 46, - kClueBombingSuspect = 47, - kClueSadiksGun = 48, - kClueDetonatorWire = 49, - kClueVictimInformation = 50, - kClueAttemptedFileAccess = 51, - kClueCrystalsCase = 52, - kClueKingstonKitchenBox1 = 53, - kClueTyrellSalesPamphlet1 = 54, - kClueTyrellSalesPamphlet2 = 55, - kCluePeruvianLadyInterview = 56, - kClueHasanInterview = 57, - kClueBobInterview1 = 58, - kClueBobInterview2 = 59, - kClueIzoInterview = 60, - kClueIzosWarning = 61, - kClueRadiationGoggles = 62, - kClueGogglesReplicantIssue = 63, - kClueFishLadyInterview = 64, - kClueDogCollar1 = 65, - kClueWeaponsCache = 66, - kClueChewInterview = 67, - kClueMorajiInterview = 68, - kClueGordoInterview1 = 69, - kClueGordoInterview2 = 70, - kClueAnsweringMachineMessage = 71, - kClueChessTable = 72, - kClueSightingSadikBradbury = 73, - kClueStaggeredbyPunches = 74, - kClueMaggieBracelet = 75, - kClueEnvelope = 76, - kClueIzosFriend = 77, - kClueChinaBarSecurityPhoto = 78, - kCluePurchasedScorpions = 79, - kClueWeaponsOrderForm = 80, - kClueShippingForm = 81, - kClueGuzzasCash = 82, - kCluePoliceIssueWeapons = 83, - kClueHysteriaToken = 84, - kClueRagDoll = 85, - kClueMoonbus1 = 86, - kClueCheese = 87, - kClueDektorasDressingRoom = 88, - kClueEarlyQsClub = 89, - kClueDragonflyCollection = 90, - kClueDragonflyBelt = 91, - kClueEarlyQInterview = 92, - kClueStrangeScale1 = 93, - kClueDektoraInterview1 = 94, - kClueSuspectDektora = 95, - kClueDektoraInterview2 = 96, - kClueDektoraInterview3 = 97, - kClueDektorasCard = 98, - kClueGrigoriansNote = 99, - kClueCollectionReceipt = 100, - kClueSpecialIngredient = 101, - kClueStolenCheese = 102, - kClueGordoInterview3 = 103, - kClueGordoConfession = 104, - kClueGordosLighter1 = 105, - kClueGordosLighter2 = 106, - kClueDektoraInterview4 = 107, - kClueHollowayInterview = 108, - kClueBakersBadge = 109, - kClueHoldensBadge = 110, - kClueCar = 111, - kClueCarIdentified = 112, - kClueCarRegistration1 = 113, - kClueCarRegistration2 = 114, - kClueCarRegistration3 = 115, - kClueCrazylegsInterview1 = 116, - kClueCrazylegsInterview2 = 117, - kClueLichenDogWrapper = 118, - kClueRequisitionForm = 119, - kClueScaryChair = 120, - kClueIzosStashRaided = 121, - kClueHomelessManInterview1 = 122, - kClueHomelessManInterview2 = 123, - kClueHomelessManKid = 124, - kClueFolder = 125, - kClueGuzzaFramedMcCoy = 126, - kClueOriginalShippingForm = 127, - kClueOriginalRequisitionForm = 128, - kClueCandyWrapper = 129, - kClueGordoBlabs = 130, - kClueFlaskOfAbsinthe = 131, - kClueGuzzaAgreesToMeet = 132, - kClueDektoraConfession = 133, - kClueRunciterConfession1 = 134, - kClueRunciterConfession2 = 135, - kClueLutherLanceInterview = 136, - kClueMoonbus2 = 137, - kClueMoonbusCloseup = 138, - kCluePhoneCallDektora1 = 139, - kCluePhoneCallDektora2 = 140, - kCluePhoneCallLucy1 = 141, - kCluePhoneCallLucy2 = 142, - kCluePhoneCallClovis = 143, - kCluePhoneCallCrystal = 144, - kCluePowerSource = 145, - kClueBomb = 146, - kClueDNATyrell = 147, - kClueDNASebastian = 148, - kClueDNAChew = 149, - kClueDNAMoraji = 150, - kClueDNALutherLance = 151, - kClueDNAMarcus = 152, - kClueGarterSnake = 153, - kClueSlug = 154, - kClueGoldfish = 155, - kClueZubenTalksAboutLucy1 = 156, - kClueZubenTalksAboutLucy2 = 157, - kClueZubensMotive = 158, - kClueSightingBulletBob = 159, - kClueSightingClovis = 160, - kClueSightingDektora = 161, - kClueVKDektoraReplicant = 162, - kClueVKDektoraHuman = 163, - kClueVKBobGorskyReplicant = 164, - kClueVKBobGorskyHuman = 165, - kClueVKLutherLanceReplicant = 166, - kClueVKLutherLanceHuman = 167, - kClueVKGrigorianReplicant = 168, - kClueVKGrigorianHuman = 169, - kClueVKIzoReplicant = 170, - kClueVKIzoHuman = 171, - kClueVKCrazylegsReplicant = 172, - kClueVKCrazylegsHuman = 173, - kClueVKRunciterReplicant = 174, - kClueVKRunciterHuman = 175, - kClueVKEarlyQReplicant = 176, - kClueVKEarlyQHuman = 177, - kClueCrimeSceneNotes = 178, - kClueGrigorianInterviewA = 179, - kClueGrigorianInterviewB1 = 180, - kClueGrigorianInterviewB2 = 181, - kClueLabAnalysisGoldChain = 182, - kClueSightingZuben = 183, - kClueCrystalRetiredZuben = 184, - kClueCrystalRetiredGordo = 185, - kClueSightingGordo = 186, - kClueCrystalRetiredIzo = 187, - kClueClovisIncept = 188, - kClueDektoraIncept = 189, - kClueLucyIncept = 190, - kClueGordoIncept = 191, - kClueIzoIncept = 192, - kClueSadikIncept = 193, - kClueZubenIncept = 194, - kClueMcCoyIncept = 195, - kClueWarRecordsGordoFrizz = 196, - kCluePoliceWeaponUsed = 197, - kClueMcCoysWeaponUsedonBob = 198, - kClueBobRobbed = 199, - kClueBobShotInSelfDefense = 200, - kClueBobShotInColdBlood = 201, - kClueMcCoyRecoveredHoldensBadge = 202, - kClueCrystalTestedBulletBob = 203, - kClueCrystalRetiredBob = 204, - kClueCrystalTestedCrazylegs = 205, - kClueCrystalRetiredCrazylegs = 206, - kClueCrystalArrestedCrazylegs = 207, - kClueCrystalTestedRunciter = 208, - kClueCrystalRetiredRunciter1 = 209, - kClueCrystalRetiredRunciter2 = 210, - kClueSightingMcCoyRuncitersShop = 211, - kClueMcCoyKilledRunciter1 = 212, - kClueMcCoysDescription = 213, - kClueMcCoyIsABladeRunner = 214, - kClueMcCoyLetZubenEscape = 215, - kClueMcCoyWarnedIzo = 216, - kClueMcCoyHelpedIzoIzoIsAReplicant = 217, - kClueMcCoyHelpedDektora = 218, - kClueMcCoyHelpedLucy = 219, - kClueMcCoyHelpedGordo = 220, - kClueMcCoyShotGuzza = 221, - kClueMcCoyRetiredZuben = 222, - kClueMcCoyRetiredLucy = 223, - kClueMcCoyRetiredDektora = 224, - kClueMcCoyRetiredGordo = 225, - kClueMcCoyRetiredSadik = 226, - kClueMcCoyShotZubenintheback = 227, - kClueMcCoyRetiredLutherLance = 228, - kClueMcCoyBetrayal = 229, - kClueMcCoyKilledRunciter2 = 230, - kClueClovisOrdersMcCoysDeath = 231, - kClueEarlyAttemptedToSeduceLucy = 232, - kClueCarWasStolen = 233, - kClueGrigoriansResponse1 = 234, - kClueGrigoriansResponse2 = 235, - kClueCrazysInvolvement = 236, - kClueGrigoriansResources = 237, - kClueMcCoyPulledAGun = 238, - kClueMcCoyIsStupid = 239, - kClueMcCoyIsAnnoying = 240, - kClueMcCoyIsKind = 241, - kClueMcCoyIsInsane = 242, - kClueAnimalMurderSuspect = 243, - kClueMilitaryBoots = 244, - kClueOuterDressingRoom = 245, - kCluePhotoOfMcCoy1 = 246, - kCluePhotoOfMcCoy2 = 247, - kClueEarlyQAndLucy = 248, - kClueClovisflowers = 249, - kClueLucyWithDektora = 250, - kClueWomanInAnimoidRow = 251, - kClueScorpions = 252, - kClueStrangeScale2 = 253, - kClueChinaBarSecurityCamera = 254, - kClueIzo = 255, - kClueGuzza = 256, - kClueChinaBarSecurityDisc = 257, - kClueScorpionbox = 258, - kClueTyrellSecurityPhoto = 259, - kClueChinaBar = 260, - kCluePlasticExplosive = 261, - kClueDogCollar2 = 262, - kClueKingstonKitchenBox2 = 263, - kClueCrystalsCigarette = 264, - kClueSpinnerKeys = 265, - kClueAct2Ended = 266, - kClueAct3Ended = 267, - kClueAct4Ended = 268, - kClueExpertBomber = 269, - kClueAmateurBomber = 270, - kClueVKLucyReplicant = 271, - kClueVKLucyHuman = 272, - kClueLucyInterview = 273, - kClueMoonbusReflection = 274, - kClueMcCoyAtMoonbus = 275, - kClueClovisAtMoonbus = 276, - kClueSadikAtMoonbus = 277, - kClueRachaelInterview = 278, - kClueTyrellInterview = 279, - kClueRuncitersConfession1 = 280, - kClueRuncitersConfession2 = 281, - kClueRuncitersConfession3 = 282, - kClueEarlyInterviewA = 283, - kClueEarlyInterviewB1 = 284, - kClueEarlyInterviewB2 = 285, - kClueCrazylegsInterview3 = 286, - kClueCrazylegGgrovels = 287 -}; - -enum ClueTypes { - kClueTypePhotograph = 0, - kClueTypeVideoClip = 1, - kClueTypeAudioRecording = 2, - kClueTypeObject = 3 -}; - -enum Crimes { - kCrimeAnimalMurder = 0, - kCrimeEisendullerMurder = 1, - kCrimeArmsDealing = 2, - kCrimeMorajiMurder = 3, - kCrimeBradburyAssault = 4, - kCrimeFactoryBombing = 5, - kCrimeBobMurder = 6, - kCrimeRunciterMurder = 7, - kCrimeMoonbusHijacking = 8 -}; - -enum SpinnerDestinations { - kSpinnerDestinationPoliceStation = 0, - kSpinnerDestinationMcCoysApartment = 1, - kSpinnerDestinationRuncitersAnimals = 2, - kSpinnerDestinationChinatown = 3, - kSpinnerDestinationAnimoidRow = 4, - kSpinnerDestinationTyrellBuilding = 5, - kSpinnerDestinationDNARow = 6, - kSpinnerDestinationBradburyBuilding = 7, - kSpinnerDestinationNightclubRow = 8, - kSpinnerDestinationHysteriaHall = 9 -}; - -enum Flags { - kFlagIntroPlayed = 24, - kFlagMA02toMA06 = 33, - kFlagMA06ToMA02 = 34, - kFlagMA02ToMA04 = 35, - kFlagMA04ToMA02 = 36, - kFlagMA01toMA06 = 37, - kFlagMA06toMA01 = 38, - kFlagMA07toMA06 = 57, - kFlagMA06toMA07 = 58, - kFlagMA04toMA05 = 62, - kFlagMA05toMA04 = 63, - kFlagRC01PoliceDone = 186, - kFlagMA01Locked = 250 -}; - -enum Variables { - kVariableWalkLoopActor = 37, - kVariableWalkLoopRun = 38 -}; - -enum Outtakes { - kOuttakeIntro = 0, - kOuttakeWestwood = 28, - kOuttakeDescent = 33, - kOuttakeBladeRunner = 41 -}; - class BladeRunnerEngine; class ScriptBase { @@ -464,7 +37,9 @@ protected: BladeRunnerEngine *_vm; public: - ScriptBase(BladeRunnerEngine *vm) : _vm(vm) {} + ScriptBase(BladeRunnerEngine *vm) { + _vm = vm; + } virtual ~ScriptBase() {} protected: @@ -663,8 +238,8 @@ protected: // Query_Score void Set_Score(int a0, int a1); void Give_McCoy_Ammo(int ammoType, int ammo); - void Assign_Player_Gun_Hit_Sounds(int row, int soundId1, int soundId2, int soundId3); - void Assign_Player_Gun_Miss_Sounds(int row, int soundId1, int soundId2, int soundId3); + void Assign_Player_Gun_Hit_Sounds(int ammoType, int soundId1, int soundId2, int soundId3); + void Assign_Player_Gun_Miss_Sounds(int ammoType, int soundId1, int soundId2, int soundId3); void Disable_Shadows(int animationsIdsList[], int listSize); bool Query_System_Currently_Loading_Game(); void Actor_Retired_Here(int actorId, int width, int height, int retired, int retiredByActorId); @@ -677,8 +252,8 @@ protected: void Un_Combat_Target_Object(const char *objectName); void Set_Fade_Color(float r, float g, float b); void Set_Fade_Density(float density); - void Set_Fog_Color(const char* fogName, float r, float g, float b); - void Set_Fog_Density(const char* fogName, float density); + void Set_Fog_Color(const char *fogName, float r, float g, float b); + void Set_Fog_Density(const char *fogName, float density); void ADQ_Flush(); void ADQ_Add(int actorId, int sentenceId, int animationMode); void ADQ_Add_Pause(int delay); @@ -697,12 +272,12 @@ protected: void AI_Movement_Track_Append(int actorId, int waypointId, int delay); void AI_Movement_Track_Flush(int actorId); - void ESPER_Add_Photo(const char* fileName, int a2, int a3); + void ESPER_Add_Photo(const char *fileName, int a2, int a3); void ESPER_Define_Special_Region(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, const char *name); - void KIA_Play_Actor_Dialogue(int a1, int a2); - void KIA_Play_Slice_Model(int a1); - void KIA_Play_Photograph(int a1); + void KIA_Play_Actor_Dialogue(int actorId, int sentenceId); + void KIA_Play_Slice_Model(int sliceModelId); + void KIA_Play_Photograph(int photographId); void VK_Play_Speech_Line(int actorIndex, int a2, float a3); void VK_Add_Question(int a1, int a2, int a3); diff --git a/engines/bladerunner/script/vk.cpp b/engines/bladerunner/script/vk.cpp index 0650cb4987..421b86c9f9 100644 --- a/engines/bladerunner/script/vk.cpp +++ b/engines/bladerunner/script/vk.cpp @@ -26,7 +26,7 @@ namespace BladeRunner { -bool ScriptVK::SCRIPT_VK_DLL_Initialize(int a1) { +bool VKScript::SCRIPT_VK_DLL_Initialize(int a1) { VK_Add_Question(0, 7400, -1); VK_Add_Question(0, 7405, -1); VK_Add_Question(0, 7410, -1); @@ -82,7 +82,7 @@ bool ScriptVK::SCRIPT_VK_DLL_Initialize(int a1) { } } -void ScriptVK::SCRIPT_VK_DLL_Calibrate(int a1) { +void VKScript::SCRIPT_VK_DLL_Calibrate(int a1) { if (unknown1 == 0) { VK_Play_Speech_Line(0, 7370, 0.5f); VK_Play_Speech_Line(0, 7385, 0.5f); @@ -101,12 +101,12 @@ void ScriptVK::SCRIPT_VK_DLL_Calibrate(int a1) { } } -bool ScriptVK::SCRIPT_VK_DLL_Begin_Test() { +bool VKScript::SCRIPT_VK_DLL_Begin_Test() { unknown2 = 0; return false; } -void ScriptVK::SCRIPT_VK_DLL_McCoy_Asks_Question(int a1, int a2) { +void VKScript::SCRIPT_VK_DLL_McCoy_Asks_Question(int a1, int a2) { switch (a2) { case 7400: VK_Play_Speech_Line(0, 7400, 0.5f); @@ -300,7 +300,7 @@ void ScriptVK::SCRIPT_VK_DLL_McCoy_Asks_Question(int a1, int a2) { } } -void ScriptVK::SCRIPT_VK_DLL_Question_Asked(int a1, int a2) { +void VKScript::SCRIPT_VK_DLL_Question_Asked(int a1, int a2) { switch (a1) { case 15: sub_407CF8(a2); @@ -320,7 +320,7 @@ void ScriptVK::SCRIPT_VK_DLL_Question_Asked(int a1, int a2) { } } -void ScriptVK::SCRIPT_VK_DLL_Shutdown(int a1, signed int a2, signed int a3) { +void VKScript::SCRIPT_VK_DLL_Shutdown(int a1, signed int a2, signed int a3) { if (a2 > 79 && a3 > 79) { VK_Play_Speech_Line(39, 450, 0.5f); } else if (a3 > 79) { @@ -367,7 +367,7 @@ void ScriptVK::SCRIPT_VK_DLL_Shutdown(int a1, signed int a2, signed int a3) { VK_Play_Speech_Line(39, 460, 0.5f); } -void ScriptVK::sub_402604(int a1) { +void VKScript::sub_402604(int a1) { switch (a1) { case 7385: VK_Subject_Reacts(40, 0, 0, 0); @@ -858,7 +858,7 @@ void ScriptVK::sub_402604(int a1) { } } -void ScriptVK::sub_404B44(int a1) { +void VKScript::sub_404B44(int a1) { switch (a1) { case 7385: VK_Subject_Reacts(20, 0, 0, 5); @@ -1117,7 +1117,7 @@ void ScriptVK::sub_404B44(int a1) { } } -void ScriptVK::sub_406088(int a1) { +void VKScript::sub_406088(int a1) { switch (a1) { case 7385: VK_Subject_Reacts(36, 0, 0, 0); @@ -1472,7 +1472,7 @@ void ScriptVK::sub_406088(int a1) { } } -void ScriptVK::sub_407CF8(int a1) { +void VKScript::sub_407CF8(int a1) { switch (a1) { case 7385: VK_Subject_Reacts(20, 10, 20, 0); @@ -1651,7 +1651,7 @@ void ScriptVK::sub_407CF8(int a1) { } } -void ScriptVK::sub_40897C(int a1) { +void VKScript::sub_40897C(int a1) { switch (a1) { case 7385: VK_Eye_Animates(1); @@ -1980,7 +1980,7 @@ void ScriptVK::sub_40897C(int a1) { } } -void ScriptVK::sub_40A300(int a1, int a2) { +void VKScript::sub_40A300(int a1, int a2) { switch (a1) { case 15: sub_407CF8(7385); @@ -2000,7 +2000,7 @@ void ScriptVK::sub_40A300(int a1, int a2) { } } -void ScriptVK::sub_40A350(int a1, int a2) { +void VKScript::sub_40A350(int a1, int a2) { switch (a1) { case 15: sub_407CF8(7390); @@ -2020,7 +2020,7 @@ void ScriptVK::sub_40A350(int a1, int a2) { } } -void ScriptVK::sub_40A3A0(int a1, int a2) { +void VKScript::sub_40A3A0(int a1, int a2) { switch (a1) { case 15: sub_407CF8(7395); @@ -2040,14 +2040,14 @@ void ScriptVK::sub_40A3A0(int a1, int a2) { } } -void ScriptVK::sub_40A3F0(int a1) { +void VKScript::sub_40A3F0(int a1) { VK_Play_Speech_Line(3, 1470, 0.5f); VK_Subject_Reacts(40, 4, 4, 0); VK_Play_Speech_Line(0, 7795, 0.5f); VK_Play_Speech_Line(3, 1480, 0.5f); } -void ScriptVK::sub_40A470(int a1) { +void VKScript::sub_40A470(int a1) { VK_Subject_Reacts(40, 2, 2, 0); VK_Play_Speech_Line(3, 1450, 0.5f); VK_Play_Speech_Line(0, 7785, 0.5f); @@ -2055,7 +2055,7 @@ void ScriptVK::sub_40A470(int a1) { VK_Play_Speech_Line(0, 7790, 0.5f); } -void ScriptVK::sub_40A510(int a1) { +void VKScript::sub_40A510(int a1) { VK_Subject_Reacts(36, 0, 0, 0); VK_Play_Speech_Line(3, 1440, 0.5f); } diff --git a/engines/bladerunner/script/vk.h b/engines/bladerunner/script/vk.h index 087faa88d1..0835568f9e 100644 --- a/engines/bladerunner/script/vk.h +++ b/engines/bladerunner/script/vk.h @@ -29,9 +29,9 @@ namespace BladeRunner { class BladeRunnerEngine; -class ScriptVK : ScriptBase { +class VKScript : ScriptBase { public: - ScriptVK(BladeRunnerEngine *vm) + VKScript(BladeRunnerEngine *vm) : ScriptBase(vm) { } diff --git a/engines/bladerunner/set.cpp b/engines/bladerunner/set.cpp index 5501f27a2c..a68799a232 100644 --- a/engines/bladerunner/set.cpp +++ b/engines/bladerunner/set.cpp @@ -37,7 +37,8 @@ namespace BladeRunner { #define kSet0 0x53657430 -Set::Set(BladeRunnerEngine *vm) : _vm(vm) { +Set::Set(BladeRunnerEngine *vm) { + _vm = vm; _objectCount = 0; _walkboxCount = 0; _objects = new Object[85]; @@ -60,13 +61,13 @@ bool Set::open(const Common::String &name) { if (sig != kSet0) return false; - int framesCount = s->readUint32LE(); + int frameCount = s->readUint32LE(); _objectCount = s->readUint32LE(); assert(_objectCount <= 85); for (int i = 0; i < _objectCount; ++i) { - s->read(_objects[i]._name, 20); + s->read(_objects[i].name, 20); float x0, y0, z0, x1, y1, z1; x0 = s->readFloatLE(); @@ -76,12 +77,11 @@ bool Set::open(const Common::String &name) { y1 = s->readFloatLE(); z1 = s->readFloatLE(); - _objects[i]._bbox = BoundingBox(x0, y0, z0, x1, y1, z1); - - _objects[i]._isObstacle = s->readByte(); - _objects[i]._isClickable = s->readByte(); - _objects[i]._isHotMouse = 0; - _objects[i]._isTarget = 0; + _objects[i].bbox = BoundingBox(x0, y0, z0, x1, y1, z1); + _objects[i].isObstacle = s->readByte(); + _objects[i].isClickable = s->readByte(); + _objects[i].isHotMouse = 0; + _objects[i].isTarget = 0; s->skip(4); // debug("OBJECT: %s [%d%d%d%d]", _objects[i]._name, _objects[i]._isObstacle, _objects[i]._isClickable, _objects[i]._isHotMouse, _objects[i]._isTarget); @@ -93,34 +93,34 @@ bool Set::open(const Common::String &name) { for (int i = 0; i < _walkboxCount; ++i) { float x, z; - s->read(_walkboxes[i]._name, 20); - _walkboxes[i]._altitude = s->readFloatLE(); - _walkboxes[i]._vertexCount = s->readUint32LE(); + s->read(_walkboxes[i].name, 20); + _walkboxes[i].altitude = s->readFloatLE(); + _walkboxes[i].vertexCount = s->readUint32LE(); - assert(_walkboxes[i]._vertexCount <= 8); + assert(_walkboxes[i].vertexCount <= 8); - for (int j = 0; j < _walkboxes[i]._vertexCount; ++j) { + for (int j = 0; j < _walkboxes[i].vertexCount; ++j) { x = s->readFloatLE(); z = s->readFloatLE(); - _walkboxes[i]._vertices[j] = Vector3(x, _walkboxes[i]._altitude, z); + _walkboxes[i].vertices[j] = Vector3(x, _walkboxes[i].altitude, z); } // debug("WALKBOX: %s", _walkboxes[i]._name); } _vm->_lights->reset(); - _vm->_lights->read(s.get(), framesCount); + _vm->_lights->read(s.get(), frameCount); _vm->_sliceRenderer->setLights(_vm->_lights); _effects->reset(); - _effects->read(s.get(), framesCount); + _effects->read(s.get(), frameCount); _vm->_sliceRenderer->setSetEffects(_effects); - // _vm->_sliceRenderer->set_setColors(&this->colors); + // _vm->_sliceRenderer->set_setColors(&colors); _loaded = true; for (int i = 0; i < _walkboxCount; ++i) { - this->setWalkboxStepSound(i, 0); + setWalkboxStepSound(i, 0); } return true; @@ -128,7 +128,7 @@ bool Set::open(const Common::String &name) { void Set::addObjectsToScene(SceneObjects *sceneObjects) const { for (int i = 0; i < _objectCount; i++) { - sceneObjects->addObject(i + SCENE_OBJECTS_OBJECTS_OFFSET, &_objects[i]._bbox, _objects[i]._isClickable, _objects[i]._isObstacle, _objects[i]._unknown1, _objects[i]._isTarget); + sceneObjects->addObject(i + kSceneObjectOffsetObjects, &_objects[i].bbox, _objects[i].isClickable, _objects[i].isObstacle, _objects[i].unknown1, _objects[i].isTarget); } } @@ -152,14 +152,14 @@ bool pointInWalkbox(float x, float z, const Walkbox &w) } */ -static bool isXZInWalkbox(float x, float z, const Walkbox &walkbox) { +bool Set::isXZInWalkbox(float x, float z, const Walkbox &walkbox) { int found = 0; - float lastX = walkbox._vertices[walkbox._vertexCount - 1].x; - float lastZ = walkbox._vertices[walkbox._vertexCount - 1].z; - for (int i = 0; i < walkbox._vertexCount; i++) { - float currentX = walkbox._vertices[i].x; - float currentZ = walkbox._vertices[i].z; + float lastX = walkbox.vertices[walkbox.vertexCount - 1].x; + float lastZ = walkbox.vertices[walkbox.vertexCount - 1].z; + for (int i = 0; i < walkbox.vertexCount; i++) { + float currentX = walkbox.vertices[i].x; + float currentZ = walkbox.vertices[i].z; if ((currentZ > z && z >= lastZ) || (currentZ <= z && z < lastZ)) { float lineX = (lastX - currentX) / (lastZ - currentZ) * (z - currentZ) + currentX; @@ -173,15 +173,15 @@ static bool isXZInWalkbox(float x, float z, const Walkbox &walkbox) { } float Set::getAltitudeAtXZ(float x, float z, bool *inWalkbox) const { - float altitude = _walkboxes[0]._altitude; + float altitude = _walkboxes[0].altitude; *inWalkbox = false; for (int i = 0; i < _walkboxCount; ++i) { const Walkbox &walkbox = _walkboxes[i]; if (isXZInWalkbox(x, z, walkbox)) { - if (!*inWalkbox || altitude < walkbox._altitude) { - altitude = walkbox._altitude; + if (!*inWalkbox || altitude < walkbox.altitude) { + altitude = walkbox.altitude; *inWalkbox = true; } } @@ -197,7 +197,7 @@ int Set::findWalkbox(float x, float z) const { const Walkbox &w = _walkboxes[i]; if (isXZInWalkbox(x, z, w)) { - if (result == -1 || w._altitude > _walkboxes[result]._altitude) { + if (result == -1 || w.altitude > _walkboxes[result].altitude) { result = i; } } @@ -209,7 +209,7 @@ int Set::findWalkbox(float x, float z) const { int Set::findObject(const char *objectName) const { int i; for (i = 0; i < (int)_objectCount; i++) { - if (scumm_stricmp(objectName, _objects[i]._name) == 0) { + if (scumm_stricmp(objectName, _objects[i].name) == 0) { return i; } } @@ -224,7 +224,7 @@ bool Set::objectSetHotMouse(int objectId) const { return false; } - _objects[objectId]._isHotMouse = true; + _objects[objectId].isHotMouse = true; return true; } @@ -237,30 +237,30 @@ bool Set::objectGetBoundingBox(int objectId, BoundingBox *boundingBox) const { } float x0, y0, z0, x1, y1, z1; - _objects[objectId]._bbox.getXYZ(&x0, &y0, &z0, &x1, &y1, &z1); + _objects[objectId].bbox.getXYZ(&x0, &y0, &z0, &x1, &y1, &z1); boundingBox->setXYZ(x0, y0, z0, x1, y1, z1); return true; } -void Set::objectSetIsClickable(int objectId, bool isClickable) const { - _objects[objectId]._isClickable = isClickable; +void Set::objectSetIsClickable(int objectId, bool isClickable) { + _objects[objectId].isClickable = isClickable; } -void Set::objectSetIsObstacle(int objectId, bool isObstacle) const { - _objects[objectId]._isObstacle = isObstacle; +void Set::objectSetIsObstacle(int objectId, bool isObstacle) { + _objects[objectId].isObstacle = isObstacle; } -void Set::objectSetIsTarget(int objectId, bool isTarget) const { - _objects[objectId]._isTarget = isTarget; +void Set::objectSetIsTarget(int objectId, bool isTarget) { + _objects[objectId].isTarget = isTarget; } const char *Set::objectGetName(int objectId) const { - return _objects[objectId]._name; + return _objects[objectId].name; } void Set::setWalkboxStepSound(int walkboxId, int stepSound) { - this->_walkboxStepSound[walkboxId] = stepSound; + _walkboxStepSound[walkboxId] = stepSound; } void Set::setFoodstepSoundOverride(int soundId) { @@ -271,12 +271,12 @@ void Set::resetFoodstepSoundOverride() { _footstepSoundOverride = -1; } -int Set::getWalkboxSoundWalkLeft(int walkboxId) { +int Set::getWalkboxSoundWalkLeft(int walkboxId) const{ int soundId; - if (this->_footstepSoundOverride >= 0) { - soundId = this->_footstepSoundOverride; + if (_footstepSoundOverride >= 0) { + soundId = _footstepSoundOverride; } else { - soundId = this->_walkboxStepSound[walkboxId]; + soundId = _walkboxStepSound[walkboxId]; } if (soundId == 0) { //stone floor @@ -295,12 +295,12 @@ int Set::getWalkboxSoundWalkLeft(int walkboxId) { return -1; } -int Set::getWalkboxSoundWalkRight(int walkboxId) { +int Set::getWalkboxSoundWalkRight(int walkboxId) const { int soundId; - if (this->_footstepSoundOverride >= 0) { - soundId = this->_footstepSoundOverride; + if (_footstepSoundOverride >= 0) { + soundId = _footstepSoundOverride; } else { - soundId = this->_walkboxStepSound[walkboxId]; + soundId = _walkboxStepSound[walkboxId]; } if (soundId == 0) { //stone floor @@ -319,11 +319,11 @@ int Set::getWalkboxSoundWalkRight(int walkboxId) { return -1; } -int Set::getWalkboxSoundRunLeft(int walkboxId) { +int Set::getWalkboxSoundRunLeft(int walkboxId) const { return getWalkboxSoundWalkLeft(walkboxId); } -int Set::getWalkboxSoundRunRight(int walkboxId) { +int Set::getWalkboxSoundRunRight(int walkboxId) const { return getWalkboxSoundWalkRight(walkboxId); } } // End of namespace BladeRunner diff --git a/engines/bladerunner/set.h b/engines/bladerunner/set.h index d3540c5c0f..17d06263b9 100644 --- a/engines/bladerunner/set.h +++ b/engines/bladerunner/set.h @@ -36,27 +36,26 @@ class VQADecoder; class SetEffects; class SceneObjects; -struct Object { - char _name[20]; - BoundingBox _bbox; - uint8 _isObstacle; - uint8 _isClickable; - uint8 _isHotMouse; - uint8 _isTarget; - uint8 _unknown1; -}; - -struct Walkbox { - char _name[20]; - float _altitude; - int _vertexCount; - Vector3 _vertices[8]; -}; - class Set { -#if _DEBUG +#if BLADERUNNER_DEBUG_RENDERING friend class BladeRunnerEngine; #endif + struct Object { + char name[20]; + BoundingBox bbox; + uint8 isObstacle; + uint8 isClickable; + uint8 isHotMouse; + uint8 isTarget; + uint8 unknown1; + }; + + struct Walkbox { + char name[20]; + float altitude; + int vertexCount; + Vector3 vertices[8]; + }; BladeRunnerEngine *_vm; @@ -68,6 +67,7 @@ class Set { int _walkboxStepSound[85]; int _footstepSoundOverride; // float _unknown[10]; + public: SetEffects *_effects; @@ -87,19 +87,21 @@ public: bool objectSetHotMouse(int objectId) const; bool objectGetBoundingBox(int objectId, BoundingBox *boundingBox) const; - void objectSetIsClickable(int objectId, bool isClickable) const; - void objectSetIsObstacle(int objectId, bool isObstacle) const; - void objectSetIsTarget(int objectId, bool isTarget) const; + void objectSetIsClickable(int objectId, bool isClickable); + void objectSetIsObstacle(int objectId, bool isObstacle); + void objectSetIsTarget(int objectId, bool isTarget); const char *objectGetName(int objectId) const; void setWalkboxStepSound(int walkboxId, int soundId); void setFoodstepSoundOverride(int soundId); void resetFoodstepSoundOverride(); - int getWalkboxSoundWalkLeft(int walkboxId); - int getWalkboxSoundWalkRight(int walkboxId); - int getWalkboxSoundRunLeft(int walkboxId); - int getWalkboxSoundRunRight(int walkboxId); - + int getWalkboxSoundWalkLeft(int walkboxId) const; + int getWalkboxSoundWalkRight(int walkboxId) const; + int getWalkboxSoundRunLeft(int walkboxId) const; + int getWalkboxSoundRunRight(int walkboxId) const; + +private: + static bool isXZInWalkbox(float x, float z, const Walkbox &walkbox); }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/set_effects.cpp b/engines/bladerunner/set_effects.cpp index c4038f6726..5c7b2487a8 100644 --- a/engines/bladerunner/set_effects.cpp +++ b/engines/bladerunner/set_effects.cpp @@ -37,7 +37,7 @@ SetEffects::SetEffects(BladeRunnerEngine *vm) { _fadeColor.b = 0.0f; _fadeDensity = 0.0f; - _fogsCount = 0; + _fogCount = 0; _fogs = nullptr; } @@ -45,15 +45,15 @@ SetEffects::~SetEffects() { reset(); } -void SetEffects::read(Common::ReadStream *stream, int framesCount) { +void SetEffects::read(Common::ReadStream *stream, int frameCount) { _distanceCoeficient = stream->readFloatLE(); _distanceColor.r = stream->readFloatLE(); _distanceColor.g = stream->readFloatLE(); _distanceColor.b = stream->readFloatLE(); - _fogsCount = stream->readUint32LE(); + _fogCount = stream->readUint32LE(); int i; - for (i = 0; i < _fogsCount; i++) { + for (i = 0; i < _fogCount; i++) { int type = stream->readUint32LE(); Fog *fog = nullptr; switch (type) { @@ -70,7 +70,7 @@ void SetEffects::read(Common::ReadStream *stream, int framesCount) { if (!fog) { //TODO exception, unknown fog type } else { - fog->read(stream, framesCount); + fog->read(stream, frameCount); fog->_next = _fogs; _fogs = fog; } @@ -80,13 +80,14 @@ void SetEffects::read(Common::ReadStream *stream, int framesCount) { void SetEffects::reset() { Fog *nextFog; - if (!_fogs) + if (!_fogs) { return; + } do { nextFog = _fogs->_next; - delete this->_fogs; - this->_fogs = nextFog; + delete _fogs; + _fogs = nextFog; } while (nextFog); } @@ -105,8 +106,9 @@ void SetEffects::setFadeDensity(float density) { void SetEffects::setFogColor(const char *fogName, float r, float g, float b) { Fog *fog = findFog(fogName); - if (fog == nullptr) + if (fog == nullptr) { return; + } fog->_fogColor.r = r; fog->_fogColor.g = g; @@ -115,13 +117,14 @@ void SetEffects::setFogColor(const char *fogName, float r, float g, float b) { void SetEffects::setFogDensity(const char *fogName, float density) { Fog *fog = findFog(fogName); - if (fog == nullptr) + if (fog == nullptr) { return; + } fog->_fogDensity = density; } -void SetEffects::calculateColor(Vector3 viewPosition, Vector3 position, float *outCoeficient, Color *outColor) { +void SetEffects::calculateColor(Vector3 viewPosition, Vector3 position, float *outCoeficient, Color *outColor) const { float distanceCoeficient = CLIP((position - viewPosition).length() * _distanceCoeficient, 0.0f, 1.0f); *outCoeficient = 1.0f - distanceCoeficient; @@ -129,7 +132,7 @@ void SetEffects::calculateColor(Vector3 viewPosition, Vector3 position, float *o outColor->g = _distanceColor.g * distanceCoeficient; outColor->b = _distanceColor.b * distanceCoeficient; - for (Fog *fog = this->_fogs; fog != nullptr; fog = fog->_next) { + for (Fog *fog = _fogs; fog != nullptr; fog = fog->_next) { float fogCoeficient = 0.0f; fog->calculateCoeficient(position, viewPosition, &fogCoeficient); if (fogCoeficient > 0.0f) { @@ -142,15 +145,16 @@ void SetEffects::calculateColor(Vector3 viewPosition, Vector3 position, float *o } } - *outCoeficient = *outCoeficient * (1.0f - this->_fadeDensity); - outColor->r = outColor->r * (1.0f - this->_fadeDensity) + this->_fadeColor.r * this->_fadeDensity; - outColor->g = outColor->g * (1.0f - this->_fadeDensity) + this->_fadeColor.g * this->_fadeDensity; - outColor->b = outColor->b * (1.0f - this->_fadeDensity) + this->_fadeColor.b * this->_fadeDensity; + *outCoeficient = *outCoeficient * (1.0f - _fadeDensity); + outColor->r = outColor->r * (1.0f - _fadeDensity) + _fadeColor.r * _fadeDensity; + outColor->g = outColor->g * (1.0f - _fadeDensity) + _fadeColor.g * _fadeDensity; + outColor->b = outColor->b * (1.0f - _fadeDensity) + _fadeColor.b * _fadeDensity; } -Fog *SetEffects::findFog(const char *fogName) { - if (!_fogs) +Fog *SetEffects::findFog(const char *fogName) const { + if (!_fogs) { return nullptr; + } Fog *fog = _fogs; diff --git a/engines/bladerunner/set_effects.h b/engines/bladerunner/set_effects.h index 1e041ad1d4..81d7b93149 100644 --- a/engines/bladerunner/set_effects.h +++ b/engines/bladerunner/set_effects.h @@ -34,19 +34,18 @@ namespace BladeRunner { class SetEffects { BladeRunnerEngine *_vm; -private: Color _distanceColor; float _distanceCoeficient; Color _fadeColor; float _fadeDensity; - int _fogsCount; + int _fogCount; Fog *_fogs; public: SetEffects(BladeRunnerEngine *vm); ~SetEffects(); - void read(Common::ReadStream *stream, int framesCount); + void read(Common::ReadStream *stream, int frameCount); void reset(); @@ -54,14 +53,13 @@ public: void setFadeColor(float r, float g, float b); void setFadeDensity(float density); - void setFogColor(const char* fogName, float r, float g, float b); - void setFogDensity(const char* fogName, float density); - - void calculateColor(Vector3 viewPosition, Vector3 position, float *outCoeficient, Color *outColor); -private: + void setFogColor(const char *fogName, float r, float g, float b); + void setFogDensity(const char *fogName, float density); - Fog *findFog(const char* fogName); + void calculateColor(Vector3 viewPosition, Vector3 position, float *outCoeficient, Color *outColor) const; +private: + Fog *findFog(const char *fogName) const; }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/settings.cpp b/engines/bladerunner/settings.cpp index 7db1192c89..d0ba84321c 100644 --- a/engines/bladerunner/settings.cpp +++ b/engines/bladerunner/settings.cpp @@ -32,7 +32,12 @@ namespace BladeRunner { -Settings::Settings(BladeRunnerEngine *vm) : _vm(vm) { +Settings::Settings(BladeRunnerEngine *vm) { + _vm = vm; + + _difficulty = 1; + _playerAgenda = 1; + _chapter = 1; _gamma = 1.0f; @@ -46,6 +51,13 @@ Settings::Settings(BladeRunnerEngine *vm) : _vm(vm) { _fullHDFrames = true; _mst3k = false; + + _ammoType = 0; + _ammoAmounts[0] = 0; + _ammoAmounts[1] = 0; + _ammoAmounts[2] = 0; + + _learyMode = false; } bool Settings::openNewScene() { @@ -107,6 +119,12 @@ int Settings::getAmmoAmount(int ammoType) { return _ammoAmounts[ammoType]; } +void Settings::setAmmoType(int ammoType) { + if (_ammoAmounts[ammoType] > 0) { + _ammoType = ammoType; + } +} + void Settings::addAmmo(int ammoType, int ammo) { if (ammoType > _ammoType || _ammoAmounts[_ammoType] == 0) _ammoType = ammoType; diff --git a/engines/bladerunner/settings.h b/engines/bladerunner/settings.h index 713acfe492..85674d25c4 100644 --- a/engines/bladerunner/settings.h +++ b/engines/bladerunner/settings.h @@ -58,6 +58,8 @@ class Settings { int _ammoType; int _ammoAmounts[3]; + bool _learyMode; + public: Settings(BladeRunnerEngine *vm); @@ -104,11 +106,20 @@ public: int getAmmoType(); int getAmmoAmount(int ammoType); + void setAmmoType(int ammoType); int getDifficulty(); int getPlayerAgenda(); void setPlayerAgenda(int agenda); void addAmmo(int ammoType, int ammo); + + bool getLearyMode() { + return _learyMode; + } + + void setLearyMode(bool learyMode) { + _learyMode = learyMode; + } }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/shape.cpp b/engines/bladerunner/shape.cpp index 8e62aa4057..571bb90938 100644 --- a/engines/bladerunner/shape.cpp +++ b/engines/bladerunner/shape.cpp @@ -32,8 +32,9 @@ namespace BladeRunner { -Shape::Shape(BladeRunnerEngine *vm) - : _vm(vm), _data(nullptr) { +Shape::Shape(BladeRunnerEngine *vm) { + _vm = vm; + _data = nullptr; } Shape::~Shape() { @@ -86,7 +87,7 @@ bool Shape::readFromContainer(const Common::String &container, int index) { return true; } -void Shape::draw(Graphics::Surface &surface, int x, int y) { +void Shape::draw(Graphics::Surface &surface, int x, int y) const { // debug("x=%d, y=%d", x, y); // debug("w=%d, h=%d", _width, _height); @@ -110,13 +111,13 @@ void Shape::draw(Graphics::Surface &surface, int x, int y) { } byte *src_p = _data + 2 * (src_y * _width + src_x); - byte *dst_p = (byte*)surface.getBasePtr(dst_x, dst_y); + byte *dst_p = (byte *)surface.getBasePtr(dst_x, dst_y); for (int yi = 0; yi != rect_h; ++yi) { for (int xi = 0; xi != rect_w; ++xi) { uint16 color = READ_LE_UINT16(src_p); if ((color & 0x8000) == 0) { - *(uint16*)dst_p = color; + *(uint16 *)dst_p = color; } src_p += 2; diff --git a/engines/bladerunner/shape.h b/engines/bladerunner/shape.h index cd06e79a24..799826cb4b 100644 --- a/engines/bladerunner/shape.h +++ b/engines/bladerunner/shape.h @@ -46,7 +46,7 @@ public: bool readFromContainer(const Common::String &container, int index); - void draw(Graphics::Surface &surface, int x, int y); + void draw(Graphics::Surface &surface, int x, int y) const; int getWidth() const { return _width; } int getHeight() const { return _height; } diff --git a/engines/bladerunner/slice_animations.cpp b/engines/bladerunner/slice_animations.cpp index 503193c2a6..181b11d9f1 100644 --- a/engines/bladerunner/slice_animations.cpp +++ b/engines/bladerunner/slice_animations.cpp @@ -67,27 +67,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].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", - i, - _animations[i].frameCount, - _animations[i].frameSize, - _animations[i].fps, - _animations[i].unk0, - _animations[i].unk1, - _animations[i].unk2, - _animations[i].unk3, - _animations[i].offset); -#endif + _animations[i].facingChange = file.readFloatLE(); + _animations[i].offset = file.readUint32LE(); } _pages.resize(_pageCount); @@ -171,14 +158,14 @@ void *SliceAnimations::getFramePtr(uint32 animation, uint32 frame) { _pages[page]._lastAccess = _vm->_system->getMillis(); - return (byte*)_pages[page]._data + pageOffset; + return (byte *)_pages[page]._data + pageOffset; } -Vector3 SliceAnimations::getPositionChange(int animation) { +Vector3 SliceAnimations::getPositionChange(int animation) const { return _animations[animation].positionChange; } -float SliceAnimations::getFacingChange(int animation) { +float SliceAnimations::getFacingChange(int animation) const { return _animations[animation].facingChange; } diff --git a/engines/bladerunner/slice_animations.h b/engines/bladerunner/slice_animations.h index b5b60ef096..a34b6ec13e 100644 --- a/engines/bladerunner/slice_animations.h +++ b/engines/bladerunner/slice_animations.h @@ -36,12 +36,6 @@ namespace BladeRunner { class BladeRunnerEngine; -struct SlicePalette { - uint16 color555[256]; - Color256 color[256]; - -// uint16 &operator[](size_t i) { return color555[i]; } -}; class SliceAnimations { friend class SliceRenderer; @@ -55,6 +49,13 @@ class SliceAnimations { uint32 offset; }; + struct Palette { + uint16 color555[256]; + Color256 color[256]; + + // uint16 &operator[](size_t i) { return color555[i]; } + }; + struct Page { void *_data; uint32 _lastAccess; @@ -80,7 +81,7 @@ class SliceAnimations { uint32 _pageCount; uint32 _paletteCount; - Common::Array<SlicePalette> _palettes; + Common::Array<Palette> _palettes; Common::Array<Animation> _animations; Common::Array<Page> _pages; @@ -100,14 +101,14 @@ public: bool openCoreAnim(); bool openHDFrames(); - SlicePalette &getPalette(int i) { return _palettes[i]; }; - void *getFramePtr(uint32 animation, uint32 frame); + Palette &getPalette(int i) { return _palettes[i]; }; + void *getFramePtr(uint32 animation, uint32 frame); - int getFrameCount(int animation){ return _animations[animation].frameCount; } - float getFPS(int animation){ return _animations[animation].fps; } + int getFrameCount(int animation) const { return _animations[animation].frameCount; } + float getFPS(int animation) const { return _animations[animation].fps; } - Vector3 getPositionChange(int animation); - float getFacingChange(int animation); + Vector3 getPositionChange(int animation) const; + float getFacingChange(int animation) const; }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/slice_renderer.cpp b/engines/bladerunner/slice_renderer.cpp index 0bbd201ee0..56bdc66fe7 100644 --- a/engines/bladerunner/slice_renderer.cpp +++ b/engines/bladerunner/slice_renderer.cpp @@ -234,7 +234,7 @@ void SliceRenderer::loadFrame(int animation, int frame) { _frame = frame; _sliceFramePtr = _vm->_sliceAnimations->getFramePtr(_animation, _frame); - Common::MemoryReadStream stream((byte*)_sliceFramePtr, _vm->_sliceAnimations->_animations[_animation].frameSize); + Common::MemoryReadStream stream((byte *)_sliceFramePtr, _vm->_sliceAnimations->_animations[_animation].frameSize); _frameScale.x = stream.readFloatLE(); _frameScale.y = stream.readFloatLE(); @@ -398,7 +398,7 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos int frameY = sliceLineIterator._startY; - uint16 *frameLinePtr = (uint16*)surface.getPixels() + 640 * frameY; + uint16 *frameLinePtr = (uint16 *)surface.getPixels() + 640 * frameY; uint16 *zBufferLinePtr = zbuffer + 640 * frameY; while (sliceLineIterator._currentY <= sliceLineIterator._endY) { @@ -433,7 +433,7 @@ void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 pos } } -void SliceRenderer::drawOnScreen(int animationId, int animationFrame, int screenX, int screenY, float facing, float scale, Graphics::Surface &surface, uint16 *zbuffer) { +void SliceRenderer::drawOnScreen(int animationId, int animationFrame, int screenX, int screenY, float facing, float scale, Graphics::Surface &surface) { if (scale == 0.0f) { return; } @@ -481,7 +481,7 @@ void SliceRenderer::drawOnScreen(int animationId, int animationFrame, int screen float currentSlice = 0; float sliceStep = 1.0f / size / _frameSliceHeight; - uint16 *frameLinePtr = (uint16*)surface.getPixels() + 640 * frameY; + uint16 *frameLinePtr = (uint16 *)surface.getPixels() + 640 * frameY; uint16 lineZbuffer[640]; while (currentSlice < _frameSliceCount) { @@ -499,13 +499,13 @@ void SliceRenderer::drawSlice(int slice, bool advanced, uint16 *frameLinePtr, ui if (slice < 0 || (uint32)slice >= _frameSliceCount) return; - SlicePalette &palette = _vm->_sliceAnimations->getPalette(_framePaletteIndex); + SliceAnimations::Palette &palette = _vm->_sliceAnimations->getPalette(_framePaletteIndex); - byte *p = (byte*)_sliceFramePtr + 0x20 + 4 * slice; + byte *p = (byte *)_sliceFramePtr + 0x20 + 4 * slice; uint32 polyOffset = READ_LE_UINT32(p); - p = (byte*)_sliceFramePtr + polyOffset; + p = (byte *)_sliceFramePtr + polyOffset; uint32 polyCount = READ_LE_UINT32(p); p += 4; diff --git a/engines/bladerunner/slice_renderer.h b/engines/bladerunner/slice_renderer.h index aeca8c6c2d..bf00454cb1 100644 --- a/engines/bladerunner/slice_renderer.h +++ b/engines/bladerunner/slice_renderer.h @@ -104,7 +104,7 @@ public: void getScreenRectangle(Common::Rect *screenRectangle, int animationId, int animationFrame, Vector3 position, float facing, float scale); void drawInWorld(int animationId, int animationFrame, Vector3 position, float facing, float scale, Graphics::Surface &surface, uint16 *zbuffer); - void drawOnScreen(int animationId, int animationFrame, int screenX, int screenY, float facing, float scale, Graphics::Surface &surface, uint16 *zbuffer); + void drawOnScreen(int animationId, int animationFrame, int screenX, int screenY, float facing, float scale, Graphics::Surface &surface); void preload(int animationId); diff --git a/engines/bladerunner/suspects_database.cpp b/engines/bladerunner/suspects_database.cpp index 5c77356d1c..c0e8469852 100644 --- a/engines/bladerunner/suspects_database.cpp +++ b/engines/bladerunner/suspects_database.cpp @@ -45,62 +45,62 @@ void SuspectDatabaseEntry::setSex(int sex) { } bool SuspectDatabaseEntry::addMOClue(int clueId) { - if (_moCluesCount >= MO_CLUES_COUNT) { + if (_moClueCount >= kMOClueCount) { return false; } - _moClues[_moCluesCount++] = clueId; + _moClues[_moClueCount++] = clueId; return true; } bool SuspectDatabaseEntry::addWhereaboutsClue(int clueId) { - if (_whereaboutsCluesCount >= WHEREABOUTS_CLUES_COUNT) { + if (_whereaboutsClueCount >= kWhereaboutsClueCount) { return false; } - _whereaboutsClues[_whereaboutsCluesCount++] = clueId; + _whereaboutsClues[_whereaboutsClueCount++] = clueId; return true; } bool SuspectDatabaseEntry::addReplicantClue(int clueId) { - if (_replicantCluesCount >= REPLICANT_CLUES_COUNT) { + if (_replicantClueCount >= kReplicantClueCount) { return false; } - _replicantClues[_replicantCluesCount++] = clueId; + _replicantClues[_replicantClueCount++] = clueId; return true; } bool SuspectDatabaseEntry::addNonReplicantClue(int clueId) { - if (_nonReplicantCluesCount >= NONREPLICANT_CLUES_COUNT) { + if (_nonReplicantClueCount >= kNonReplicantClueCount) { return false; } - _nonReplicantClues[_nonReplicantCluesCount++] = clueId; + _nonReplicantClues[_nonReplicantClueCount++] = clueId; return true; } bool SuspectDatabaseEntry::addOtherClue(int clueId) { - if (_otherCluesCount >= OTHER_CLUES_COUNT) { + if (_otherClueCount >= kOtherClueCount) { return false; } - _otherClues[_otherCluesCount++] = clueId; + _otherClues[_otherClueCount++] = clueId; return true; } bool SuspectDatabaseEntry::addIdentityClue(int clueId) { - if (_identityCluesCount >= IDENTITY_CLUES_COUNT) { + if (_identityClueCount >= kIdentityClueCount) { return false; } - _identityClues[_identityCluesCount++] = clueId; + _identityClues[_identityClueCount++] = clueId; return true; } bool SuspectDatabaseEntry::addPhotoClue(int shapeId, int clueId) { - if (_photoCluesCount >= PHOTO_CLUES_COUNT) { + if (_photoClueCount >= kPhotoClueCount) { return false; } - _photoClues[_photoCluesCount][0] = clueId; - _photoClues[_photoCluesCount][1] = shapeId; - _photoClues[_photoCluesCount][2] = -1; + _photoClues[_photoClueCount][0] = clueId; + _photoClues[_photoClueCount][1] = shapeId; + _photoClues[_photoClueCount][2] = -1; - _photoCluesCount++; + _photoClueCount++; return true; } @@ -109,7 +109,7 @@ const char *SuspectDatabaseEntry::getName() { } bool SuspectDatabaseEntry::hasMOClue(int clueId) { - for (int i = 0; i < _moCluesCount; i++) { + for (int i = 0; i < _moClueCount; i++) { if (_moClues[i] == clueId) { return true; } @@ -118,7 +118,7 @@ bool SuspectDatabaseEntry::hasMOClue(int clueId) { } bool SuspectDatabaseEntry::hasWhereaboutsClue(int clueId) { - for (int i = 0; i < _whereaboutsCluesCount; i++) { + for (int i = 0; i < _whereaboutsClueCount; i++) { if (_whereaboutsClues[i] == clueId) { return true; } @@ -127,7 +127,7 @@ bool SuspectDatabaseEntry::hasWhereaboutsClue(int clueId) { } bool SuspectDatabaseEntry::hasReplicantClue(int clueId) { - for (int i = 0; i < _replicantCluesCount; i++) { + for (int i = 0; i < _replicantClueCount; i++) { if (_replicantClues[i] == clueId) { return true; } @@ -136,7 +136,7 @@ bool SuspectDatabaseEntry::hasReplicantClue(int clueId) { } bool SuspectDatabaseEntry::hasNonReplicantClue(int clueId) { - for (int i = 0; i < _nonReplicantCluesCount; i++) { + for (int i = 0; i < _nonReplicantClueCount; i++) { if (_nonReplicantClues[i] == clueId) { return true; } @@ -145,7 +145,7 @@ bool SuspectDatabaseEntry::hasNonReplicantClue(int clueId) { } bool SuspectDatabaseEntry::hasOtherClue(int clueId) { - for (int i = 0; i < _otherCluesCount; i++) { + for (int i = 0; i < _otherClueCount; i++) { if (_otherClues[i] == clueId) { return true; } @@ -154,7 +154,7 @@ bool SuspectDatabaseEntry::hasOtherClue(int clueId) { } bool SuspectDatabaseEntry::hasIdentityClue(int clueId) { - for (int i = 0; i < _identityCluesCount; i++) { + for (int i = 0; i < _identityClueCount; i++) { if (_identityClues[i] == clueId) { return true; } @@ -185,34 +185,34 @@ int SuspectDatabaseEntry::getPhotoClue3(int photoId) { void SuspectDatabaseEntry::reset() { _actorId = -1; _sex = -1; - for (int i = 0; i < MO_CLUES_COUNT; i++) { + for (int i = 0; i < kMOClueCount; i++) { _moClues[i] = -1; } - for (int i = 0; i < WHEREABOUTS_CLUES_COUNT; i++) { + for (int i = 0; i < kWhereaboutsClueCount; i++) { _whereaboutsClues[i] = -1; } - for (int i = 0; i < IDENTITY_CLUES_COUNT; i++) { + for (int i = 0; i < kIdentityClueCount; i++) { _identityClues[i] = -1; } - for (int i = 0; i < REPLICANT_CLUES_COUNT; i++) { + for (int i = 0; i < kReplicantClueCount; i++) { _replicantClues[i] = -1; } - for (int i = 0; i < NONREPLICANT_CLUES_COUNT; i++) { + for (int i = 0; i < kNonReplicantClueCount; i++) { _nonReplicantClues[i] = -1; } - for (int i = 0; i < OTHER_CLUES_COUNT; i++) { + for (int i = 0; i < kOtherClueCount; i++) { _otherClues[i] = -1; } // photo clues are not reseted in original game - _moCluesCount = 0; - _whereaboutsCluesCount = 0; - _replicantCluesCount = 0; - _nonReplicantCluesCount = 0; - _otherCluesCount = 0; - _identityCluesCount = 0; - _photoCluesCount = 0; + _moClueCount = 0; + _whereaboutsClueCount = 0; + _replicantClueCount = 0; + _nonReplicantClueCount = 0; + _otherClueCount = 0; + _identityClueCount = 0; + _photoClueCount = 0; } SuspectsDatabase::SuspectsDatabase(BladeRunnerEngine *vm, int size) { diff --git a/engines/bladerunner/suspects_database.h b/engines/bladerunner/suspects_database.h index 2b087909bd..71db4dba68 100644 --- a/engines/bladerunner/suspects_database.h +++ b/engines/bladerunner/suspects_database.h @@ -29,33 +29,36 @@ namespace BladeRunner { class BladeRunnerEngine; class TextResource; -#define MO_CLUES_COUNT 10 -#define WHEREABOUTS_CLUES_COUNT 10 -#define REPLICANT_CLUES_COUNT 20 -#define NONREPLICANT_CLUES_COUNT 20 -#define OTHER_CLUES_COUNT 20 -#define IDENTITY_CLUES_COUNT 10 -#define PHOTO_CLUES_COUNT 6 - class SuspectDatabaseEntry { +private: + static const int kMOClueCount = 10; + static const int kWhereaboutsClueCount = 10; + static const int kReplicantClueCount = 20; + static const int kNonReplicantClueCount = 20; + static const int kOtherClueCount = 20; + static const int kIdentityClueCount = 10; + static const int kPhotoClueCount = 6; + BladeRunnerEngine *_vm; int _actorId; int _sex; - int _moClues[MO_CLUES_COUNT]; - int _whereaboutsClues[WHEREABOUTS_CLUES_COUNT]; - int _replicantClues[REPLICANT_CLUES_COUNT]; - int _nonReplicantClues[NONREPLICANT_CLUES_COUNT]; - int _otherClues[OTHER_CLUES_COUNT]; - int _identityClues[IDENTITY_CLUES_COUNT]; - int _photoClues[PHOTO_CLUES_COUNT][3]; - int _moCluesCount; - int _whereaboutsCluesCount; - int _replicantCluesCount; - int _nonReplicantCluesCount; - int _otherCluesCount; - int _identityCluesCount; - int _photoCluesCount; + + int _moClues[kMOClueCount]; + int _whereaboutsClues[kWhereaboutsClueCount]; + int _replicantClues[kReplicantClueCount]; + int _nonReplicantClues[kNonReplicantClueCount]; + int _otherClues[kOtherClueCount]; + int _identityClues[kIdentityClueCount]; + int _photoClues[kPhotoClueCount][3]; + + int _moClueCount; + int _whereaboutsClueCount; + int _replicantClueCount; + int _nonReplicantClueCount; + int _otherClueCount; + int _identityClueCount; + int _photoClueCount; public: SuspectDatabaseEntry(BladeRunnerEngine *_vm); diff --git a/engines/bladerunner/text_resource.cpp b/engines/bladerunner/text_resource.cpp index 78a73f5e71..42d30038bc 100644 --- a/engines/bladerunner/text_resource.cpp +++ b/engines/bladerunner/text_resource.cpp @@ -30,7 +30,8 @@ namespace BladeRunner { -TextResource::TextResource(BladeRunnerEngine *vm) : _vm(vm) { +TextResource::TextResource(BladeRunnerEngine *vm) { + _vm = vm; _count = 0; _ids = nullptr; _offsets = nullptr; @@ -43,11 +44,11 @@ TextResource::~TextResource() { delete[] _strings; } -bool TextResource::open(const char *name) { - assert(strlen(name) <= 8); +bool TextResource::open(const Common::String &name) { + assert(name.size() <= 8); char resName[13]; - sprintf(resName, "%s.TR%s", name, _vm->_languageCode); + sprintf(resName, "%s.TR%s", name.c_str(), _vm->_languageCode); Common::ScopedPtr<Common::SeekableReadStream> s(_vm->getResourceStream(resName)); if (!s) return false; @@ -78,7 +79,7 @@ bool TextResource::open(const char *name) { s->read(_strings, remain); -#if 0 +#if BLADERUNNER_DEBUG_CONSOLE debug("\n%s\n----------------", resName); for (uint32 i = 0; i != (uint32)_count; ++i) { debug("%3d: %s", i, getText(i)); @@ -88,7 +89,7 @@ bool TextResource::open(const char *name) { return true; } -const char *TextResource::getText(uint32 id) { +const char *TextResource::getText(uint32 id) const { for (uint32 i = 0; i != _count; ++i) { if (_ids[i] == id) { return _strings + _offsets[i]; @@ -98,4 +99,8 @@ const char *TextResource::getText(uint32 id) { return ""; } +int TextResource::getCount() const { + return _count; +} + } // End of namespace BladeRunner diff --git a/engines/bladerunner/text_resource.h b/engines/bladerunner/text_resource.h index 9554267b9b..b513629d9d 100644 --- a/engines/bladerunner/text_resource.h +++ b/engines/bladerunner/text_resource.h @@ -23,7 +23,7 @@ #ifndef BLADERUNNER_TEXT_RESOURCE_H #define BLADERUNNER_TEXT_RESOURCE_H -#include "common/scummsys.h" +#include "common/str.h" namespace BladeRunner { @@ -42,8 +42,9 @@ public: TextResource(BladeRunnerEngine *vm); ~TextResource(); - bool open(const char *name); - const char *getText(uint32 id); + bool open(const Common::String &name); + const char *getText(uint32 id) const; + int getCount() const; }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/elevator.cpp b/engines/bladerunner/ui/elevator.cpp index 99f3160141..f0c8d7d921 100644 --- a/engines/bladerunner/elevator.cpp +++ b/engines/bladerunner/ui/elevator.cpp @@ -20,17 +20,16 @@ * */ -#include "bladerunner/elevator.h" - -#include "bladerunner/bladerunner.h" +#include "bladerunner/ui/elevator.h" #include "bladerunner/actor.h" +#include "bladerunner/bladerunner.h" #include "bladerunner/audio_player.h" -#include "bladerunner/gameinfo.h" +#include "bladerunner/game_info.h" #include "bladerunner/mouse.h" #include "bladerunner/shape.h" #include "bladerunner/script/script.h" -#include "bladerunner/ui_image_picker.h" +#include "bladerunner/ui/ui_image_picker.h" #include "bladerunner/vqa_player.h" #include "common/rect.h" @@ -39,7 +38,8 @@ namespace BladeRunner { -Elevator::Elevator(BladeRunnerEngine *vm) : _vm(vm) { +Elevator::Elevator(BladeRunnerEngine *vm) { + _vm = vm; reset(); _imagePicker = new UIImagePicker(vm, 8); } @@ -49,11 +49,6 @@ Elevator::~Elevator() { reset(); } -void elevator_mouseInCallback(int, void*); -void elevator_mouseOutCallback(int, void*); -void elevator_mouseDownCallback(int, void*); -void elevator_mouseUpCallback(int, void*); - int Elevator::activate(int elevatorId) { const char *vqaName; @@ -67,10 +62,11 @@ int Elevator::activate(int elevatorId) { error("Invalid elevator id"); } - if (!_vm->openArchive("MODE.MIX")) + if (!_vm->openArchive("MODE.MIX")) { return 0; + } - _vqaPlayer = new VQAPlayer(_vm, &_vm->_surfaceInterface); + _vqaPlayer = new VQAPlayer(_vm, &_vm->_surfaceBack); if (!_vqaPlayer->open(vqaName)) { return 0; } @@ -151,10 +147,10 @@ int Elevator::activate(int elevatorId) { } _imagePicker->activate( - elevator_mouseInCallback, - elevator_mouseOutCallback, - elevator_mouseDownCallback, - elevator_mouseUpCallback, + mouseInCallback, + mouseOutCallback, + mouseDownCallback, + mouseUpCallback, this ); @@ -213,8 +209,8 @@ void Elevator::tick() { int frame = _vqaPlayer->update(); assert(frame >= -1); - // vqaPlayer renders to _surfaceInterface - blit(_vm->_surfaceInterface, _vm->_surfaceGame); + // vqaPlayer renders to _surfaceBack + blit(_vm->_surfaceBack, _vm->_surfaceFront); Common::Point p = _vm->getMousePos(); @@ -226,10 +222,10 @@ void Elevator::tick() { _vm->_mouse->setCursor(0); } - _imagePicker->draw(_vm->_surfaceGame); - _vm->_mouse->draw(_vm->_surfaceGame, p.x, p.y); + _imagePicker->draw(_vm->_surfaceFront); + _vm->_mouse->draw(_vm->_surfaceFront, p.x, p.y); - _vm->blitToScreen(_vm->_surfaceGame); + _vm->blitToScreen(_vm->_surfaceFront); tickDescription(); _vm->_system->delayMillis(10); } @@ -308,22 +304,22 @@ void Elevator::resume() { // TODO } -void elevator_mouseInCallback(int buttonId, void *self) { - ((Elevator*)self)->buttonFocus(buttonId); +void Elevator::mouseInCallback(int buttonId, void *self) { + ((Elevator *)self)->buttonFocus(buttonId); } -void elevator_mouseOutCallback(int, void *self) { - ((Elevator*)self)->buttonFocus(-1); +void Elevator::mouseOutCallback(int, void *self) { + ((Elevator *)self)->buttonFocus(-1); } -void elevator_mouseDownCallback(int, void *self) { - Elevator *elevator = ((Elevator*)self); +void Elevator::mouseDownCallback(int, void *self) { + Elevator *elevator = ((Elevator *)self); const char *name = elevator->_vm->_gameInfo->getSfxTrack(515); elevator->_vm->_audioPlayer->playAud(name, 100, 0, 0, 50, 0); } -void elevator_mouseUpCallback(int buttonId, void *self) { - ((Elevator*)self)->buttonClick(buttonId); +void Elevator::mouseUpCallback(int buttonId, void *self) { + ((Elevator *)self)->buttonClick(buttonId); } } // End of namespace BladeRunner diff --git a/engines/bladerunner/elevator.h b/engines/bladerunner/ui/elevator.h index 0a5940a3b3..f2e1443929 100644 --- a/engines/bladerunner/elevator.h +++ b/engines/bladerunner/ui/elevator.h @@ -37,17 +37,12 @@ class Elevator { bool _isOpen; VQAPlayer *_vqaPlayer; int _buttonClicked; - Common::Array<Shape*> _shapes; + Common::Array<Shape *> _shapes; UIImagePicker *_imagePicker; int _actorId; int _sentenceId; int _timeSpeakDescription; - friend void elevator_mouseInCallback(int, void*); - friend void elevator_mouseOutCallback(int, void*); - friend void elevator_mouseDownCallback(int, void*); - friend void elevator_mouseUpCallback(int, void*); - public: Elevator(BladeRunnerEngine *vm); ~Elevator(); @@ -65,6 +60,12 @@ public: void resetDescription(); void tickDescription(); void resume(); + +private: + static void mouseInCallback(int, void *); + static void mouseOutCallback(int, void *); + static void mouseDownCallback(int, void *); + static void mouseUpCallback(int, void *); }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/kia.cpp b/engines/bladerunner/ui/kia.cpp new file mode 100644 index 0000000000..09c5918872 --- /dev/null +++ b/engines/bladerunner/ui/kia.cpp @@ -0,0 +1,1229 @@ +/* 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/ui/kia.h" + +#include "bladerunner/actor.h" +#include "bladerunner/audio_player.h" +#include "bladerunner/bladerunner.h" +#include "bladerunner/combat.h" +#include "bladerunner/font.h" +#include "bladerunner/game_constants.h" +#include "bladerunner/game_flags.h" +#include "bladerunner/game_info.h" +#include "bladerunner/mouse.h" +#include "bladerunner/scene.h" +#include "bladerunner/shape.h" +#include "bladerunner/script/kia.h" +#include "bladerunner/settings.h" +#include "bladerunner/slice_renderer.h" +#include "bladerunner/text_resource.h" +#include "bladerunner/ui/kia_log.h" +#include "bladerunner/ui/kia_section_base.h" +#include "bladerunner/ui/kia_section_clues.h" +#include "bladerunner/ui/kia_section_crimes.h" +#include "bladerunner/ui/kia_section_diagnostic.h" +#include "bladerunner/ui/kia_section_help.h" +#include "bladerunner/ui/kia_section_load.h" +#include "bladerunner/ui/kia_section_settings.h" +#include "bladerunner/ui/kia_section_pogo.h" +#include "bladerunner/ui/kia_section_save.h" +#include "bladerunner/ui/kia_section_suspects.h" +#include "bladerunner/ui/kia_shapes.h" +#include "bladerunner/ui/ui_image_picker.h" +#include "bladerunner/vqa_player.h" + +#include "common/str.h" +#include "common/keyboard.h" + +namespace BladeRunner { + +const char *KIA::kPogo = "POGO"; + +enum KIASections { + kKIASectionNone = 0, + kKIASectionCrimes = 1, + kKIASectionSuspects = 2, + kKIASectionClues = 3, + kKIASectionSettings = 4, + kKIASectionHelp = 5, + kKIASectionSave = 6, + kKIASectionLoad = 7, + kKIASectionQuit = 8, + kKIASectionDiagnostic = 9, + kKIASectionPogo = 10 +}; + +KIA::KIA(BladeRunnerEngine *vm) { + _vm = vm; + + _script = new KIAScript(_vm); + _log = new KIALog(_vm); + _shapes = new KIAShapes(_vm); + + _forceOpen = 0; + _currentSectionId = kKIASectionNone; + _lastSectionIdKIA = kKIASectionCrimes; + _lastSectionIdOptions = kKIASectionSettings; + _playerVqaTimeLast = _vm->getTotalPlayTime(); + _playerVqaFrame = 0; + _playerVisualizerState = 0; + _playerPhotographId = -1; + _playerPhotograph = nullptr; + _playerSliceModelId = -1; + _playerSliceModelAngle = 0.0f; + // _playerImage = nullptr; + _timeLast = _vm->getTotalPlayTime(); + _playerActorDialogueQueueCapacity = 31; + _playerActorDialogueQueuePosition = 0; + _playerActorDialogueQueueSize = 0; + _playerActorDialogueQueue = new ActorDialogueQueueEntry[_playerActorDialogueQueueCapacity]; + _playerActorDialogueState = 0; + _currentSection = nullptr; + _mainVqaPlayer = nullptr; + _playerVqaPlayer = nullptr; + // _thumbnail = nullptr; + + _pogoPos = 0; + + _buttons = new UIImagePicker(_vm, 22); + + _crimesSection = new KIASectionCrimes(_vm); // PlayerActor->_clues + _suspectsSection = new KIASectionSuspects(_vm); // PlayerActor->_clues + _cluesSection = new KIASectionClues(_vm, _vm->_playerActor->_clues); + _settingsSection = new KIASectionSettings(_vm); + _helpSection = new KIASectionHelp(_vm); + _saveSection = new KIASectionSave(_vm); + _loadSection = new KIASectionLoad(_vm); + _diagnosticSection = new KIASectionDiagnostic(_vm); + _pogoSection = new KIASectionPogo(_vm); +} + +KIA::~KIA() { + delete _playerPhotograph; + // delete _playerImage; + // delete _thumbnail; + delete _settingsSection; + delete _buttons; + delete _shapes; + delete _log; + delete _script; +} + +void KIA::openLastOpened() { + open(_lastSectionIdKIA); +} + +void KIA::openOptions() { + open(kKIASectionSettings); +} + +void KIA::tick() { + if (!_currentSectionId) { + return; + } + + int timeNow = _vm->getTotalPlayTime(); + int timeDiff = timeNow - _timeLast; + + if (_playerActorDialogueQueueSize == _playerActorDialogueQueuePosition) { + _playerActorDialogueState = 0; + } else if (_playerActorDialogueState == 0) { + if (_playerSliceModelId == -1 && _playerPhotographId == -1) { //&& !this->_playerImage + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(495), 70, 0, 0, 50, 0); + } + _playerActorDialogueState = 1; + } else if (_playerActorDialogueState == 200) { + if (!_vm->_actors[_playerActorDialogueQueue[_playerActorDialogueQueuePosition].actorId]->isSpeeching()) { + if (_playerActorDialogueQueueSize != _playerActorDialogueQueuePosition) { + _playerActorDialogueQueuePosition = (_playerActorDialogueQueuePosition + 1) % _playerActorDialogueQueueCapacity; + } + if (_playerActorDialogueQueueSize != _playerActorDialogueQueuePosition) { + _vm->_actors[_playerActorDialogueQueue[_playerActorDialogueQueuePosition].actorId]->speechPlay(_playerActorDialogueQueue[_playerActorDialogueQueuePosition].sentenceId, true); + } + } + } else { + _playerActorDialogueState += timeDiff; + + if (_playerActorDialogueState >= 200) { + _playerActorDialogueState = 200; + _vm->_actors[_playerActorDialogueQueue[_playerActorDialogueQueuePosition].actorId]->speechPlay(_playerActorDialogueQueue[_playerActorDialogueQueuePosition].sentenceId, true); + } + } + + int timeDiffDiv48 = (timeNow - _playerVqaTimeLast) / 48; + if (timeDiffDiv48 > 0) { + _playerVqaTimeLast = timeNow; + if (_playerActorDialogueQueueSize == _playerActorDialogueQueuePosition || _playerSliceModelId != -1 || _playerPhotographId != -1) { // || this->_viewerImage + if (_playerVisualizerState > 0) { + _playerVisualizerState = MAX(_playerVisualizerState - timeDiffDiv48, 0); + } + } else { + if (_playerVisualizerState < 2) { + _playerVisualizerState = MIN(_playerVisualizerState + timeDiffDiv48, 2); + + } + } + + if ( _playerSliceModelId != -1 || _playerPhotographId != -1 ) { // || _playerImage + if (_playerVqaFrame < 8) { + int newVqaFrame = MIN(timeDiffDiv48 + _playerVqaFrame, 8); + if (_playerVqaFrame <= 0 && newVqaFrame > 0) { + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(497), 100, 70, 70, 50, 0); + } + _playerVqaFrame = newVqaFrame; + } + } else { + if (_playerVqaFrame > 0) { + int newVqaFrame = MAX(_playerVqaFrame - timeDiffDiv48, 0); + if (_playerVqaFrame >= 8 && newVqaFrame < 8) + { + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(496), 100, 70, 70, 50, 0); + } + _playerVqaFrame = newVqaFrame; + } + } + } + + _mainVqaPlayer->update(false); + blit(_vm->_surfaceBack, _vm->_surfaceFront); + + Common::Point mouse = _vm->getMousePos(); + + if (!_transitionId) { + _buttons->handleMouseAction(mouse.x, mouse.y, false, false, false); + if (_buttons->hasHoveredImage()) { + _vm->_mouse->setCursor(1); + } else { + _vm->_mouse->setCursor(0); + } + if (_currentSection) { + _currentSection->handleMouseMove(mouse.x, mouse.y); + } + } + + if (_vm->_gameFlags->query(kFlagKIAPrivacyAddon)) { + _shapes->get(40)->draw(_vm->_surfaceFront, 0, 0); + _shapes->get(41)->draw(_vm->_surfaceFront, 211, 447); + } + if (_currentSectionId != kKIASectionQuit && _transitionId != 14) { + if (_vm->_settings->getDifficulty() > 0) { + _vm->_mainFont->drawColor(Common::String::format("%04d", _vm->_gameVars[2]), _vm->_surfaceFront, 580, 341, 0x2991); + } else { + _shapes->get(39)->draw(_vm->_surfaceFront, 583, 342); + } + } + _playerVqaPlayer->seekToFrame(_playerVqaFrame); + _playerVqaPlayer->update(true); //_vm->_surfaceFront, 3 + + _playerSliceModelAngle += (float)(timeDiff) * 1.0f/400.0f; + while (_playerSliceModelAngle >= 2 * M_PI) { + _playerSliceModelAngle -= (float)(2 * M_PI); + } + + if (_playerVqaFrame == 8) { + if (_playerSliceModelId != -1) { + _vm->_sliceRenderer->drawOnScreen(_playerSliceModelId, 0, 585, 80, _playerSliceModelAngle, 100.0, _vm->_surfaceFront); + } else if (_playerPhotographId != -1) { + int width = _playerPhotograph->getWidth(); + int height = _playerPhotograph->getHeight(); + _playerPhotograph->draw(_vm->_surfaceFront, 590 - width / 2, 80 - height / 2); + } + // else if (_playerImage) { + // ... + // } + } + + if (_playerVisualizerState == 1) { + _shapes->get(51)->draw(_vm->_surfaceFront, 576, 174); + } else if (_playerVisualizerState == 2) { + _shapes->get(50)->draw(_vm->_surfaceFront, 576, 174); + _shapes->get(_vm->_rnd.getRandomNumberRng(90, 105))->draw(_vm->_surfaceFront, 576, 174); + } + if (!_transitionId) { + _buttons->draw(_vm->_surfaceFront); + if (_currentSection) { + _currentSection->draw(_vm->_surfaceFront); + } + } + if (_vm->_settings->getAmmoAmount(0) > 0) { + if (_vm->_settings->getAmmoType() == 0) { + _shapes->get(42)->draw(_vm->_surfaceFront, 147, 405); + } else { + _shapes->get(45)->draw(_vm->_surfaceFront, 140, 446); + } + } + if (_vm->_settings->getAmmoAmount(1) > 0) { + if (_vm->_settings->getAmmoType() == 1) { + _shapes->get(43)->draw(_vm->_surfaceFront, 167, 394); + } else { + _shapes->get(46)->draw(_vm->_surfaceFront, 160, 446); + } + } + if (_vm->_settings->getAmmoAmount(2) > 0) { + if (_vm->_settings->getAmmoType() == 2) { + _shapes->get(44)->draw(_vm->_surfaceFront, 189, 385); + } else { + _shapes->get(47)->draw(_vm->_surfaceFront, 182, 446); + } + } + _vm->_mainFont->drawColor("1.00", _vm->_surfaceFront, 438, 471, 0x1CE7); + if (!_transitionId) { + _buttons->drawTooltip(_vm->_surfaceFront, mouse.x, mouse.y); + } + _vm->_mouse->draw(_vm->_surfaceFront, mouse.x, mouse.y); + _vm->blitToScreen(_vm->_surfaceFront); + + _timeLast = timeNow; +} + +void KIA::handleMouseDown(int mouseX, int mouseY, bool mainButton) { + if (!_currentSectionId) { + return; + } + if (mainButton) { + _buttons->handleMouseAction(mouseX, mouseY, true, false, false); + } + if (_currentSection) { + _currentSection->handleMouseDown(mainButton); + } +} + +void KIA::handleMouseUp(int mouseX, int mouseY, bool mainButton) { + if (!_currentSectionId) { + return; + } + if (mainButton) { + _buttons->handleMouseAction(mouseX, mouseY, false, true, false); + } + if (_currentSection) { + _currentSection->handleMouseUp(mainButton); + } + if (_currentSection && _currentSection->_field0) { + if (_currentSectionId == kKIASectionCrimes) { + open(kKIASectionSuspects); + // kiaSuspects::sub_45290C(_suspectsMenu, _crimesMenu->selectedSuspectId); + _log->next(); + _log->clearFuture(); + } else if (_currentSectionId == kKIASectionSuspects) { + open(kKIASectionCrimes); + // kiaCrimes::updateCrime(_crimesMenu, *&_suspectsMenu->data[8052]); + _log->next(); + _log->clearFuture(); + } else { + open(kKIASectionNone); + } + } +} + +void KIA::handleKeyUp(const Common::KeyState &kbd) { + if (!_currentSectionId) { + return; + } + + if (toupper(kbd.ascii) != kPogo[_pogoPos]) { + _pogoPos = 0; + } + if (_currentSectionId != kKIASectionSave) { + if (toupper(kbd.ascii) == kPogo[_pogoPos]) { + ++_pogoPos; + if (!kPogo[_pogoPos]) { + open(kKIASectionPogo); + _pogoPos = 0; + } + } + } + if (kbd.keycode == Common::KEYCODE_ESCAPE) { + if (!_forceOpen) { + open(kKIASectionNone); + } + } else { + if (_currentSection) { + _currentSection->handleKeyUp(kbd); + } + } + if (_currentSection && _currentSection->_field0) { + open(kKIASectionNone); + } +} + +void KIA::handleKeyDown(const Common::KeyState &kbd) { + if (!_currentSectionId) { + return; + } + switch (kbd.keycode) { + case Common::KEYCODE_F1: + open(kKIASectionHelp); + break; + case Common::KEYCODE_F2: + if (!_forceOpen) { + open(kKIASectionSave); + } + break; + case Common::KEYCODE_F3: + open(kKIASectionLoad); + break; + case Common::KEYCODE_F10: + open(kKIASectionQuit); + break; + case Common::KEYCODE_F4: + if (_currentSectionId != kKIASectionCrimes) { + if (!_forceOpen) { + open(kKIASectionCrimes); + _log->next(); + _log->clearFuture(); + } + } + break; + case Common::KEYCODE_F5: + if (_currentSectionId != kKIASectionSuspects) { + if (_forceOpen) { + open(kKIASectionSuspects); + _log->next(); + _log->clearFuture(); + } + } + break; + case Common::KEYCODE_F6: + if (_currentSectionId != kKIASectionClues) { + if (!_forceOpen) { + open(kKIASectionClues); + _log->next(); + _log->clearFuture(); + } + } + break; + default: + if (_currentSection) { + _currentSection->handleKeyDown(kbd); + } + break; + } + if (_currentSection && _currentSection->_field0) { + open(kKIASectionNone); + } +} + +void KIA::playerReset() { + if (_playerActorDialogueQueueSize != _playerActorDialogueQueuePosition) { + if (_playerActorDialogueQueueSize != _playerActorDialogueQueuePosition) { + int actorId = _playerActorDialogueQueue[_playerActorDialogueQueuePosition].actorId; + if (_vm->_actors[actorId]->isSpeeching()) { + _vm->_actors[actorId]->speechStop(); + } + } + } + _playerActorDialogueQueueSize = _playerActorDialogueQueuePosition; + _playerSliceModelId = -1; + if (_playerPhotographId != -1) { + delete _playerPhotograph; + _playerPhotograph = nullptr; + } + _playerPhotographId = -1; + // delete _playerImage; + // _playerImage = nullptr; + _playerActorDialogueState = 0; +} + +void KIA::playActorDialogue(int actorId, int sentenceId) { + int newQueueSize = (_playerActorDialogueQueueSize + 1) % _playerActorDialogueQueueCapacity; + if (newQueueSize != _playerActorDialogueQueuePosition) { + _playerActorDialogueQueue[_playerActorDialogueQueueSize].actorId = actorId; + _playerActorDialogueQueue[_playerActorDialogueQueueSize].sentenceId = sentenceId; + _playerActorDialogueQueueSize = newQueueSize; + } +} + +void KIA::playSliceModel(int sliceModelId) { + if (_playerVqaFrame == 8) { + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(502), 70, 0, 0, 50, 0); + } + _playerSliceModelId = sliceModelId; +} + +void KIA::playPhotograph(int photographId) { + if (_playerPhotographId != -1) { + delete _playerPhotograph; + _playerPhotograph = nullptr; + } + if (_playerVqaFrame == 8) { + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(502), 70, 0, 0, 50, 0); + } + _playerPhotographId = photographId; + _playerPhotograph = new Shape(_vm); + _playerPhotograph->readFromContainer("photos.shp", photographId); +} + +void KIA::mouseDownCallback(int buttonId, void *callbackData) { + KIA *self = (KIA *)callbackData; + switch (buttonId) { + case 0: + case 6: + self->_vm->_audioPlayer->playAud(self->_vm->_gameInfo->getSfxTrack(503), 100, -65, -65, 50, 0); + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + self->_vm->_audioPlayer->playAud(self->_vm->_gameInfo->getSfxTrack(505), 70, 0, 0, 50, 0); + if (buttonId == 12){ + self->_vm->_audioPlayer->playAud(self->_vm->_gameInfo->getSfxTrack(596), 70, 0, 0, 50, 0); + } + break; + case 15: + self->_vm->_audioPlayer->playAud(self->_vm->_gameInfo->getSfxTrack(503), 70, 0, 0, 50, 0); + break; + } +} + +void KIA::mouseUpCallback(int buttonId, void *callbackData) { + KIA *self = (KIA *)callbackData; + switch (buttonId) { + case 0: + case 6: + self->_vm->_audioPlayer->playAud(self->_vm->_gameInfo->getSfxTrack(504), 100, -65, -65, 50, 0); + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + self->_vm->_audioPlayer->playAud(self->_vm->_gameInfo->getSfxTrack(506), 70, 0, 0, 50, 0); + break; + case 15: + self->_vm->_audioPlayer->playAud(self->_vm->_gameInfo->getSfxTrack(504), 100, 0, 0, 50, 0); + break; + default: + break; + } + self->buttonClicked(buttonId); +} + +void KIA::loopEnded(void *callbackData, int frame, int loopId) { + KIA *self = (KIA *)callbackData; + self->_mainVqaPlayer->setLoop(self->getVqaLoopMain(self->_currentSectionId) + 1, -1, kLoopSetModeJustStart, nullptr, nullptr); + self->_transitionId = 0; +} + +void KIA::open(int sectionId) { + if (_currentSectionId == sectionId) { + return; + } + + if (!sectionId) { + unload(); + return; + } + + if (!_currentSectionId) { + init(); + } + + switch (_currentSectionId) { + case kKIASectionCrimes: + _crimesSection->saveToLog(); + break; + case kKIASectionSuspects: + _suspectsSection->saveToLog(); + break; + case kKIASectionClues: + _cluesSection->saveToLog(); + break; + } + + if (sectionId != kKIASectionCrimes && sectionId != kKIASectionSuspects && sectionId != kKIASectionClues) { + playerReset(); + } + + _transitionId = getTransitionId(_currentSectionId, sectionId); + const char *name = getSectionVqaName(sectionId); + if (getSectionVqaName(_currentSectionId) != name) { + if (_mainVqaPlayer) { + _mainVqaPlayer->close(); + delete _mainVqaPlayer; + _mainVqaPlayer = nullptr; + } + + _mainVqaPlayer = new VQAPlayer(_vm, &_vm->_surfaceBack); + _mainVqaPlayer->open(name); + } + + if (_transitionId) { + playTransitionSound(_transitionId); + _mainVqaPlayer->setLoop(getVqaLoopTransition(_transitionId), -1, kLoopSetModeImmediate, nullptr, nullptr); + _mainVqaPlayer->setLoop(getVqaLoopMain(sectionId), -1, kLoopSetModeEnqueue, loopEnded, this); + } else { + int loopId = getVqaLoopMain(sectionId); + _mainVqaPlayer->setLoop(loopId, -1, kLoopSetModeImmediate, nullptr, nullptr); + _mainVqaPlayer->setLoop(loopId + 1, -1, kLoopSetModeJustStart, nullptr, nullptr); + } + + _buttons->resetImages(); + createButtons(sectionId); + switchSection(sectionId); + _currentSectionId = sectionId; + + if (sectionId == kKIASectionCrimes || sectionId == kKIASectionSuspects || sectionId == kKIASectionClues) { + _lastSectionIdKIA = _currentSectionId; + } + + if (sectionId == kKIASectionSettings || sectionId == kKIASectionHelp || sectionId == kKIASectionSave || sectionId == kKIASectionLoad) { + _lastSectionIdOptions = _currentSectionId; + } +} + +void KIA::init() { + if (!_vm->openArchive("MODE.MIX")) { + return; + } + + playerReset(); + _playerVqaFrame = 0; + _playerVqaTimeLast = _vm->getTotalPlayTime(); + _timeLast = _vm->getTotalPlayTime(); + + if (_vm->_gameFlags->query(kFlagKIAPrivacyAddon) && !_vm->_gameFlags->query(kFlagKIAPrivacyAddonIntro)) { + _vm->_gameFlags->set(kFlagKIAPrivacyAddonIntro); + playPrivateAddon(); + } + + _shapes->load(); + _buttons->activate(nullptr, nullptr, mouseDownCallback, mouseUpCallback, this); + _vm->_mouse->setCursor(0); + if (_playerVqaPlayer == nullptr) { + + _playerVqaPlayer = new VQAPlayer(_vm, &_vm->_surfaceFront); + _playerVqaPlayer->open("kiaover.vqa"); + _playerVqaPlayer->setLoop(0, -1, kLoopSetModeJustStart, nullptr, nullptr); + } + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(501), 70, 0, 0, 50, 0); + + // TODO: time->lock(); +} + +void KIA::unload() { + if (!_currentSectionId) { + return; + } + + _forceOpen = false; + + if (_currentSection) { + _currentSection->close(); + _currentSection = nullptr; + } + + _buttons->resetImages(); + _buttons->deactivate(); + + _shapes->unload(); + + if (_mainVqaPlayer) { + _mainVqaPlayer->close(); + delete _mainVqaPlayer; + _mainVqaPlayer = nullptr; + } + + if (_playerVqaPlayer) { + _playerVqaPlayer->close(); + delete _playerVqaPlayer; + _playerVqaPlayer = nullptr; + } + + _vm->closeArchive("MODE.MIX"); + + _currentSectionId = 0; + + // TODO: Unfreeze game time + + //if (!_vm->_settings->isLoadingGame(&Settings) && GameRunning) + // if (_vm->_gameIsRunning) { + // _vm->_scene->resume(false); + // } +} + +void KIA::createButtons(int sectionId) { + Common::Rect kiaButton6( 66, 00, 122, 44); + Common::Rect kiaButton7( 191, 29, 233, 70); + Common::Rect kiaButton8( 234, 29, 278, 70); + Common::Rect kiaButton9( 278, 29, 321, 70); + Common::Rect kiaButton10(322, 29, 365, 70); + Common::Rect kiaButton11(366, 29, 410, 70); + Common::Rect kiaButton12(420, 286, 472, 328); + Common::Rect kiaButton13(334, 286, 386, 328); + Common::Rect kiaButton14(411, 29, 453, 70); + Common::Rect kiaButton15(264, 9, 304, 26); + Common::Rect kiaButton16(140, 406, 160, 479); + Common::Rect kiaButton17(161, 406, 180, 479); + Common::Rect kiaButton18(181, 406, 202, 479); + Common::Rect kiaButton19(575, 307, 606, 350); + Common::Rect kiaButton21(211, 443, 291, 479); + + const Shape *shapeUp = nullptr; + const Shape *shapeHovered = nullptr; + const Shape *shapeDown = nullptr; + + switch (sectionId) { + case kKIASectionCrimes: + case kKIASectionSuspects: + case kKIASectionClues: + _buttons->defineImage(0, kiaButton6, nullptr, nullptr, _shapes->get(1), _vm->_textKIA->getText(23)); + + if (sectionId == kKIASectionCrimes) { + shapeUp = _shapes->get(2); + shapeHovered = _shapes->get(2); + shapeDown = _shapes->get(10); + } else { + shapeUp = nullptr; + shapeHovered = nullptr; + shapeDown = _shapes->get(18); + } + _buttons->defineImage(1, kiaButton7, shapeUp, shapeHovered, shapeDown, _vm->_textKIA->getText(24)); + + if (sectionId == kKIASectionSuspects) { + shapeUp = _shapes->get(3); + shapeHovered = _shapes->get(3); + shapeDown = _shapes->get(11); + } else { + shapeUp = nullptr; + shapeHovered = nullptr; + shapeDown = _shapes->get(19); + } + _buttons->defineImage(2, kiaButton8, shapeUp, shapeHovered, shapeDown, _vm->_textKIA->getText(25)); + + if (sectionId == kKIASectionClues) { + shapeUp = _shapes->get(4); + shapeHovered = _shapes->get(4); + shapeDown = _shapes->get(12); + } else { + shapeUp = nullptr; + shapeHovered = nullptr; + shapeDown = _shapes->get(20); + } + _buttons->defineImage(3, kiaButton9, shapeUp, shapeHovered, shapeDown, _vm->_textKIA->getText(26)); + + _buttons->defineImage(4, kiaButton10, nullptr, nullptr, _shapes->get(21), _vm->_textKIA->getText(27)); + + _buttons->defineImage(5, kiaButton11, nullptr, nullptr, _shapes->get(22), _vm->_textKIA->getText(28)); + + _buttons->defineImage(14, kiaButton14, nullptr, nullptr, _shapes->get(23), _vm->_textKIA->getText(29)); + + break; + case kKIASectionSettings: + case kKIASectionHelp: + case kKIASectionSave: + case kKIASectionLoad: + case kKIASectionDiagnostic: + case kKIASectionPogo: + _buttons->defineImage(6, kiaButton6, nullptr, nullptr, _shapes->get(0), _vm->_textKIA->getText(37)); + + if (sectionId == kKIASectionSettings) { + shapeUp = _shapes->get(5); + shapeHovered = _shapes->get(5); + shapeDown = _shapes->get(13); + } else { + shapeUp = nullptr; + shapeHovered = nullptr; + shapeDown = _shapes->get(24); + } + _buttons->defineImage(7, kiaButton7, shapeUp, shapeHovered, shapeDown, _vm->_textKIA->getText(38)); + + if (sectionId == kKIASectionHelp) { + shapeUp = _shapes->get(6); + shapeHovered = _shapes->get(6); + shapeDown = _shapes->get(14); + } else { + shapeUp = nullptr; + shapeHovered = nullptr; + shapeDown = _shapes->get(25); + } + _buttons->defineImage(8, kiaButton8, shapeUp, shapeHovered, shapeDown, _vm->_textKIA->getText(41)); + + if (sectionId == kKIASectionSave) { + shapeUp = _shapes->get(7); + shapeHovered = _shapes->get(7); + shapeDown = _shapes->get(15); + } else { + shapeUp = nullptr; + shapeHovered = nullptr; + shapeDown = _shapes->get(26); + } + _buttons->defineImage(9, kiaButton9, shapeUp, shapeHovered, shapeDown, _vm->_textKIA->getText(39)); + + if (sectionId == kKIASectionLoad) { + shapeUp = _shapes->get(8); + shapeHovered = _shapes->get(8); + shapeDown = _shapes->get(16); + } else { + shapeUp = nullptr; + shapeHovered = nullptr; + shapeDown = _shapes->get(27); + } + _buttons->defineImage(10, kiaButton10, shapeUp, shapeHovered, shapeDown, _vm->_textKIA->getText(40)); + + _buttons->defineImage(11, kiaButton11, nullptr, nullptr, _shapes->get(28), _vm->_textKIA->getText(42)); + + _buttons->defineImage(14, kiaButton14, nullptr, nullptr, _shapes->get(29), _vm->_textKIA->getText(29)); + + break; + case 8: + _buttons->defineImage(12, kiaButton12, _shapes->get(124), _shapes->get(124), _shapes->get(48), _vm->_textKIA->getText(42)); + + _buttons->defineImage(13, kiaButton13, _shapes->get(125), _shapes->get(125), _shapes->get(49), _vm->_textKIA->getText(29)); + break; + } + + if (sectionId != kKIASectionQuit) { + _buttons->defineImage(15, kiaButton15, nullptr, nullptr, _shapes->get(38), _vm->_textKIA->getText(43)); + + _buttons->defineImage(19, kiaButton19, nullptr, nullptr, nullptr, _vm->_textKIA->getText(44)); + + if (_vm->_settings->getAmmoAmount(0) > 0) { + _buttons->defineImage(16, kiaButton16, nullptr, nullptr, nullptr, _vm->_textKIA->getText(50)); + } + Common::String tooltip; + if (_vm->_settings->getAmmoAmount(1) > 0) { + if (_vm->_settings->getDifficulty() > 0) { + tooltip = Common::String::format("%d", _vm->_settings->getAmmoAmount(1)); + } else { + tooltip = _vm->_textKIA->getText(50); + } + _buttons->defineImage(17, kiaButton17, nullptr, nullptr, nullptr, tooltip.c_str()); + } + if (_vm->_settings->getAmmoAmount(2) > 0) { + if (_vm->_settings->getDifficulty() > 0) { + tooltip = Common::String::format("%d", _vm->_settings->getAmmoAmount(2)); + } else { + tooltip = _vm->_textKIA->getText(50); + } + _buttons->defineImage(18, kiaButton18, nullptr, nullptr, nullptr, tooltip.c_str()); + } + if (_vm->_gameFlags->query(kFlagKIAPrivacyAddon)) { + _buttons->defineImage(21, kiaButton21, nullptr, nullptr, nullptr, nullptr); + } + } +} + +void KIA::buttonClicked(int buttonId) { + int soundId = 0; + + if (!_currentSectionId) { + return; + } + switch (buttonId) { + case 0: + open(kKIASectionSettings); + break; + case 1: + if (_currentSectionId != kKIASectionCrimes) { + open(kKIASectionCrimes); + _log->next(); + _log->clearFuture(); + } + break; + case 2: + if (_currentSectionId != kKIASectionSuspects) { + open(kKIASectionSuspects); + _log->next(); + _log->clearFuture(); + } + break; + case 3: + if (_currentSectionId != kKIASectionClues) { + open(kKIASectionClues); + _log->next(); + _log->clearFuture(); + } + break; + case 4: + if (_log->hasPrev()) { + int kiaLogPrevType = _log->getPrevType(); + switch (kiaLogPrevType) { + case 2: + open(kKIASectionCrimes); + _log->prev(); + _crimesSection->loadFromLog(); + break; + case 1: + open(kKIASectionSuspects); + _log->prev(); + _suspectsSection->loadFromLog(); + break; + case 0: + open(kKIASectionClues); + _log->prev(); + _cluesSection->loadFromLog(); + break; + } + } + break; + case 5: + if (_log->hasNext()) { + int kiaLogNextType = _log->getNextType(); + switch (kiaLogNextType) { + case 2: + open(kKIASectionCrimes); + _log->next(); + _crimesSection->loadFromLog(); + break; + case 1: + open(kKIASectionSuspects); + _log->next(); + _suspectsSection->loadFromLog(); + break; + case 0: + open(kKIASectionClues); + _log->next(); + _cluesSection->loadFromLog(); + break; + } + } + break; + case 6: + if (!_forceOpen) { + open(_lastSectionIdKIA); + } + break; + case 7: + open(kKIASectionSettings); + break; + case 8: + open(kKIASectionHelp); + break; + case 9: + if (!_forceOpen) { + open(kKIASectionSave); + } + break; + case 10: + open(kKIASectionLoad); + break; + case 11: + open(kKIASectionQuit); + break; + case 12: + _vm->_gameIsRunning = false; + open(kKIASectionNone); + break; + case 13: + open(_lastSectionIdOptions); + break; + case 14: + if (!_forceOpen) { + open(kKIASectionNone); + } + break; + case 15: + open(kKIASectionDiagnostic); + break; + case 16: + _vm->_settings->setAmmoType(0); + if (_vm->_rnd.getRandomNumber(1)) { + soundId = _vm->_combat->getHitSound(); + } else { + soundId = _vm->_combat->getMissSound(); + } + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(soundId), 70, 0, 0, 50, 0); + break; + case 17: + _vm->_settings->setAmmoType(1); + if (_vm->_rnd.getRandomNumber(1)) { + soundId = _vm->_combat->getHitSound(); + } else { + soundId = _vm->_combat->getMissSound(); + } + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(soundId), 70, 0, 0, 50, 0); + break; + case 18: + _vm->_settings->setAmmoType(2); + if (_vm->_rnd.getRandomNumber(1)) { + soundId = _vm->_combat->getHitSound(); + } else { + soundId = _vm->_combat->getMissSound(); + } + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(soundId), 70, 0, 0, 50, 0); + break; + case 19: + return; + case 20: + playerReset(); + break; + case 21: + playPrivateAddon(); + break; + } +} + +void KIA::switchSection(int sectionId) { + if (_currentSection) { + _currentSection->close(); + } + switch (sectionId) { + case kKIASectionCrimes: + _currentSection = _crimesSection; + break; + case kKIASectionSuspects: + _currentSection = _suspectsSection; + break; + case kKIASectionClues: + _currentSection = _cluesSection; + break; + case kKIASectionSettings: + _currentSection = _settingsSection; + break; + case kKIASectionHelp: + _currentSection = _helpSection; + break; + case kKIASectionSave: + _currentSection = _saveSection; + break; + case kKIASectionLoad: + _currentSection = _loadSection; + break; + case kKIASectionQuit: + _currentSection = nullptr; + break; + case kKIASectionDiagnostic: + _currentSection = _diagnosticSection; + break; + case kKIASectionPogo: + _currentSection = _pogoSection; + break; + default: + _currentSection = nullptr; + break; + } + if (_currentSection) { + _currentSection->open(); + } +} + +const char *KIA::getSectionVqaName(int sectionId) { + switch (sectionId) { + case kKIASectionCrimes: + return "kia_crim.vqa"; + case kKIASectionSuspects: + return "kia_susp.vqa"; + case kKIASectionClues: + return "kia_clue.vqa"; + case kKIASectionSettings: + case kKIASectionHelp: + case kKIASectionSave: + case kKIASectionLoad: + case kKIASectionQuit: + case kKIASectionDiagnostic: + case kKIASectionPogo: + return "kia_ingm.vqa"; + default: + return nullptr; + } +} + +int KIA::getVqaLoopMain(int sectionId) { + switch (sectionId) { + case kKIASectionCrimes: + case kKIASectionSuspects: + case kKIASectionClues: + return 3; + case kKIASectionSettings: + case kKIASectionHelp: + case kKIASectionSave: + case kKIASectionLoad: + case kKIASectionDiagnostic: + case kKIASectionPogo: + return 4; + case kKIASectionQuit: + return 7; + default: + return 0; + } +} + +int KIA::getVqaLoopTransition(int transitionId) { + switch (transitionId) { + case 0: + case 2: + case 7: + case 8: + return 0; + case 1: + case 4: + case 5: + case 9: + return 1; + case 3: + case 10: + case 11: + case 12: + return 2; + case 6: + return 3; + case 13: + return 6; + default: + return 0; + } +} + +int KIA::getTransitionId(int oldSectionId, int newSectionId) { + switch (oldSectionId) { + case kKIASectionNone: + return 0; + case kKIASectionCrimes: + switch (newSectionId) { + case kKIASectionCrimes: + return 0; + case kKIASectionSuspects: + return 1; + case kKIASectionClues: + return 2; + case kKIASectionSettings: + case kKIASectionHelp: + case kKIASectionSave: + case kKIASectionLoad: + case kKIASectionDiagnostic: + case kKIASectionPogo: + return 3; + case kKIASectionQuit: + return 13; + } + return 0; + case kKIASectionSuspects: + switch (newSectionId) { + case kKIASectionCrimes: + return 4; + case kKIASectionSuspects: + return 0; + case kKIASectionClues: + return 5; + case kKIASectionSettings: + case kKIASectionHelp: + case kKIASectionSave: + case kKIASectionLoad: + case kKIASectionDiagnostic: + case kKIASectionPogo: + return 6; + case kKIASectionQuit: + return 13; + } + return 0; + case kKIASectionClues: + switch (newSectionId) { + case kKIASectionCrimes: + return 7; + case kKIASectionSuspects: + return 8; + case kKIASectionClues: + return 0; + case kKIASectionSettings: + case kKIASectionHelp: + case kKIASectionSave: + case kKIASectionLoad: + case kKIASectionDiagnostic: + case kKIASectionPogo: + return 9; + case kKIASectionQuit: + return 13; + } + return 0; + case kKIASectionSettings: + case kKIASectionHelp: + case kKIASectionSave: + case kKIASectionLoad: + case kKIASectionDiagnostic: + case kKIASectionPogo: + switch (newSectionId) { + case kKIASectionCrimes: + return 10; + case kKIASectionSuspects: + return 11; + case kKIASectionClues: + return 12; + case kKIASectionSettings: + case kKIASectionHelp: + case kKIASectionSave: + case kKIASectionLoad: + case kKIASectionDiagnostic: + case kKIASectionPogo: + return 0; + case kKIASectionQuit: + return 13; + } + return 0; + case kKIASectionQuit: + if (newSectionId != kKIASectionQuit) { + return 14; + } + } + return 0; +} + +void KIA::playTransitionSound(int transitionId) { + switch (transitionId) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(498), 100, 0, 0, 50, 0); + break; + case 13: + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(499), 100, 0, 0, 50, 0); + break; + case 14: + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(500), 100, 0, 0, 50, 0); + break; + } +} + +void KIA::playPrivateAddon() { + playerReset(); + playSliceModel(524); + playActorDialogue(14, 2060); + playActorDialogue(14, 2070); +} + +} // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/kia.h b/engines/bladerunner/ui/kia.h new file mode 100644 index 0000000000..c979f9ff8b --- /dev/null +++ b/engines/bladerunner/ui/kia.h @@ -0,0 +1,155 @@ +/* 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_KIA_H +#define BLADERUNNER_KIA_H + +#include "common/str.h" + + +namespace Common { +struct KeyState; +} + +namespace Graphics { +struct Surface; +} + +namespace BladeRunner { + +class BladeRunnerEngine; +class KIALog; +class KIAScript; +class KIASectionBase; +class KIASectionClues; +class KIASectionDiagnostic; +class KIASectionCrimes; +class KIASectionHelp; +class KIASectionLoad; +class KIASectionSettings; +class KIASectionPogo; +class KIASectionSave; +class KIASectionSuspects; +class KIAShapes; +class Shape; +class UIImagePicker; +class VQAPlayer; + +class KIA { + static const char *kPogo; + + struct ActorDialogueQueueEntry { + int actorId; + int sentenceId; + }; + + BladeRunnerEngine *_vm; + + int _forceOpen; + int _transitionId; + + int _lastSectionIdKIA; + int _lastSectionIdOptions; + + int _playerVqaTimeLast; + VQAPlayer *_playerVqaPlayer; + int _playerVqaFrame; + int _playerVisualizerState; + int _playerPhotographId; + Shape *_playerPhotograph; + int _playerSliceModelId; + float _playerSliceModelAngle; + int _timeLast; + + ActorDialogueQueueEntry *_playerActorDialogueQueue; + int _playerActorDialogueQueueCapacity; + int _playerActorDialogueQueuePosition; + int _playerActorDialogueQueueSize; + int _playerActorDialogueState; + + KIASectionBase *_currentSection; + KIASectionClues *_cluesSection; + KIASectionCrimes *_crimesSection; + KIASectionDiagnostic *_diagnosticSection; + KIASectionHelp *_helpSection; + KIASectionLoad *_loadSection; + KIASectionSettings *_settingsSection; + KIASectionPogo *_pogoSection; + KIASectionSave *_saveSection; + KIASectionSuspects *_suspectsSection; + + UIImagePicker *_buttons; + + VQAPlayer *_mainVqaPlayer; + + int _pogoPos; + +public: + int _currentSectionId; + KIALog *_log; + KIAScript *_script; + KIAShapes *_shapes; + +public: + KIA(BladeRunnerEngine *vm); + ~KIA(); + + void openLastOpened(); + void openOptions(); + + void tick(); + + void handleMouseDown(int mouseX, int mouseY, bool mainButton); + void handleMouseUp(int mouseX, int mouseY, bool mainButton); + void handleKeyUp(const Common::KeyState &kbd); + void handleKeyDown(const Common::KeyState &kbd); + + void playerReset(); + void playActorDialogue(int actorId, int sentenceId); + void playSliceModel(int sliceModelId); + void playPhotograph(int photographId); + +private: + static void mouseDownCallback(int buttonId, void *callbackData); + static void mouseUpCallback(int buttonId, void *callbackData); + static void loopEnded(void *callbackData, int frame, int loopId); + + void open(int sectionId); + void init(); + void unload(); + void switchSection(int sectionId); + + void createButtons(int sectionId); + void buttonClicked(int buttonId); + + const char *getSectionVqaName(int sectionId); + int getVqaLoopMain(int sectionId); + int getVqaLoopTransition(int transitionId); + + int getTransitionId(int oldSectionId, int newSectionId); + void playTransitionSound(int transitionId); + + void playPrivateAddon(); +}; + +} // End of namespace BladeRunner +#endif diff --git a/engines/bladerunner/ui/kia_log.cpp b/engines/bladerunner/ui/kia_log.cpp new file mode 100644 index 0000000000..51b922a8f7 --- /dev/null +++ b/engines/bladerunner/ui/kia_log.cpp @@ -0,0 +1,128 @@ +/* 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/ui/kia_log.h" + +#include "bladerunner/bladerunner.h" + +namespace BladeRunner { + +KIALog::KIALog(BladeRunnerEngine *vm) { + _vm = vm; + + _firstIndex = 0; + _lastIndex = 0; + _currentIndex = 0; + for (int i = 0; i < kSize; ++i) { + _entries[i].dataSize = 0; + _entries[i].data = nullptr; + } +} + +KIALog::~KIALog() { + clear(); +} + +void KIALog::add(int type, int dataSize, const void *data) { + if (_currentIndex == _lastIndex) { + _lastIndex = (_lastIndex + 1) % kSize; + } + + if (_entries[_currentIndex].data) { + delete[] _entries[_currentIndex].data; + } + + _entries[_currentIndex].type = type; + _entries[_currentIndex].dataSize = dataSize; + + if (dataSize > 0) { + char *dataCopy = new char[dataSize]; + memcpy(dataCopy, data, dataSize); + _entries[_currentIndex].data = dataCopy; + } else { + _entries[_currentIndex].data = nullptr; + } +} + +void KIALog::clear() { + _firstIndex = 0; + _lastIndex = 0; + _currentIndex = 0; + for (int i = 0; i < kSize; ++i) { + if (_entries[i].data) { + delete[] _entries[i].data; + } + _entries[i].dataSize = 0; + _entries[i].data = nullptr; + } +} + +void KIALog::prev() { + if (_currentIndex != _firstIndex) { + _currentIndex = (_currentIndex - 1) % kSize; + } +} + +void KIALog::next() { + if (_currentIndex != _lastIndex) { + _currentIndex = (_currentIndex + 1) % kSize; + } +} + +void KIALog::clearFuture() { + _lastIndex = _currentIndex; + int currentIndex = _currentIndex; + while (currentIndex != _firstIndex) { + if (_entries[currentIndex].data) { + delete[] _entries[currentIndex].data; + _entries[currentIndex].data = 0; + _entries[currentIndex].dataSize = 0; + } + currentIndex = (currentIndex + 1) % kSize; + } +} + +bool KIALog::hasPrev() const { + return _currentIndex != _firstIndex; +} + +bool KIALog::hasNext() const { + if (_currentIndex == _lastIndex) { + return false; + } + + return (((_currentIndex + 1) % kSize) != _lastIndex); +} + +int KIALog::getPrevType() const { + return _entries[(_currentIndex - 1) % kSize].type; +} + +int KIALog::getNextType() const { + return _entries[(_currentIndex + 1) % kSize].type; +} + +const void *KIALog::getCurrentData() const { + return _entries[_currentIndex].data; +} + +} // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/kia_log.h b/engines/bladerunner/ui/kia_log.h new file mode 100644 index 0000000000..4a89492817 --- /dev/null +++ b/engines/bladerunner/ui/kia_log.h @@ -0,0 +1,65 @@ +/* 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_KIA_LOG_H +#define BLADERUNNER_KIA_LOG_H + +namespace BladeRunner { + +class BladeRunnerEngine; + +class KIALog { + static const int kSize = 16; + + struct Entry { + int type; + int dataSize; + const char *data; + }; + + BladeRunnerEngine *_vm; + + Entry _entries[kSize]; + int _firstIndex; + int _lastIndex; + int _currentIndex; + +public: + KIALog(BladeRunnerEngine *vm); + ~KIALog(); + + void add(int type, int dataSize, const void *data); + void clear(); + + void prev(); + void next(); + void clearFuture(); + bool hasPrev() const; + bool hasNext() const; + int getPrevType() const; + int getNextType() const; + const void *getCurrentData() const; +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/ui/kia_section_base.cpp b/engines/bladerunner/ui/kia_section_base.cpp new file mode 100644 index 0000000000..96571e5a48 --- /dev/null +++ b/engines/bladerunner/ui/kia_section_base.cpp @@ -0,0 +1,35 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "bladerunner/ui/kia_section_base.h" + +namespace BladeRunner { + +KIASectionBase::KIASectionBase(BladeRunnerEngine *vm) { + _vm = vm; + _field0 = false; +} + +KIASectionBase::~KIASectionBase() { +} + +} // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/kia_section_base.h b/engines/bladerunner/ui/kia_section_base.h new file mode 100644 index 0000000000..176e30d4b7 --- /dev/null +++ b/engines/bladerunner/ui/kia_section_base.h @@ -0,0 +1,67 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BLADERUNNER_KIA_SECTION_BASE_H +#define BLADERUNNER_KIA_SECTION_BASE_H + + +namespace Common { +struct KeyState; +} + +namespace Graphics { +struct Surface; +} + +namespace BladeRunner { + +class BladeRunnerEngine; + +class KIASectionBase { +protected: + BladeRunnerEngine *_vm; + +public: + bool _field0; + + KIASectionBase(BladeRunnerEngine *vm); + virtual ~KIASectionBase(); + + virtual void open() {} + virtual void close() {} + + virtual void draw(Graphics::Surface &surface) {} + + virtual void handleKeyUp(const Common::KeyState &kbd) {} + virtual void handleKeyDown(const Common::KeyState &kbd) {} + virtual void handleMouseMove(int mouseX, int mouseY) {} + virtual void handleMouseDown(bool mainButton) {} + virtual void handleMouseUp(bool mainButton) {} + +protected: + virtual void onButtonPressed(int buttonId) {} + +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/ui/kia_section_clues.cpp b/engines/bladerunner/ui/kia_section_clues.cpp new file mode 100644 index 0000000000..1e80b57ed7 --- /dev/null +++ b/engines/bladerunner/ui/kia_section_clues.cpp @@ -0,0 +1,422 @@ +/* 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/ui/kia_section_clues.h" + +#include "bladerunner/actor_clues.h" +#include "bladerunner/audio_player.h" +#include "bladerunner/bladerunner.h" +#include "bladerunner/crimes_database.h" +#include "bladerunner/game_constants.h" +#include "bladerunner/game_flags.h" +#include "bladerunner/game_info.h" +#include "bladerunner/font.h" +#include "bladerunner/script/kia.h" +#include "bladerunner/text_resource.h" +#include "bladerunner/ui/kia.h" +#include "bladerunner/ui/kia_log.h" +#include "bladerunner/ui/kia_shapes.h" +#include "bladerunner/ui/ui_container.h" +#include "bladerunner/ui/ui_image_picker.h" +#include "bladerunner/ui/ui_scroll_box.h" + +#include "common/rect.h" + +namespace BladeRunner { + +KIASectionClues::KIASectionClues(BladeRunnerEngine *vm, ActorClues *clues) : KIASectionBase(vm) { + _uiContainer = new UIContainer(_vm); + + _isVisible = false; + + _debugIntangible = false; + _debugNop = 0; + + _clues = clues; + + _mouseX = 0; + _mouseY = 0; + + _buttons = new UIImagePicker(_vm, 2); + + _cluesScrollBox = new UIScrollBox(_vm, scrollBoxCallback, this, _vm->_gameInfo->getClueCount(), 1, false, Common::Rect(312, 172, 500, 376), Common::Rect(506, 160, 506, 394)); + _uiContainer->add(_cluesScrollBox); + + _filterScrollBox = new UIScrollBox(_vm, scrollBoxCallback, this, 128, 1, false, Common::Rect(142, 162, 291, 376), Common::Rect(120, 160, 120, 370)); + _uiContainer->add(_filterScrollBox); + + _assetTypeFilterCount = 4 + 1; // we have 4 asset types + _crimeFilterCount = _vm->_gameInfo->getCrimeCount() + 1; + _filterCount = _assetTypeFilterCount + _crimeFilterCount; + _filters.resize(_filterCount); + for (int i = 0; i < _filterCount; ++i) { + _filters[i] = true; + } +} + +KIASectionClues::~KIASectionClues() { + _uiContainer->clear(); + delete _filterScrollBox; + delete _cluesScrollBox; + delete _uiContainer; +} + +void KIASectionClues::open() { + _isVisible = true; + + _buttons->resetImages(); + _buttons->defineImage(0, Common::Rect(142, 380, 191, 395), _vm->_kia->_shapes->get(79), _vm->_kia->_shapes->get(80), _vm->_kia->_shapes->get(81), _vm->_textKIA->getText(30)); + _buttons->defineImage(1, Common::Rect(193, 380, 242, 395), _vm->_kia->_shapes->get(76), _vm->_kia->_shapes->get(77), _vm->_kia->_shapes->get(78), _vm->_textKIA->getText(31)); + + _buttons->activate(nullptr, nullptr, nullptr, mouseUpCallback, this); + _cluesScrollBox->show(); + _filterScrollBox->show(); + + populateFilters(); + populateClues(); +} + +void KIASectionClues::close() { + if (_isVisible) { + _isVisible = false; + + _buttons->deactivate(); + _cluesScrollBox->hide(); + _filterScrollBox->hide(); + } +} + +void KIASectionClues::draw(Graphics::Surface &surface) { + _uiContainer->draw(surface); + + _vm->_mainFont->drawColor(_vm->_textKIA->getText(0), surface, 300, 162, 0x77DF); + _vm->_mainFont->drawColor(_vm->_textKIA->getText(2), surface, 440, 426, 0x2991); + _vm->_mainFont->drawColor(_vm->_textKIA->getText(1), surface, 440, 442, 0x2991); + _vm->_mainFont->drawColor(_vm->_textKIA->getText(4), surface, 440, 458, 0x2991); + + int clueId = _cluesScrollBox->getSelectedLineData(); + if (clueId != -1) { + Common::String text; + + int actorId = _clues->getFromActorId(clueId); + if (actorId != -1) { + text = _vm->_textActorNames->getText(actorId); + } else { + text.clear(); + } + _vm->_mainFont->drawColor(text, surface, 490, 426, 0x46BF); + + int crimeId = _vm->_crimesDatabase->getCrime(clueId); + if (crimeId != -1) { + text = _vm->_textCrimes->getText(crimeId); + } else { + text.clear(); + } + _vm->_mainFont->drawColor(text, surface, 490, 442, 0x46BF); + + int assetType = _vm->_crimesDatabase->getAssetType(clueId); + if (assetType != -1) { + text = _vm->_textClueTypes->getText(assetType); + } else { + text.clear(); + } + _vm->_mainFont->drawColor(text, surface, 490, 458, 0x46BF); + } + + _buttons->draw(surface); + _buttons->drawTooltip(surface, _mouseX, _mouseY); + + if (_debugNop) { + _vm->_mainFont->drawColor(Common::String::format("Debug display: %s", _vm->_textActorNames->getText(_debugNop)), surface, 120, 132, 0x7FE0); + } + if (_debugIntangible) { + _vm->_mainFont->drawColor("Debug Mode: Showing intangible clues.", surface, 220, 105, 0x7FE0); + } +} + +void KIASectionClues::handleMouseMove(int mouseX, int mouseY) { + _mouseX = mouseX; + _mouseY = mouseY; + _buttons->handleMouseAction(mouseX, mouseY, false, false, false); + _uiContainer->handleMouseMove(mouseX, mouseY); +} + +void KIASectionClues::handleMouseDown(bool mainButton) { + _uiContainer->handleMouseDown(!mainButton); + if (mainButton) { + _buttons->handleMouseAction(_mouseX, _mouseY, true, false, false); + } +} + +void KIASectionClues::handleMouseUp(bool mainButton) { + _uiContainer->handleMouseUp(!mainButton); + if (mainButton) { + _buttons->handleMouseAction(_mouseX, _mouseY, false, true, false); + } +} + +void KIASectionClues::saveToLog() { + _vm->_kia->_log->add(0, sizeof(bool) * _filterCount, _filters.data()); +} + +void KIASectionClues::loadFromLog() { + memcpy(_filters.data(), _vm->_kia->_log->getCurrentData(), sizeof(bool) * _filterCount); + populateFilters(); + populateClues(); +} + +void KIASectionClues::scrollBoxCallback(void *callbackData, void *source, int lineData, int mouseButton) { + KIASectionClues *self = (KIASectionClues *)callbackData; + + if (source == self->_filterScrollBox && lineData >= 0) { + self->_filters[lineData] = !self->_filters[lineData]; + self->_filterScrollBox->toggleCheckBox(lineData); + self->populateClues(); + } else if (source == self->_cluesScrollBox && lineData >= 0) { + if (mouseButton) { + if (self->_vm->_gameFlags->query(kFlagKIAPrivacyAddon)) { + self->_vm->_audioPlayer->playAud(self->_vm->_gameInfo->getSfxTrack(511), 70, 0, 0, 50, 0); + + if (self->_clues->isPrivate(lineData)) { + self->_clues->setPrivate(lineData, false); + self->_cluesScrollBox->resetFlags(lineData, 0x08); + } else { + self->_clues->setPrivate(lineData, true); + self->_cluesScrollBox->setFlags(lineData, 0x08); + } + } + } else { + self->_clues->setViewed(lineData, true); + self->_cluesScrollBox->resetHighlight(lineData); + self->_vm->_kia->_script->playClueAssetScript(0, lineData); + } + } +} + +void KIASectionClues::mouseUpCallback(int buttonId, void *callbackData) { + KIASectionClues *self = (KIASectionClues *)callbackData; + + if (buttonId <= 1) { + self->_vm->_audioPlayer->playAud(self->_vm->_gameInfo->getSfxTrack(510), 100, 0, 0, 50, 0); + } + + self->onButtonPressed(buttonId); +} + +void KIASectionClues::onButtonPressed(int buttonId) { + if (buttonId == 1) { + disableAllFilters(); + } + if (buttonId == 0) { + enableAllFilters(); + } +} + +void KIASectionClues::enableAllFilters() { + for (int i = 0; i < _filterCount; ++i) { + if (_filterScrollBox->hasLine(i)) { + _filters[i] = true; + } + } + _filterScrollBox->checkAll(); + populateClues(); +} + +void KIASectionClues::disableAllFilters() { + for (int i = 0; i < _filterCount; ++i) { + if (_filterScrollBox->hasLine(i)) { + _filters[i] = false; + } + } + _filterScrollBox->uncheckAll(); + populateClues(); +} + +void KIASectionClues::populateFilters() { + _filterScrollBox->clearLines(); + + Common::Array<bool> availableFilters(_filterCount); + for (int i = 0; i < _filterCount; ++i) { + availableFilters[i] = false; + } + + Common::String assetTypeNames[] = { + _vm->_textKIA->getText(6), + _vm->_textKIA->getText(7), + _vm->_textKIA->getText(8), + _vm->_textKIA->getText(9) + }; + + for (int i = 0; i < kClueCount; ++i) { + if (_clues->isAcquired(i)) { + int assetType = _vm->_crimesDatabase->getAssetType(i); + int crimeId = _vm->_crimesDatabase->getCrime(i); + if (_debugIntangible || assetType != -1) { + availableFilters[getLineIdForAssetType(assetType)] = true; + availableFilters[getLineIdForCrimeId(crimeId)] = true; + } + } + } + + int assetTypeFiltersAvailable = 0; + for (int i = 0; i < _assetTypeFilterCount; ++i) { + if (availableFilters[i]) { + ++assetTypeFiltersAvailable; + } + } + + int crimeFiltersAvailable = 0; + for (int i = _assetTypeFilterCount; i < _filterCount; ++i) { + if (availableFilters[i]) { + ++crimeFiltersAvailable; + } + } + + if (assetTypeFiltersAvailable > 1) { + _filterScrollBox->addLine(_vm->_textKIA->getText(11), -1, 0x04); + + for (int i = 0; i < _assetTypeFilterCount; ++i) { + if (availableFilters[i]) { + int flags = 0x01; + if (_filters[i]) { + flags |= 0x02; + } + + Common::String text; + int typeTextId = getClueFilterTypeTextId(i); + if (typeTextId == -1) { + text = _vm->_textKIA->getText(10); + } else { + text = assetTypeNames[typeTextId]; + } + + _filterScrollBox->addLine(text, i, flags); + } + } + } + + if (crimeFiltersAvailable > 1) { + if (assetTypeFiltersAvailable > 1) { + _filterScrollBox->addLine(" ", -1, 0); + } + + _filterScrollBox->addLine(_vm->_textKIA->getText(12), -1, 0x04); + + struct Line { + Common::String crimeName; + int lineData; + int flags; + }; + + Common::Array<Line> crimeLines; + crimeLines.reserve(crimeFiltersAvailable); + + for (int i = _assetTypeFilterCount; i < _filterCount; ++i) { + if (availableFilters[i]) { + Line line; + + line.lineData = i; + + line.flags = 0x01; + if (_filters[i]) { + line.flags |= 0x02; + } + + int crimeId = getClueFilterCrimeId(i); + if (crimeId == -1) { + line.crimeName = _vm->_textKIA->getText(5); + } else { + line.crimeName = _vm->_textCrimes->getText(crimeId); + } + + crimeLines.push_back(line); + } + } + + for (int i = 0; i < crimeFiltersAvailable - 1; ++i) { + for (int j = i + 1; j < crimeFiltersAvailable; ++j) { + if (crimeLines[i].lineData != _assetTypeFilterCount) { + if (crimeLines[i].crimeName.compareToIgnoreCase(crimeLines[j].crimeName) <= 0) { + continue; + } + } + SWAP(crimeLines[i], crimeLines[j]); + } + } + + for (uint i = 0; i < crimeLines.size(); ++i) { + _filterScrollBox->addLine(crimeLines[i].crimeName, crimeLines[i].lineData, crimeLines[i].flags); + } + } +} + +void KIASectionClues::populateClues() { + _cluesScrollBox->clearLines(); + for (int i = 0; i < kClueCount; ++i) { + if (_clues->isAcquired(i)) { + int assetType = _vm->_crimesDatabase->getAssetType(i); + int crimeId = _vm->_crimesDatabase->getCrime(i); + if (assetType != -1 || _debugIntangible) { + if(_filters[getLineIdForAssetType(assetType)] && _filters[getLineIdForCrimeId(crimeId)]) { + int flags = 0x30; + if (_clues->isPrivate(i)) { + flags = 0x08; + } else if (_clues->isViewed(i)) { + flags = 0x10; + } + _cluesScrollBox->addLine(_vm->_crimesDatabase->getClueText(i), i, flags); + } + } + } + } + _cluesScrollBox->sortLines(); +} + +int KIASectionClues::getClueFilterTypeTextId(int i) { + if (i) { + return i - 1; + } + return -1; +} + +int KIASectionClues::getClueFilterCrimeId(int filterId) { + if (filterId == _assetTypeFilterCount) { + return -1; + } + return filterId - (_assetTypeFilterCount + 1); +} + +int KIASectionClues::getLineIdForAssetType(int assetType) { + if (assetType == -1) { + return 0; + } + return assetType + 1; +} + +int KIASectionClues::getLineIdForCrimeId(int crimeId) { + if (crimeId == -1) { + return _assetTypeFilterCount; + } + return _assetTypeFilterCount + crimeId + 1; +} + +} // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/kia_section_clues.h b/engines/bladerunner/ui/kia_section_clues.h new file mode 100644 index 0000000000..28d9077e6c --- /dev/null +++ b/engines/bladerunner/ui/kia_section_clues.h @@ -0,0 +1,95 @@ +/* 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_KIA_SECTION_CLUES_H +#define BLADERUNNER_KIA_SECTION_CLUES_H + +#include "bladerunner/ui/kia_section_base.h" + +#include "common/array.h" +#include "common/str.h" + +namespace BladeRunner { + +class ActorClues; +class UIContainer; +class UIImagePicker; +class UIScrollBox; + +class KIASectionClues : public KIASectionBase { + static const int kClueCount = 288; + + UIContainer *_uiContainer; + UIImagePicker *_buttons; + UIScrollBox *_cluesScrollBox; + UIScrollBox *_filterScrollBox; + + bool _isVisible; + bool _debugIntangible; + int _debugNop; + ActorClues *_clues; + + int _assetTypeFilterCount; + int _crimeFilterCount; + int _filterCount; + Common::Array<bool> _filters; + + int _mouseX; + int _mouseY; + +public: + KIASectionClues(BladeRunnerEngine *vm, ActorClues *clues); + ~KIASectionClues(); + + void open(); + void close(); + + void draw(Graphics::Surface &surface); + + void handleMouseMove(int mouseX, int mouseY); + void handleMouseDown(bool mainButton); + void handleMouseUp(bool mainButton); + + void saveToLog(); + void loadFromLog(); + +private: + static void scrollBoxCallback(void *callbackData, void *source, int lineData, int mouseButton); + static void mouseUpCallback(int buttonId, void *callbackData); + + void onButtonPressed(int buttonId); + + void enableAllFilters(); + void disableAllFilters(); + + void populateFilters(); + void populateClues(); + + int getClueFilterTypeTextId(int); + int getClueFilterCrimeId(int); + int getLineIdForAssetType(int assetType); + int getLineIdForCrimeId(int crimeId); +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/ui/kia_section_crimes.cpp b/engines/bladerunner/ui/kia_section_crimes.cpp new file mode 100644 index 0000000000..4cfaaedbad --- /dev/null +++ b/engines/bladerunner/ui/kia_section_crimes.cpp @@ -0,0 +1,37 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "bladerunner/ui/kia_section_crimes.h" + +#include "bladerunner/bladerunner.h" + +namespace BladeRunner { + +KIASectionCrimes::KIASectionCrimes(BladeRunnerEngine *vm) + : KIASectionBase(vm) + , _shape(vm) { +} + +KIASectionCrimes::~KIASectionCrimes() { +} + +} // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/kia_section_crimes.h b/engines/bladerunner/ui/kia_section_crimes.h new file mode 100644 index 0000000000..befe5e528c --- /dev/null +++ b/engines/bladerunner/ui/kia_section_crimes.h @@ -0,0 +1,82 @@ +/* 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_KIA_SECTION_CRIME_H +#define BLADERUNNER_KIA_SECTION_CRIME_H + +#include "bladerunner/shape.h" +#include "bladerunner/ui/kia_section_base.h" + +namespace BladeRunner { + +class ActorClues; +class BladeRunnerEngine; +class UIContainer; +class UIImagePicker; +class UIScrollBox; + +class KIASectionCrimes : public KIASectionBase { + struct Clue + { + int clueId; + int actorId; + }; + +protected: + + UIContainer *_uiContainer; + // void (__cdecl **scrollboxCallback)(int, UIScrollBoxStruc *, int, int); + int _isOpen; + int *_list; + UIImagePicker *_uiImagePicker; + + UIScrollBox *_cluesScrollbox; + ActorClues *_clues; + int _clueInfoCount; + Clue _clueInfo[1000]; + int _selectedCrimeId; + int _crimesFoundCount; + int *_crimeIsKnown; + int _selectedSuspectId; + int _suspectsFoundCount; + int *_suspectIsKnown; + int *_suspectHasIdentity; + int _mouseX; + int _mouseY; + int _suspectPhotoShapeId; + int _field_15; + Shape _shape; + +public: + KIASectionCrimes(BladeRunnerEngine *vm); + ~KIASectionCrimes(); + + void saveToLog() {} + void loadFromLog() {} + +protected: + +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/ui/kia_section_diagnostic.h b/engines/bladerunner/ui/kia_section_diagnostic.h new file mode 100644 index 0000000000..9a5b74b8af --- /dev/null +++ b/engines/bladerunner/ui/kia_section_diagnostic.h @@ -0,0 +1,39 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BLADERUNNER_KIA_SECTION_DIAGNOSTIC_H +#define BLADERUNNER_KIA_SECTION_DIAGNOSTIC_H + +#include "bladerunner/ui/kia_section_base.h" + +namespace BladeRunner { + +class KIASectionDiagnostic : public KIASectionBase { + +public: + KIASectionDiagnostic(BladeRunnerEngine *vm) : KIASectionBase(vm){} + +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/ui/kia_section_help.cpp b/engines/bladerunner/ui/kia_section_help.cpp new file mode 100644 index 0000000000..5065382c41 --- /dev/null +++ b/engines/bladerunner/ui/kia_section_help.cpp @@ -0,0 +1,90 @@ +/* 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/ui/kia_section_help.h" + +#include "bladerunner/bladerunner.h" +#include "bladerunner/text_resource.h" +#include "bladerunner/ui/kia.h" +#include "bladerunner/ui/kia_shapes.h" +#include "bladerunner/ui/ui_container.h" +#include "bladerunner/ui/ui_scroll_box.h" + +namespace BladeRunner { + +KIASectionHelp::KIASectionHelp(BladeRunnerEngine *vm) : KIASectionBase(vm) { + _uiContainer = new UIContainer(_vm); + _scrollBox = new UIScrollBox(_vm, nullptr, this, 1024, 0, false, Common::Rect(135, 145, 461, 385), Common::Rect(506, 160, 506, 350)); + + _uiContainer->add(_scrollBox); +} + +KIASectionHelp::~KIASectionHelp() { + _uiContainer->clear(); + delete _scrollBox; + delete _uiContainer; +} + +void KIASectionHelp::open() { + TextResource textResource(_vm); + textResource.open("HELP"); + + _scrollBox->clearLines(); + + for (int i = 0; i < textResource.getCount(); ++i) { + Common::String textLine = textResource.getText(i); + int flags = 0x04; + if (textLine.firstChar() == ' ') { + flags = 0x00; + } + _scrollBox->addLine(textLine, -1, flags); + } + + _scrollBox->show(); +} + +void KIASectionHelp::close() { + _scrollBox->hide(); +} + +void KIASectionHelp::draw(Graphics::Surface &surface){ + _vm->_kia->_shapes->get(69)->draw(surface, 501, 123); + _uiContainer->draw(surface); +} + +void KIASectionHelp::handleKeyUp(const Common::KeyState &kbd) { + _uiContainer->handleKeyUp(kbd); +} + +void KIASectionHelp::handleMouseMove(int mouseX, int mouseY) { + _uiContainer->handleMouseMove(mouseX, mouseY); +} + +void KIASectionHelp::handleMouseDown(bool mainButton) { + _uiContainer->handleMouseDown(!mainButton); +} + +void KIASectionHelp::handleMouseUp(bool mainButton) { + _uiContainer->handleMouseUp(!mainButton); +} + +} // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/kia_section_help.h b/engines/bladerunner/ui/kia_section_help.h new file mode 100644 index 0000000000..0bda5d8851 --- /dev/null +++ b/engines/bladerunner/ui/kia_section_help.h @@ -0,0 +1,54 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BLADERUNNER_KIA_SECTION_HELP_H +#define BLADERUNNER_KIA_SECTION_HELP_H + +#include "bladerunner/ui/kia_section_base.h" + +namespace BladeRunner { + +class BladeRunnerEngine; +class UIContainer; +class UIScrollBox; + +class KIASectionHelp : public KIASectionBase { + UIContainer *_uiContainer; + UIScrollBox *_scrollBox; + +public: + KIASectionHelp(BladeRunnerEngine *vm); + ~KIASectionHelp(); + + void open(); + void close(); + + void draw(Graphics::Surface &surface); + + void handleKeyUp(const Common::KeyState &kbd); + void handleMouseMove(int mouseX, int mouseY); + void handleMouseDown(bool mainButton); + void handleMouseUp(bool mainButton); +}; + +} // End of namespace BladeRunner +#endif diff --git a/engines/bladerunner/ui/kia_section_load.h b/engines/bladerunner/ui/kia_section_load.h new file mode 100644 index 0000000000..4cff04d2c4 --- /dev/null +++ b/engines/bladerunner/ui/kia_section_load.h @@ -0,0 +1,39 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BLADERUNNER_KIA_SECTION_LOAD_H +#define BLADERUNNER_KIA_SECTION_LOAD_H + +#include "bladerunner/ui/kia_section_base.h" + +namespace BladeRunner { + +class KIASectionLoad : public KIASectionBase { + +public: + KIASectionLoad(BladeRunnerEngine *vm): KIASectionBase(vm){} + +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/ui/kia_section_pogo.h b/engines/bladerunner/ui/kia_section_pogo.h new file mode 100644 index 0000000000..d2a2edd859 --- /dev/null +++ b/engines/bladerunner/ui/kia_section_pogo.h @@ -0,0 +1,39 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BLADERUNNER_KIA_SECTION_POGO_H +#define BLADERUNNER_KIA_SECTION_POGO_H + +#include "bladerunner/ui/kia_section_base.h" + +namespace BladeRunner { + +class KIASectionPogo : public KIASectionBase { + +public: + KIASectionPogo(BladeRunnerEngine *vm): KIASectionBase(vm){} + +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/ui/kia_section_save.h b/engines/bladerunner/ui/kia_section_save.h new file mode 100644 index 0000000000..5e2f5f26ac --- /dev/null +++ b/engines/bladerunner/ui/kia_section_save.h @@ -0,0 +1,39 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BLADERUNNER_KIA_SECTION_SAVE_H +#define BLADERUNNER_KIA_SECTION_SAVE_H + +#include "bladerunner/ui/kia_section_base.h" + +namespace BladeRunner { + +class KIASectionSave : public KIASectionBase { + +public: + KIASectionSave(BladeRunnerEngine *vm): KIASectionBase(vm){} + +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/ui/kia_section_settings.cpp b/engines/bladerunner/ui/kia_section_settings.cpp new file mode 100644 index 0000000000..7f2db4ae12 --- /dev/null +++ b/engines/bladerunner/ui/kia_section_settings.cpp @@ -0,0 +1,301 @@ +/* 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/ui/kia_section_settings.h" + +#include "bladerunner/audio_player.h" +#include "bladerunner/audio_speech.h" +#include "bladerunner/ambient_sounds.h" +#include "bladerunner/bladerunner.h" +#include "bladerunner/font.h" +#include "bladerunner/game_constants.h" +#include "bladerunner/game_flags.h" +#include "bladerunner/game_info.h" +#include "bladerunner/music.h" +#include "bladerunner/settings.h" +#include "bladerunner/text_resource.h" +#include "bladerunner/ui/kia.h" +#include "bladerunner/ui/kia_shapes.h" +#include "bladerunner/ui/ui_check_box.h" +#include "bladerunner/ui/ui_container.h" +#include "bladerunner/ui/ui_image_picker.h" +#include "bladerunner/ui/ui_slider.h" + +#include "common/keyboard.h" + +namespace BladeRunner { + +const char *KIASectionSettings::kLeary = "LEARY"; + +KIASectionSettings::KIASectionSettings(BladeRunnerEngine *vm) + : KIASectionBase(vm) { + + _uiContainer = new UIContainer(_vm); + _musicVolume = new UISlider(_vm, sliderCallback, this, Common::Rect(180, 160, 460, 170), 101, 0); + _soundEffectVolume = new UISlider(_vm, sliderCallback, this, Common::Rect( 180, 185, 460, 195), 101, 0); + _ambientSoundVolume = new UISlider(_vm, sliderCallback, this, Common::Rect(180, 210, 460, 220), 101, 0); + _speechVolume = new UISlider(_vm, sliderCallback, this, Common::Rect(180, 235, 460, 245), 101, 0); + _gammaCorrection = new UISlider(_vm, sliderCallback, this, Common::Rect(180, 260, 460, 270), 101, 0); + _directorsCut = new UICheckBox(_vm, checkBoxCallback, this, Common::Rect(180, 364, 460, 374), 0, false); + _playerAgendaSelector = new UIImagePicker(_vm, 5); + + _uiContainer->add(_musicVolume); + _uiContainer->add(_soundEffectVolume); + _uiContainer->add(_ambientSoundVolume); + _uiContainer->add(_speechVolume); + _uiContainer->add(_gammaCorrection); + _uiContainer->add(_directorsCut); + + _learyPos = 0; +} + +KIASectionSettings::~KIASectionSettings() { + delete _uiContainer; + delete _musicVolume; + delete _soundEffectVolume; + delete _ambientSoundVolume; + delete _speechVolume; + delete _gammaCorrection; + delete _directorsCut; + delete _playerAgendaSelector; +} + +void KIASectionSettings::open() { + _playerAgendaSelector->resetImages(); + + _playerAgendaSelector->defineImage(0, Common::Rect(180, 290, 227, 353), nullptr, nullptr, nullptr, _vm->_textOptions->getText(30)); + _playerAgendaSelector->defineImage(1, Common::Rect(238, 290, 285, 353), nullptr, nullptr, nullptr, _vm->_textOptions->getText(31)); + _playerAgendaSelector->defineImage(2, Common::Rect(296, 290, 343, 353), nullptr, nullptr, nullptr, _vm->_textOptions->getText(32)); + _playerAgendaSelector->defineImage(3, Common::Rect(354, 290, 401, 353), nullptr, nullptr, nullptr, _vm->_textOptions->getText(33)); + _playerAgendaSelector->defineImage(4, Common::Rect(412, 290, 459, 353), nullptr, nullptr, nullptr, _vm->_textOptions->getText(34)); + initConversationChoices(); + _playerAgendaSelector->activate(mouseInCallback, nullptr, nullptr, mouseUpCallback, this); + + _directorsCut->enable(); +} + +void KIASectionSettings::close() { + _playerAgendaSelector->deactivate(); +} + +void KIASectionSettings::draw(Graphics::Surface &surface) { + _musicVolume->setValue(_vm->_music->getVolume()); + _soundEffectVolume->setValue(_vm->_audioPlayer->getVolume()); + _ambientSoundVolume->setValue(_vm->_ambientSounds->getVolume()); + _speechVolume->setValue(_vm->_audioSpeech->getVolume()); + _gammaCorrection->setValue(100.0f); + _directorsCut->setChecked(_vm->_gameFlags->query(kFlagDirectorsCut)); + + const char *textConversationChoices = _vm->_textOptions->getText(0); + const char *textMusic = _vm->_textOptions->getText(2); + const char *textSoundEffects = _vm->_textOptions->getText(3); + const char *textAmbientSound = _vm->_textOptions->getText(4); + const char *textSpeech = _vm->_textOptions->getText(5); + const char *textGammaCorrection = _vm->_textOptions->getText(7); + const char *textSoft = _vm->_textOptions->getText(10); + const char *textLoud = _vm->_textOptions->getText(11); + const char *textDark = _vm->_textOptions->getText(14); + const char *textLight = _vm->_textOptions->getText(15); + const char *textDesignersCut = _vm->_textOptions->getText(18); + + int posConversationChoices = 320 - _vm->_mainFont->getTextWidth(textConversationChoices) / 2; + int posMusic = 320 - _vm->_mainFont->getTextWidth(textMusic) / 2; + int posSoundEffects = 320 - _vm->_mainFont->getTextWidth(textSoundEffects) / 2; + int posAmbientSound = 320 - _vm->_mainFont->getTextWidth(textAmbientSound) / 2; + int posSpeech = 320 - _vm->_mainFont->getTextWidth(textSpeech) / 2; + int posGammaCorrection = 320 - _vm->_mainFont->getTextWidth(textGammaCorrection) / 2; + int posSoft = 178 - _vm->_mainFont->getTextWidth(textSoft); + int posDark = 178 - _vm->_mainFont->getTextWidth(textDark); + + _uiContainer->draw(surface); + _playerAgendaSelector->draw(surface); + + _vm->_mainFont->drawColor(textConversationChoices, surface, posConversationChoices, 280, 0x7751); + + _vm->_mainFont->drawColor(textMusic, surface, posMusic, 150, 0x7751); + _vm->_mainFont->drawColor(textSoft, surface, posSoft, 161, 0x6EEE); + _vm->_mainFont->drawColor(textLoud, surface, 462, 161, 0x6EEE); + + _vm->_mainFont->drawColor(textSoundEffects, surface, posSoundEffects, 175, 0x7751); + _vm->_mainFont->drawColor(textSoft, surface, posSoft, 186, 0x6EEE); + _vm->_mainFont->drawColor(textLoud, surface, 462, 186, 0x6EEE); + + _vm->_mainFont->drawColor(textAmbientSound, surface, posAmbientSound, 200, 0x7751); + _vm->_mainFont->drawColor(textSoft, surface, posSoft, 211, 0x6EEE); + _vm->_mainFont->drawColor(textLoud, surface, 462, 211, 0x6EEE); + + _vm->_mainFont->drawColor(textSpeech, surface, posSpeech, 225, 0x7751); + _vm->_mainFont->drawColor(textSoft, surface, posSoft, 236, 0x6EEE); + _vm->_mainFont->drawColor(textLoud, surface, 462, 236, 0x6EEE); + + _vm->_mainFont->drawColor(textGammaCorrection, surface, posGammaCorrection, 250, 0x7751); + _vm->_mainFont->drawColor(textDark, surface, posDark, 261, 0x6EEE); + _vm->_mainFont->drawColor(textLight, surface, 462, 261, 0x6EEE); + + _vm->_mainFont->drawColor(textDesignersCut, surface, 192, 365, 0x7751); + + _playerAgendaSelector->drawTooltip(surface, _mouseX, _mouseY); +} + +void KIASectionSettings::handleKeyUp(const Common::KeyState &kbd) { + if (toupper(kbd.ascii) != kLeary[_learyPos]) { + _learyPos = 0; + } + + if (toupper(kbd.ascii) == kLeary[_learyPos]) { + ++_learyPos; + if (!kLeary[_learyPos]) { + _vm->_settings->setLearyMode(!_vm->_settings->getLearyMode()); + _learyPos = 0; + initConversationChoices(); + } + } +} + +void KIASectionSettings::handleMouseMove(int mouseX, int mouseY) { + _uiContainer->handleMouseMove(mouseX, mouseY); + _mouseX = mouseX; + _mouseY = mouseY; + _playerAgendaSelector->handleMouseAction(mouseX, mouseY, false, false, false); +} + +void KIASectionSettings::handleMouseDown(bool mainButton) { + if (mainButton) { + _uiContainer->handleMouseDown(false); + _playerAgendaSelector->handleMouseAction(_mouseX, _mouseY, true, false, false); + } +} + +void KIASectionSettings::handleMouseUp(bool mainButton) { + if (mainButton) { + _uiContainer->handleMouseUp(false); + _playerAgendaSelector->handleMouseAction(_mouseX, _mouseY, false, true, false); + } +} + +void KIASectionSettings::sliderCallback(void *callbackData, void *source) { + KIASectionSettings *self = (KIASectionSettings *)callbackData; + + if (source == self->_musicVolume) { + self->_vm->_music->setVolume(self->_musicVolume->_value); + self->_vm->_music->playSample(); + } else if (source == self->_soundEffectVolume) { + self->_vm->_audioPlayer->setVolume(self->_soundEffectVolume->_value); + self->_vm->_audioPlayer->playSample(); + } else if (source == self->_ambientSoundVolume) { + self->_vm->_ambientSounds->setVolume(self->_ambientSoundVolume->_value); + self->_vm->_ambientSounds->playSample(); + } else if (source == self->_speechVolume) { + self->_vm->_audioSpeech->setVolume(self->_speechVolume->_value); + self->_vm->_audioSpeech->playSample(); + } else if (source == self->_gammaCorrection) { + // TODO: gamma, should we support it? + // gamma = self->_gammaCorrection._value / 100.0f; + // settings::setGamma(&Settings, gamma); + // colorFormat = DirectDrawSurfaces_get_colorFormat(); + // Palette_fill(colorFormat); + // Palette_copy(Palette); + // kia::resume(KIA); + } +} + +void KIASectionSettings::checkBoxCallback(void *callbackData, void *source) { + KIASectionSettings *self = (KIASectionSettings *)callbackData; + if (source == self->_directorsCut) { + if (self->_directorsCut->_isChecked) { + self->_vm->_gameFlags->set(kFlagDirectorsCut); + } else { + self->_vm->_gameFlags->reset(kFlagDirectorsCut); + } + } +} + +void KIASectionSettings::mouseInCallback(int buttonId, void *callbackData) { + KIASectionSettings *self = (KIASectionSettings *)callbackData; + self->_vm->_audioPlayer->playAud(self->_vm->_gameInfo->getSfxTrack(508), 100, 0, 0, 50, 0); +} + +void KIASectionSettings::mouseUpCallback(int buttonId, void *callbackData) { + KIASectionSettings *self = (KIASectionSettings *)callbackData; + self->onButtonPressed(buttonId); +} + +void KIASectionSettings::onButtonPressed(int buttonId) { + switch (buttonId) { + case 0: + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(513), 90, -30, -30, 50, 0); + _vm->_settings->setPlayerAgenda(0); + initConversationChoices(); + break; + case 1: + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(513), 90, -15, -15, 50, 0); + _vm->_settings->setPlayerAgenda(1); + initConversationChoices(); + break; + case 2: + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(513), 90, 0, 0, 50, 0); + _vm->_settings->setPlayerAgenda(2); + initConversationChoices(); + break; + case 3: + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(513), 90, 15, 15, 50, 0); + _vm->_settings->setPlayerAgenda(3); + initConversationChoices(); + break; + case 4: + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(513), 90, 30, 30, 50, 0); + _vm->_settings->setPlayerAgenda(4); + initConversationChoices(); + break; + default: + return; + } +} + +void KIASectionSettings::initConversationChoices() { + for (int i = 0; i < 5; ++i) { + const Shape *shape = nullptr; + if (_vm->_settings->getPlayerAgenda() == i) { + if (i == 4) { + shape = _vm->_kia->_shapes->get(122); + } else if (_vm->_settings->getLearyMode()) { + shape = _vm->_kia->_shapes->get(106 + i); + } else { + shape = _vm->_kia->_shapes->get(114 + i); + } + } else { + if (i == 4) { + shape = _vm->_kia->_shapes->get(123); + } else if (_vm->_settings->getLearyMode()) { + shape = _vm->_kia->_shapes->get(110 + i); + } else { + shape = _vm->_kia->_shapes->get(118 + i); + } + } + + _playerAgendaSelector->setImageShapeUp(i, shape); + _playerAgendaSelector->setImageShapeHovered(i, shape); + _playerAgendaSelector->setImageShapeDown(i, shape); + } +} + +} // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/kia_section_settings.h b/engines/bladerunner/ui/kia_section_settings.h new file mode 100644 index 0000000000..49356266b7 --- /dev/null +++ b/engines/bladerunner/ui/kia_section_settings.h @@ -0,0 +1,80 @@ +/* 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_KIA_SECTION_SETTINGS_H +#define BLADERUNNER_KIA_SECTION_SETTINGS_H + +#include "bladerunner/ui/kia_section_base.h" + +namespace BladeRunner { + +class BladeRunnerEngine; +class UIContainer; +class UICheckBox; +class UIImagePicker; +class UISlider; + +class KIASectionSettings : public KIASectionBase { + static const char *kLeary; + + UIContainer *_uiContainer; + UISlider *_musicVolume; + UISlider *_soundEffectVolume; + UISlider *_ambientSoundVolume; + UISlider *_speechVolume; + UISlider *_gammaCorrection; + UICheckBox *_directorsCut; + UIImagePicker *_playerAgendaSelector; + + int _mouseX; + int _mouseY; + + int _learyPos; + +public: + KIASectionSettings(BladeRunnerEngine *vm); + ~KIASectionSettings(); + + void open(); + void close(); + + void draw(Graphics::Surface &surface); + + void handleKeyUp(const Common::KeyState &kbd); + void handleMouseMove(int mouseX, int mouseY); + void handleMouseDown(bool mainButton); + void handleMouseUp(bool mainButton); + +private: + static void sliderCallback(void *callbackData, void *source); + static void checkBoxCallback(void *callbackData, void *source); + static void mouseInCallback(int buttonId, void *callbackData); + static void mouseUpCallback(int buttonId, void *callbackData); + + void onButtonPressed(int buttonId); + + void initConversationChoices(); +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/ui/kia_section_suspects.h b/engines/bladerunner/ui/kia_section_suspects.h new file mode 100644 index 0000000000..94cf1bfc06 --- /dev/null +++ b/engines/bladerunner/ui/kia_section_suspects.h @@ -0,0 +1,41 @@ +/* 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_KIA_SECTION_SUSPECTS_H +#define BLADERUNNER_KIA_SECTION_SUSPECTS_H + +#include "bladerunner/ui/kia_section_base.h" + +namespace BladeRunner { + +class KIASectionSuspects : public KIASectionBase { + +public: + KIASectionSuspects(BladeRunnerEngine *vm): KIASectionBase(vm) {} + + void saveToLog() {} + void loadFromLog() {} +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/ui/kia_shapes.cpp b/engines/bladerunner/ui/kia_shapes.cpp new file mode 100644 index 0000000000..6835216e26 --- /dev/null +++ b/engines/bladerunner/ui/kia_shapes.cpp @@ -0,0 +1,69 @@ +/* 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/ui/kia_shapes.h" + +#include "bladerunner/bladerunner.h" + +namespace BladeRunner { + +KIAShapes::KIAShapes(BladeRunnerEngine *vm) { + _vm = vm; + _isLoaded = false; +} + +KIAShapes::~KIAShapes() { + unload(); +} + +void KIAShapes::load() { + if (_isLoaded) { + return; + } + + for (uint i = 0; i < kShapeCount; ++i) { + Shape *shape = new Shape(_vm); + shape->readFromContainer("kiaopt.shp", i); + _shapes[i] = shape; + } + + _isLoaded = true; +} + +void KIAShapes::unload() { + if (!_isLoaded) { + return; + } + + for (uint i = 0; i < kShapeCount; ++i) { + delete _shapes[i]; + _shapes[i] = nullptr; + } + + _isLoaded = false; +} + +const Shape *KIAShapes::get(int shapeId) const { + return _shapes[shapeId]; +} + +} // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/kia_shapes.h b/engines/bladerunner/ui/kia_shapes.h new file mode 100644 index 0000000000..e075547542 --- /dev/null +++ b/engines/bladerunner/ui/kia_shapes.h @@ -0,0 +1,54 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BLADERUNNER_UI_SHAPES_H +#define BLADERUNNER_UI_SHAPES_H + +#include "bladerunner/shape.h" + +#include "common/array.h" + +namespace BladeRunner { + +class BladeRunnerEngine; + +class KIAShapes +{ +private: + static const int kShapeCount = 132; + + BladeRunnerEngine *_vm; + const Shape *_shapes[kShapeCount]; + bool _isLoaded; + +public: + KIAShapes(BladeRunnerEngine *vm); + ~KIAShapes(); + + void load(); + void unload(); + const Shape *get(int shapeId) const; +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/spinner.cpp b/engines/bladerunner/ui/spinner.cpp index 6b8cb34ff6..9018de15e6 100644 --- a/engines/bladerunner/spinner.cpp +++ b/engines/bladerunner/ui/spinner.cpp @@ -20,23 +20,23 @@ * */ -#include "bladerunner/spinner.h" +#include "bladerunner/ui/spinner.h" #include "bladerunner/bladerunner.h" - +#include "bladerunner/mouse.h" #include "bladerunner/scene.h" #include "bladerunner/shape.h" -#include "bladerunner/mouse.h" -#include "bladerunner/vqa_player.h" #include "bladerunner/text_resource.h" -#include "bladerunner/ui_image_picker.h" +#include "bladerunner/vqa_player.h" +#include "bladerunner/ui/ui_image_picker.h" #include "common/rect.h" #include "common/system.h" namespace BladeRunner { -Spinner::Spinner(BladeRunnerEngine *vm) : _vm(vm) { +Spinner::Spinner(BladeRunnerEngine *vm) { + _vm = vm; reset(); _imagePicker = new UIImagePicker(vm, kSpinnerDestinations); _vqaPlayer = nullptr; @@ -61,17 +61,16 @@ bool Spinner::querySelectableDestinationFlag(int destination) const { return _isDestinationSelectable[destination]; } -SpinnerDestination SpinnerDestinationsNear[] = { +const Spinner::Destination Spinner::kSpinnerDestinationsNear[] = { { 0, Common::Rect(210, 263, 263, 332) }, { 1, Common::Rect(307, 330, 361, 381) }, { 2, Common::Rect(338, 137, 362, 169) }, { 3, Common::Rect(248, 135, 289, 168) }, { 4, Common::Rect(352, 222, 379, 238) }, { -1, Common::Rect(-1,-1,-1,-1) } - }; -SpinnerDestination SpinnerDestinationsMedium[] = { +const Spinner::Destination Spinner::kSpinnerDestinationsMedium[] = { { 0, Common::Rect(252, 242, 279, 283) }, { 1, Common::Rect(301, 273, 328, 304) }, { 2, Common::Rect(319, 182, 336, 200) }, @@ -83,7 +82,7 @@ SpinnerDestination SpinnerDestinationsMedium[] = { { -1, Common::Rect(-1,-1,-1,-1) } }; -SpinnerDestination SpinnerDestinationsFar[] = { +const Spinner::Destination Spinner::kSpinnerDestinationsFar[] = { { 0, Common::Rect(220, 227, 246, 262) }, { 1, Common::Rect(260, 252, 286, 279) }, { 2, Common::Rect(286, 178, 302, 196) }, @@ -97,11 +96,6 @@ SpinnerDestination SpinnerDestinationsFar[] = { { -1, Common::Rect(-1, -1, -1, -1) } }; -static void spinner_mouseInCallback(int, void*); -static void spinner_mouseOutCallback(int, void*); -static void spinner_mouseDownCallback(int, void*); -static void spinner_mouseUpCallback(int, void*); - int Spinner::chooseDestination(int loopId, bool immediately) { _selectedDestination = 0; if (!_vm->openArchive("MODE.MIX")) { @@ -119,7 +113,7 @@ int Spinner::chooseDestination(int loopId, bool immediately) { _vm->playerGainsControl(); } - _vqaPlayer = new VQAPlayer(_vm, &_vm->_surfaceInterface); + _vqaPlayer = new VQAPlayer(_vm, &_vm->_surfaceBack); if (!_vqaPlayer->open("SPINNER.VQA")) { return 0; } @@ -143,17 +137,17 @@ int Spinner::chooseDestination(int loopId, bool immediately) { mapmask = 1; if (mapmask & 4) { - _destinations = SpinnerDestinationsFar; + _destinations = kSpinnerDestinationsFar; firstShapeId = 26; shapeCount = 20; spinnerLoopId = 4; } else if (mapmask & 2) { - _destinations = SpinnerDestinationsMedium; + _destinations = kSpinnerDestinationsMedium; firstShapeId = 10; shapeCount = 16; spinnerLoopId = 2; } else if (mapmask & 1) { - _destinations = SpinnerDestinationsNear; + _destinations = kSpinnerDestinationsNear; firstShapeId = 0; shapeCount = 10; spinnerLoopId = 0; @@ -171,7 +165,7 @@ int Spinner::chooseDestination(int loopId, bool immediately) { _imagePicker->resetImages(); - for (SpinnerDestination *dest = _destinations; dest->id != -1; ++dest) { + for (const Destination *dest = _destinations; dest->id != -1; ++dest) { if (!_isDestinationSelectable[dest->id]) { continue; } @@ -189,10 +183,10 @@ int Spinner::chooseDestination(int loopId, bool immediately) { } _imagePicker->activate( - spinner_mouseInCallback, - spinner_mouseOutCallback, - spinner_mouseDownCallback, - spinner_mouseUpCallback, + nullptr, + nullptr, + nullptr, + mouseUpCallback, this ); @@ -225,16 +219,7 @@ int Spinner::chooseDestination(int loopId, bool immediately) { return _selectedDestination; } -static void spinner_mouseInCallback(int, void*) { -} - -static void spinner_mouseOutCallback(int, void*) { -} - -static void spinner_mouseDownCallback(int, void*) { -} - -static void spinner_mouseUpCallback(int image, void *self) { +void Spinner::mouseUpCallback(int image, void *self) { if (image >= 0 && image < 10) { ((Spinner *)self)->setSelectedDestination(image); } @@ -266,8 +251,8 @@ void Spinner::tick() { int frame = _vqaPlayer->update(); assert(frame >= -1); - // vqaPlayer renders to _surfaceInterface - blit(_vm->_surfaceInterface, _vm->_surfaceGame); + // vqaPlayer renders to _surfaceBack + blit(_vm->_surfaceBack, _vm->_surfaceFront); Common::Point p = _vm->getMousePos(); _imagePicker->handleMouseAction(p.x, p.y, false, false, false); @@ -276,11 +261,11 @@ void Spinner::tick() { } else { _vm->_mouse->setCursor(0); } - _imagePicker->draw(_vm->_surfaceGame); - _vm->_mouse->draw(_vm->_surfaceGame, p.x, p.y); - _imagePicker->drawTooltip(_vm->_surfaceGame, p.x, p.y); + _imagePicker->draw(_vm->_surfaceFront); + _vm->_mouse->draw(_vm->_surfaceFront, p.x, p.y); + _imagePicker->drawTooltip(_vm->_surfaceFront, p.x, p.y); - _vm->blitToScreen(_vm->_surfaceGame); + _vm->blitToScreen(_vm->_surfaceFront); _vm->_system->delayMillis(10); } diff --git a/engines/bladerunner/spinner.h b/engines/bladerunner/ui/spinner.h index cfa593b1fb..ec0f8dbe33 100644 --- a/engines/bladerunner/spinner.h +++ b/engines/bladerunner/ui/spinner.h @@ -33,22 +33,27 @@ class Shape; class VQAPlayer; class UIImagePicker; -struct SpinnerDestination { - int id; - Common::Rect rect; -}; class Spinner { static const int kSpinnerDestinations = 10; - BladeRunnerEngine *_vm; - bool _isDestinationSelectable[kSpinnerDestinations]; - bool _isOpen; - VQAPlayer *_vqaPlayer; - SpinnerDestination *_destinations; - int _selectedDestination; - Common::Array<Shape*> _shapes; - UIImagePicker *_imagePicker; + struct Destination { + int id; + Common::Rect rect; + }; + + static const Destination kSpinnerDestinationsNear[]; + static const Destination kSpinnerDestinationsMedium[]; + static const Destination kSpinnerDestinationsFar[]; + + BladeRunnerEngine *_vm; + bool _isDestinationSelectable[kSpinnerDestinations]; + bool _isOpen; + VQAPlayer *_vqaPlayer; + const Destination *_destinations; + int _selectedDestination; + Common::Array<Shape *> _shapes; + UIImagePicker *_imagePicker; public: Spinner(BladeRunnerEngine *vm); @@ -64,10 +69,14 @@ public: int handleMouseUp(int x, int y); int handleMouseDown(int x, int y); + void tick(); void setSelectedDestination(int destination); void reset(); void resume(); + +private: + static void mouseUpCallback(int, void *); }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/ui_check_box.cpp b/engines/bladerunner/ui/ui_check_box.cpp new file mode 100644 index 0000000000..39e120e883 --- /dev/null +++ b/engines/bladerunner/ui/ui_check_box.cpp @@ -0,0 +1,140 @@ +/* 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/ui/ui_check_box.h" + +#include "bladerunner/audio_player.h" +#include "bladerunner/bladerunner.h" +#include "bladerunner/game_info.h" +#include "bladerunner/ui/kia.h" +#include "bladerunner/ui/kia_shapes.h" + +namespace BladeRunner { + +UICheckBox::UICheckBox(BladeRunnerEngine *vm, UIComponentCallback *valueChangedCallback, void *callbackData, Common::Rect rect, int style, bool isChecked) + : UIComponent(vm) { + + _valueChangedCallback = valueChangedCallback; + _callbackData = callbackData; + + _isEnabled = true; + _hasFocus = false; + _isPressed = false; + _style = style; + + if (isChecked) { + _frame = 5; + } else { + _frame = 0; + } + + _timeLast = _vm->getTotalPlayTime(); + _rect = rect; + _isChecked = isChecked; +} + + +void UICheckBox::draw(Graphics::Surface &surface) { + int shapeId; + if (_rect.right > _rect.left && _rect.bottom > _rect.top) { + uint timeNow = _vm->getTotalPlayTime(); + if (timeNow - _timeLast > 67) { + int frameDelta = (timeNow - _timeLast) / 67u; + _timeLast = timeNow; + + if (_isChecked) { + _frame = MIN(_frame + frameDelta, 5); + } else { + _frame = MAX(_frame - frameDelta, 0); + } + } + + if (_style) { + if (_frame || (_hasFocus && !_isPressed && _isEnabled)) { + if (_frame != 5 || (_hasFocus && !_isPressed && _isEnabled)) { + shapeId = _frame + 54; + } else { + shapeId = 53; + } + } else { + shapeId = 52; + } + } else { + if (_frame || (_hasFocus && !_isPressed && _isEnabled)) { + if (_frame != 5 || (_hasFocus && !_isPressed && _isEnabled)) { + shapeId = _frame + 62; + } else { + shapeId = 61; + } + } else { + shapeId = 60; + } + } + + _vm->_kia->_shapes->get(shapeId)->draw(surface, _rect.left, _rect.top + 1); + } +} + +void UICheckBox::enable() { + _isEnabled = true; + _isPressed = false; + _hasFocus = false; +} + +void UICheckBox::disable() { + _isEnabled = false; +} + +void UICheckBox::setChecked(bool isChecked) { + _isChecked = isChecked; +} + +void UICheckBox::handleMouseMove(int mouseX, int mouseY) { + if (_rect.contains(mouseX, mouseY)) { + if (!_hasFocus && _isEnabled && !_isPressed ) { + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(508), 100, 0, 0, 50, 0); + } + _hasFocus = true; + } else { + _hasFocus = false; + } +} + +void UICheckBox::handleMouseDown(bool alternateButton) { + if (!alternateButton) { + if (_isEnabled && _hasFocus) { + _isChecked = !_isChecked; + if (_valueChangedCallback) { + _valueChangedCallback(_callbackData, this); + } + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(509), 100, 0, 0, 50, 0); + } else { + _isPressed = true; + } + } +} + +void UICheckBox::handleMouseUp(bool alternateButton) { + _isPressed = false; +} + +} // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/ui_check_box.h b/engines/bladerunner/ui/ui_check_box.h new file mode 100644 index 0000000000..cfd584b09e --- /dev/null +++ b/engines/bladerunner/ui/ui_check_box.h @@ -0,0 +1,64 @@ +/* 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_UI_CHECKBOX_H +#define BLADERUNNER_UI_CHECKBOX_H + +#include "bladerunner/ui/ui_component.h" + +#include "common/rect.h" + +namespace BladeRunner { + +class UICheckBox : public UIComponent +{ +private: + UIComponentCallback *_valueChangedCallback; + void *_callbackData; + + int _style; + int _isEnabled; + Common::Rect _rect; + int _frame; + int _isPressed; + uint _timeLast; + int _hasFocus; + +public: + bool _isChecked; + + UICheckBox(BladeRunnerEngine *vm, UIComponentCallback *valueChangedCallback, void *callbackData, Common::Rect rect, int style, bool isChecked); + + void draw(Graphics::Surface &surface); + + void enable(); + void disable(); + void setChecked(bool isChecked); + + void handleMouseMove(int mouseX, int mouseY); + void handleMouseDown(bool alternateButton); + void handleMouseUp(bool alternateButton); +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/ui/ui_component.h b/engines/bladerunner/ui/ui_component.h new file mode 100644 index 0000000000..9c290d9dcb --- /dev/null +++ b/engines/bladerunner/ui/ui_component.h @@ -0,0 +1,62 @@ +/* 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_UI_COMPONENT_H +#define BLADERUNNER_UI_COMPONENT_H + +namespace Common{ +struct KeyState; +} + +namespace Graphics { +struct Surface; +} + +namespace BladeRunner { + +class BladeRunnerEngine; + +typedef void UIComponentCallback(void *callbackData, void *source); + +class UIComponent +{ +protected: + BladeRunnerEngine *_vm; + +public: + UIComponent(BladeRunnerEngine *vm) { + _vm = vm; + } + + virtual ~UIComponent() {} + + virtual void draw(Graphics::Surface &surface) {} + + virtual void handleMouseMove(int mouseX, int mouseY) {} + virtual void handleMouseDown(bool alternateButton) {} + virtual void handleMouseUp(bool alternateButton) {} + virtual void handleKeyUp(const Common::KeyState &kbd) {} +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/ui/ui_container.cpp b/engines/bladerunner/ui/ui_container.cpp new file mode 100644 index 0000000000..78097a9d3d --- /dev/null +++ b/engines/bladerunner/ui/ui_container.cpp @@ -0,0 +1,67 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "bladerunner/ui/ui_container.h" + +#include "common/keyboard.h" + +namespace BladeRunner { + +void UIContainer::draw(Graphics::Surface &surface) { +for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); component++) { + (*component)->draw(surface); + } +} + +void UIContainer::handleMouseMove(int mouseX, int mouseY) { + for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); component++) { + (*component)->handleMouseMove(mouseX, mouseY); + } +} + +void UIContainer::handleMouseDown(bool alternateButton) { +for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); component++) { + (*component)->handleMouseDown(alternateButton); + } +} + +void UIContainer::handleMouseUp(bool alternateButton) { +for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); component++) { + (*component)->handleMouseUp(alternateButton); + } +} + +void UIContainer::handleKeyUp(const Common::KeyState &kbd) { +for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); component++) { + (*component)->handleKeyUp(kbd); + } +} + +void UIContainer::add(UIComponent *component) { + _components.push_back(component); +} + +void UIContainer::clear() { + _components.clear(); +} + +} // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/ui_container.h b/engines/bladerunner/ui/ui_container.h new file mode 100644 index 0000000000..9d5bded960 --- /dev/null +++ b/engines/bladerunner/ui/ui_container.h @@ -0,0 +1,56 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BLADERUNNER_UI_CONTAINER_H +#define BLADERUNNER_UI_CONTAINER_H + +#include "bladerunner/ui/ui_component.h" + +#include "common/array.h" + +namespace BladeRunner { + +class UIComponent; + +class UIContainer : public UIComponent +{ +private: + Common::Array<UIComponent*> _components; + +public: + UIContainer(BladeRunnerEngine *vm) : UIComponent(vm) {} + + void draw(Graphics::Surface &surface); + + void handleMouseMove(int mouseX, int mouseY); + void handleMouseDown(bool alternateButton); + void handleMouseUp(bool alternateButton); + void handleKeyUp(const Common::KeyState &kbd); + + void add(UIComponent *component); + void clear(); +}; + + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/ui_image_picker.cpp b/engines/bladerunner/ui/ui_image_picker.cpp index eb0b57505c..997ff7bc5e 100644 --- a/engines/bladerunner/ui_image_picker.cpp +++ b/engines/bladerunner/ui/ui_image_picker.cpp @@ -20,7 +20,7 @@ * */ -#include "bladerunner/ui_image_picker.h" +#include "bladerunner/ui/ui_image_picker.h" #include "bladerunner/bladerunner.h" #include "bladerunner/font.h" @@ -33,7 +33,8 @@ namespace BladeRunner { -UIImagePicker::UIImagePicker(BladeRunnerEngine *vm, int imageCount) : _vm(vm) { +UIImagePicker::UIImagePicker(BladeRunnerEngine *vm, int imageCount) { + _vm = vm; reset(); _images.resize(imageCount); _imageCount = imageCount; @@ -51,12 +52,12 @@ void UIImagePicker::resetImages() { } } -bool UIImagePicker::defineImage(int i, Common::Rect rect, Shape *shapeUp, Shape *shapeHovered, Shape *shapeDown, const char *tooltip) { +bool UIImagePicker::defineImage(int i, Common::Rect rect, const Shape *shapeUp, const Shape *shapeHovered, const Shape *shapeDown, const char *tooltip) { if (i < 0 || i >= _imageCount || _images[i].active) { return false; } - UIImagePickerImage &img = _images[i]; + Image &img = _images[i]; img.rect = rect; // for rect to be inclusive @@ -81,7 +82,7 @@ bool UIImagePicker::setImageTop(int i, int top) { return false; } - UIImagePickerImage &img = _images[i]; + Image &img = _images[i]; img.rect.moveTo(img.rect.left, top); @@ -93,14 +94,14 @@ bool UIImagePicker::setImageLeft(int i, int left) { return false; } - UIImagePickerImage &img = _images[i]; + Image &img = _images[i]; img.rect.moveTo(left, img.rect.top); return true; } -bool UIImagePicker::setImageShapeUp(int i, Shape *shapeUp) { +bool UIImagePicker::setImageShapeUp(int i, const Shape *shapeUp) { if (i < 0 || i >= _imageCount || !_images[i].active) { return false; } @@ -110,7 +111,7 @@ bool UIImagePicker::setImageShapeUp(int i, Shape *shapeUp) { return true; } -bool UIImagePicker::setImageShapeHovered(int i, Shape *shapeHovered) { +bool UIImagePicker::setImageShapeHovered(int i, const Shape *shapeHovered) { if (i < 0 || i >= _imageCount || !_images[i].active) { return false; } @@ -120,7 +121,7 @@ bool UIImagePicker::setImageShapeHovered(int i, Shape *shapeHovered) { return true; } -bool UIImagePicker::setImageShapeDown(int i, Shape *shapeDown) { +bool UIImagePicker::setImageShapeDown(int i, const Shape *shapeDown) { if (i < 0 || i >= _imageCount || !_images[i].active) { return false; } @@ -186,7 +187,7 @@ void UIImagePicker::draw(Graphics::Surface &surface) { } for (int i = 0; i != _imageCount; ++i) { - UIImagePickerImage &img = _images[i]; + Image &img = _images[i]; if (!img.active) { continue; } @@ -205,6 +206,9 @@ void UIImagePicker::draw(Graphics::Surface &surface) { img.shapeUp->draw(surface, img.rect.left, img.rect.top); } } +#if BLADERUNNER_DEBUG_RENDERING + surface.frameRect(img.rect, 0x7fff); +#endif } } @@ -305,7 +309,7 @@ void UIImagePicker::handleMouseAction(int x, int y, bool down, bool up, bool ign void UIImagePicker::resetImage(int i) { assert(i >= 0 && i < _imageCount); - UIImagePickerImage &img = _images[i]; + Image &img = _images[i]; img.active = false; img.rect.left = -1; diff --git a/engines/bladerunner/ui_image_picker.h b/engines/bladerunner/ui/ui_image_picker.h index c06b556c14..00f2f3dfd9 100644 --- a/engines/bladerunner/ui_image_picker.h +++ b/engines/bladerunner/ui/ui_image_picker.h @@ -36,18 +36,18 @@ namespace BladeRunner { class BladeRunnerEngine; class Shape; -typedef void UIImagePickerCallback(int, void*); - -struct UIImagePickerImage { - int active; - Common::Rect rect; - Shape *shapeUp; - Shape *shapeHovered; - Shape *shapeDown; - Common::String tooltip; -}; +typedef void UIImagePickerCallback(int, void *); class UIImagePicker { + struct Image { + int active; + Common::Rect rect; + const Shape *shapeUp; + const Shape *shapeHovered; + const Shape *shapeDown; + Common::String tooltip; + }; + BladeRunnerEngine *_vm; int _isVisible; @@ -56,7 +56,7 @@ class UIImagePicker { int _pressedImageIndex; uint32 _hoverStartTimestamp; int _isButtonDown; - Common::Array<UIImagePickerImage> _images; + Common::Array<Image> _images; UIImagePickerCallback *_mouseInCallback; UIImagePickerCallback *_mouseOutCallback; @@ -69,13 +69,13 @@ public: ~UIImagePicker(); void resetImages(); - bool defineImage(int i, Common::Rect rect, Shape *shapeUp, Shape *shapeHovered, Shape *shapeDown, const char *tooltip); + bool defineImage(int i, Common::Rect rect, const Shape *shapeUp, const Shape *shapeHovered, const Shape *shapeDown, const char *tooltip); bool setImageTop(int i, int top); bool setImageLeft(int i, int left); - bool setImageShapeUp(int i, Shape *shapeUp); - bool setImageShapeHovered(int i, Shape *shapeHovered); - bool setImageShapeDown(int i, Shape *shapeDown); + bool setImageShapeUp(int i, const Shape *shapeUp); + bool setImageShapeHovered(int i, const Shape *shapeHovered); + bool setImageShapeDown(int i, const Shape *shapeDown); bool setImageTooltip(int i, const char *tooltip); bool resetActiveImage(int i); diff --git a/engines/bladerunner/ui/ui_input_box.cpp b/engines/bladerunner/ui/ui_input_box.cpp new file mode 100644 index 0000000000..409563f73e --- /dev/null +++ b/engines/bladerunner/ui/ui_input_box.cpp @@ -0,0 +1,115 @@ +/* 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/ui/ui_input_box.h" + +#include "bladerunner/bladerunner.h" +#include "bladerunner/font.h" + +#include "common/keyboard.h" + +#include "graphics/surface.h" + +namespace BladeRunner { + +UIInputBox::UIInputBox(BladeRunnerEngine *vm, UIComponentCallback *valueChangedCallback, void *callbackData, Common::Rect rect, int maxLength, const Common::String &text) + : UIComponent(vm) { + _valueChangedCallback = valueChangedCallback; + _callbackData = callbackData; + + _isVisible = true; + _rect = rect; + + _maxLength = maxLength; + _length = 0; + setText(text); + + _cursorIsVisible = false; + _timeLast = _vm->getTotalPlayTime(); +} + +void UIInputBox::draw(Graphics::Surface &surface) { + if (!_isVisible) { + return; + } + + int rectHalfWidth = (_rect.right + _rect.left) / 2; + int textHalfWidth = _vm->_mainFont->getTextWidth(_text) / 2; + + _vm->_mainFont->drawColor(_text, surface, rectHalfWidth - textHalfWidth, _rect.top, 0x4DC7); // 10011 01110 00111 + + if (_cursorIsVisible) { + surface.vLine(textHalfWidth + rectHalfWidth + 2, _rect.top, _rect.bottom - 1, 0x7FDD); // 11111 11110 11101 + } + + if (_vm->getTotalPlayTime() - _timeLast > 500) { + _timeLast = _vm->getTotalPlayTime(); + _cursorIsVisible = !_cursorIsVisible; + } +} + +void UIInputBox::setText(const Common::String &text) { + _text = text; +} + +const Common::String &UIInputBox::getText() { + return _text; +} + +void UIInputBox::show() { + _isVisible = true; +} + +void UIInputBox::hide() { + _isVisible = false; +} + +void UIInputBox::handleKeyUp(const Common::KeyState &kbd) { + if (_isVisible) { + if (charIsValid(kbd)) { + _text += kbd.ascii; + } else if (kbd.keycode == Common::KEYCODE_BACKSPACE) { + _text.deleteLastChar(); + } else if (kbd.keycode == Common::KEYCODE_RETURN && !_text.empty()) { + if (_valueChangedCallback) { + _valueChangedCallback(_callbackData, this); + } + } + } +} + +bool UIInputBox::charIsValid(const Common::KeyState &kbd) +{ + return kbd.ascii >= ' ' + && kbd.ascii != '<' + && kbd.ascii != '>' + && kbd.ascii != ':' + && kbd.ascii != '"' + && kbd.ascii != '/' + && kbd.ascii != '\\' + && kbd.ascii != '|' + && kbd.ascii != '?' + && kbd.ascii != '*' + && (kbd.ascii <= '¿' || kbd.ascii == '¡' || kbd.ascii == 'ß'); +} + +} // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/ui_input_box.h b/engines/bladerunner/ui/ui_input_box.h new file mode 100644 index 0000000000..473fe175df --- /dev/null +++ b/engines/bladerunner/ui/ui_input_box.h @@ -0,0 +1,69 @@ +/* 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_ui_inputbox_H +#define BLADERUNNER_ui_inputbox_H + +#include "bladerunner/ui/ui_component.h" + +#include "common/rect.h" +#include "common/str.h" + +namespace BladeRunner { + +class UIInputBox : public UIComponent +{ +private: + UIComponentCallback *_valueChangedCallback; + void *_callbackData; + + bool _isVisible; + Common::Rect _rect; + + int _maxLength; + int _length; + Common::String _text; + + bool _cursorIsVisible; + + int _timeLast; + +public: + UIInputBox(BladeRunnerEngine *vm, UIComponentCallback *valueChangedCallback, void *callbackData, Common::Rect rect, int maxLength, const Common::String &text); + + void draw(Graphics::Surface &surface); + + void setText(const Common::String &text); + const Common::String &getText(); + + void show(); + void hide(); + + void handleKeyUp(const Common::KeyState &kbd); + +private: + bool charIsValid(const Common::KeyState &kbd); +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/ui/ui_scroll_box.cpp b/engines/bladerunner/ui/ui_scroll_box.cpp new file mode 100644 index 0000000000..a0d53a444d --- /dev/null +++ b/engines/bladerunner/ui/ui_scroll_box.cpp @@ -0,0 +1,662 @@ +/* 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/ui/ui_scroll_box.h" + +#include "bladerunner/audio_player.h" +#include "bladerunner/bladerunner.h" +#include "bladerunner/font.h" +#include "bladerunner/game_info.h" +#include "bladerunner/shape.h" +#include "bladerunner/ui/kia.h" +#include "bladerunner/ui/kia_shapes.h" + +namespace BladeRunner { + +const int UIScrollBox::k3DFrameColors[] = { 0x1083, 0x14A5, 0x14A6, 0x2508, 0x5230, 0x5230, 0x0000, 0x0000 }; +const int UIScrollBox::kTextBackgroundColors[] = { 0x14EA, 0x190C, 0x1D2E, 0x2570, 0x4F1F, 0x0000 }; +const int UIScrollBox::kTextColors1[] = { 0x25B3, 0x31F7, 0x3A5B, 0x46BF, 0x4F1F }; +const int UIScrollBox::kTextColors2[] = { 0x677F, 0x6F9F, 0x73BF, 0x77DF, 0x7FFF }; +const int UIScrollBox::kTextColors3[] = { 0x7BB8, 0x7BBA, 0x7BDB, 0x7FDD, 0x7FFF }; +const int UIScrollBox::kTextColors4[] = { 0x4DC7, 0x5E4B, 0x6EEE, 0x7751, 0x7F92 }; + +UIScrollBox::UIScrollBox(BladeRunnerEngine *vm, UIScrollBoxCallback *lineSelectedCallback, void *callbackData, int maxLineCount, int style, bool center, Common::Rect rect, Common::Rect scrollBarRect) : UIComponent(vm) { + _selectedLineState = 0; + _scrollUpButtonState = 0; + _scrollDownButtonState = 0; + _scrollAreaUpState = 0; + _scrollAreaDownState = 0; + _scrollBarState = 0; + + _scrollUpButtonHover = false; + _scrollDownButtonHover = false; + _scrollAreaUpHover = false; + _scrollAreaDownHover = false; + _scrollBarHover = false; + + _hoveredLine = -1; + _selectedLineIndex = -1; + + _lineSelectedCallback = lineSelectedCallback; + _callbackData = callbackData; + + _isVisible = false; + _style = style; + _center = center; + _timeLastScroll = _vm->getTotalPlayTime(); + _timeLastCheckbox = _vm->getTotalPlayTime(); + _timeLastHighlight = _vm->getTotalPlayTime(); + + _highlightFrame = 0; + + _rect = rect; + _scrollBarRect = scrollBarRect; + + _lineCount = 0; + _maxLineCount = maxLineCount; + + _firstLineVisible = 0; + + _maxLinesVisible = _rect.height() / kLineHeight; + _rect.bottom = _rect.top + kLineHeight * _maxLinesVisible - 1; + + _lines.resize(_maxLineCount); + for (int i = 0; i < _maxLineCount; ++i) { + _lines[i] = new Line(); + _lines[i]->lineData = -1; + _lines[i]->flags = 0x00; + _lines[i]->checkboxFrame = 5; + } +} + +UIScrollBox::~UIScrollBox() { + for (int i = 0; i < _maxLineCount; ++i) { + delete _lines[i]; + } +} + +void UIScrollBox::show() { + _selectedLineState = 0; + _scrollUpButtonState = 0; + _scrollDownButtonState = 0; + _scrollAreaUpState = 0; + _scrollAreaDownState = 0; + _scrollBarState = 0; + + _hoveredLine = -1; + _selectedLineIndex = -1; + + _scrollUpButtonHover = false; + _scrollDownButtonHover = false; + _scrollAreaUpHover = false; + _scrollAreaDownHover = false; + _scrollBarHover = false; + + _timeLastScroll = _vm->getTotalPlayTime(); + _timeLastCheckbox = _vm->getTotalPlayTime(); + _timeLastHighlight = _vm->getTotalPlayTime(); + + _highlightFrame = 0; + _isVisible = true; +} + +void UIScrollBox::hide() { + _isVisible = false; +} + +void UIScrollBox::clearLines(){ + _lineCount = 0; + _firstLineVisible = 0; + +} + +void UIScrollBox::addLine(const Common::String &text, int lineData, int flags) { + _lines[_lineCount]->text = text; + _lines[_lineCount]->lineData = lineData; + _lines[_lineCount]->flags = flags; + + ++_lineCount; +} + +void UIScrollBox::addLine(const char *text, int lineData, int flags) { + _lines[_lineCount]->text = text; + _lines[_lineCount]->lineData = lineData; + _lines[_lineCount]->flags = flags; + + ++_lineCount; +} + +void UIScrollBox::sortLines() { + qsort(_lines.data(), _lineCount, sizeof(Line *), &sortFunction); +} + +void UIScrollBox::handleMouseMove(int mouseX, int mouseY) { + if (!_isVisible) { + return; + } + + if (_rect.contains(mouseX, mouseY)) { + int newHoveredLine = (mouseY - _rect.top) / 10 + _firstLineVisible; + if (newHoveredLine >= _lineCount) { + newHoveredLine = -1; + } + + if (newHoveredLine != _hoveredLine && newHoveredLine >= 0 && newHoveredLine < _lineCount) { + if (_lines[newHoveredLine]->lineData >= 0 && _selectedLineState == 0) { + int soundId = 507; + if (_lines[newHoveredLine]->flags & 0x01 ) { + soundId = 508; + } + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(soundId), 100, 0, 0, 50, 0); + } + } + _hoveredLine = newHoveredLine; + } else { + _hoveredLine = -1; + } + + _scrollUpButtonHover = + (mouseX >= _scrollBarRect.left) + && (mouseX < _scrollBarRect.left + 15) + && (mouseY >= _scrollBarRect.top) + && (mouseY < _scrollBarRect.top + 8); + + _scrollDownButtonHover = + (mouseX >= _scrollBarRect.left) + && (mouseX < _scrollBarRect.left + 15) + && (mouseY > _scrollBarRect.bottom - 8) + && (mouseY <= _scrollBarRect.bottom); + + int scrollAreaHeight = _scrollBarRect.bottom - _scrollBarRect.top - 15; + + int scrollBarHeight = scrollAreaHeight; + if (_lineCount > _maxLinesVisible) { + scrollBarHeight = _maxLinesVisible * scrollAreaHeight / _lineCount; + } + if (scrollBarHeight < 16) { + scrollBarHeight = 16; + } + + int scrollAreaEmptySize = scrollAreaHeight - scrollBarHeight; + + int scrollBarY = 0; + if (_lineCount > _maxLinesVisible) { + scrollBarY = scrollAreaEmptySize * _firstLineVisible / (_lineCount - _maxLinesVisible); + } + + if (_scrollBarState == 2) { + int v12 = scrollBarHeight / 2 + 8; + if (mouseY - _scrollBarRect.top > v12 && _lineCount > _maxLinesVisible && scrollAreaEmptySize > 0) { + _firstLineVisible = (_lineCount - _maxLinesVisible) * (mouseY - _scrollBarRect.top - v12) / scrollAreaEmptySize; + if (_firstLineVisible > _lineCount - _maxLinesVisible) { + _firstLineVisible = _lineCount - _maxLinesVisible; + } + } else { + _firstLineVisible = 0; + } + + if (_lineCount <= _maxLinesVisible) { + scrollBarY = 0; + } else { + scrollBarY = scrollAreaEmptySize * _firstLineVisible/ (_lineCount - _maxLinesVisible); + } + } + scrollBarY = scrollBarY + _scrollBarRect.top + 8; + + _scrollBarHover = + (mouseX >= _scrollBarRect.left) + && (mouseX < _scrollBarRect.left + 15) + && (mouseY >= scrollBarY) + && (mouseY < scrollBarY + scrollBarHeight); + + _scrollAreaUpHover = + (mouseX >= _scrollBarRect.left) + && (mouseX < _scrollBarRect.left + 15) + && (mouseY >= _scrollBarRect.top + 8) + && (mouseY < scrollBarY); + + _scrollAreaDownHover = + (mouseX >= _scrollBarRect.left) + && (mouseX < _scrollBarRect.left + 15) + && (mouseY >= scrollBarY + scrollBarHeight) + && (mouseY < _scrollBarRect.bottom - 8); +} + +void UIScrollBox::handleMouseDown(bool alternateButton) { + if (!_isVisible) { + return; + } + + _mouseButton = alternateButton; + if (_hoveredLine == -1) { + _selectedLineState = 1; + } else if (_selectedLineIndex == -1) { + _selectedLineIndex = _hoveredLine; + _selectedLineState = 2; + if (_hoveredLine < _lineCount) { + if (_lineSelectedCallback) { + _lineSelectedCallback(_callbackData, this, _lines[_selectedLineIndex]->lineData, _mouseButton); + } + + if (_lines[_selectedLineIndex]->flags & 0x01) { + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(509), 100, 0, 0, 50, 0); + } + } + } + if (!alternateButton) { + if (_scrollUpButtonHover) { + _scrollUpButtonState = 2; + _timeLastScroll = _vm->getTotalPlayTime() - 160; + } else { + _scrollUpButtonState = 1; + } + if (_scrollDownButtonHover) { + _scrollDownButtonState = 2; + } else { + _scrollDownButtonState = 1; + } + if (_scrollBarHover) { + _scrollBarState = 2; + } else { + _scrollBarState = 1; + } + if (_scrollAreaUpHover) { + _scrollAreaUpState = 2; + _timeLastScroll = _vm->getTotalPlayTime() - 160; + } else { + _scrollAreaUpState = 1; + } + if (_scrollAreaDownHover) { + _scrollAreaDownState = 2; + _timeLastScroll = _vm->getTotalPlayTime() - 160; + } else { + _scrollAreaDownState = 1; + } + } +} + +void UIScrollBox::handleMouseUp(bool alternateButton) { + if (_isVisible) { + if ( alternateButton == _mouseButton) { + _selectedLineState = 0; + _selectedLineIndex = -1; + } + + if (!alternateButton) { + _scrollUpButtonState = 0; + _scrollDownButtonState = 0; + _scrollAreaUpState = 0; + _scrollAreaDownState = 0; + _scrollBarState = 0; + } + } +} + +int UIScrollBox::getSelectedLineData() { + if (_hoveredLine >= 0 && _selectedLineState != 1 && _hoveredLine < _lineCount) { + return _lines[_hoveredLine]->lineData; + } + return -1; +} + +void UIScrollBox::draw(Graphics::Surface &surface) { + int timeNow = _vm->getTotalPlayTime(); + + // update scrolling + if (_scrollUpButtonState == 2 && _scrollUpButtonHover) { + if ((timeNow - _timeLastScroll) > 160) { + scrollUp(); + _timeLastScroll = timeNow; + } + } else if (_scrollDownButtonState == 2 && _scrollDownButtonHover) { + if ((timeNow - _timeLastScroll) > 160) { + scrollDown(); + _timeLastScroll = timeNow; + } + } else if (_scrollAreaUpState == 2 && _scrollAreaUpHover) { + if ((timeNow - _timeLastScroll) > 160) { + _firstLineVisible -= _maxLinesVisible - 1; + _firstLineVisible = CLIP(_firstLineVisible, 0, _lineCount - _maxLinesVisible); + _timeLastScroll = timeNow; + } + } else if (_scrollAreaDownState == 2 && _scrollAreaDownHover) { + if ((timeNow - _timeLastScroll) > 160) { + _firstLineVisible += _maxLinesVisible - 1; + _firstLineVisible = CLIP(_firstLineVisible, 0, _lineCount - _maxLinesVisible); + _timeLastScroll = timeNow; + } + } + + // update checkboxes + int timeDiffCheckBox = timeNow - _timeLastCheckbox; + if (timeDiffCheckBox > 67) { + _timeLastCheckbox = timeNow; + for (int i = 0; i < _lineCount; ++i) { + if (_lines[i]->flags & 0x01) { // has checkbox + if (_lines[i]->flags & 0x02) { // checkbox checked + if (_lines[i]->checkboxFrame < 5) { + _lines[i]->checkboxFrame += timeDiffCheckBox / 67; + } + if (_lines[i]->checkboxFrame > 5) { + _lines[i]->checkboxFrame = 5; + } + } else { // checkbox not checked + if (_lines[i]->checkboxFrame > 0) { + _lines[i]->checkboxFrame -= timeDiffCheckBox / 67; + } + if (_lines[i]->checkboxFrame < 0) { + _lines[i]->checkboxFrame = 0; + } + } + } + } + } + + + // update highlight + if ((timeNow - _timeLastHighlight) > 67) { + _timeLastHighlight = timeNow; + _highlightFrame = (_highlightFrame + 1) % 8; + } + + // draw text lines + int linesVisible = 0; + int lastLineVisible = 0; + + if (_maxLinesVisible < _lineCount - _firstLineVisible) { + linesVisible = _maxLinesVisible; + lastLineVisible = _firstLineVisible + _maxLinesVisible; + } else { + linesVisible = _lineCount - _firstLineVisible; + lastLineVisible = _lineCount; + } + + if (_firstLineVisible < lastLineVisible) { + int y = _rect.top; + int y1 = _rect.top + 8; + int y2 = _rect.top + 2; + int i = _firstLineVisible; + do { + int startingColorIndex = 3; + if (i - _firstLineVisible < 3) { + startingColorIndex = i - _firstLineVisible; + } + + int endingColorIndex = 3; + if (i - _firstLineVisible >= linesVisible - 3) { + endingColorIndex = linesVisible - (i - _firstLineVisible + 1); + } + + int colorIndex = endingColorIndex; + if (startingColorIndex < endingColorIndex) { + colorIndex = startingColorIndex; + } + + bool v35 = false; + int color = 0; + + if ((((_selectedLineState == 0 && i == _hoveredLine) || (_selectedLineState == 2 && i == _selectedLineIndex && _selectedLineIndex == _hoveredLine)) && _lines[i]->lineData != -1) || _lines[i]->flags & 0x04) { + v35 = true; + if (_style) { + color = kTextColors2[colorIndex]; + } else { + color = kTextColors3[colorIndex]; + } + } + else { + if (_style) { + color = kTextColors1[colorIndex]; + } else { + color = kTextColors4[colorIndex]; + } + } + + int x = _rect.left; + + if (_lines[i]->flags & 0x01) { // has checkbox + int checkboxShapeId = 0; + if (_style == 0) { + if (_lines[i]->checkboxFrame || v35) { + if (_lines[i]->checkboxFrame != 5 || v35) { + checkboxShapeId = _lines[i]->checkboxFrame + 62; + } else { + checkboxShapeId = 61; + } + } else { + checkboxShapeId = 60; + } + } else if (_lines[i]->checkboxFrame || v35) { + if (_lines[i]->checkboxFrame != 5 || v35) { + checkboxShapeId = _lines[i]->checkboxFrame + 54; + } else { + checkboxShapeId = 53; + } + } else { + checkboxShapeId = 52; + } + _vm->_kia->_shapes->get(checkboxShapeId)->draw(surface, x - 1, y); + x += 11; + } + + if (_lines[i]->flags & 0x10) { // highlighted line + if (_lines[i]->flags & 0x20) { + int highlightShapeId = _highlightFrame; + if (highlightShapeId > 4) { + highlightShapeId = 8 - highlightShapeId; + } + _vm->_kia->_shapes->get(highlightShapeId + 85)->draw(surface, x, y2); + } + x += 6; + } + + if (_lines[i]->flags & 0x08) { // has background rectangle + int colorBackground = 0; + if (_style) { + colorBackground = kTextBackgroundColors[colorIndex]; + } else { + colorBackground = 0x28E4; + } + surface.fillRect(Common::Rect(x, y, _rect.right + 1, y1 + 1), colorBackground); + } + + if (_center) { + x = (_rect.width() - _vm->_mainFont->getTextWidth(_lines[i]->text)) / 2; + } + + _vm->_mainFont->drawColor(_lines[i]->text, surface, x, y, color); + + y1 += kLineHeight; + y2 += kLineHeight; + y += kLineHeight; + ++i; + } + while (i < lastLineVisible); + } + + // draw scroll up button + int scrollUpButtonShapeId = 0; + if (_scrollUpButtonState) { + if (_scrollUpButtonState == 2) { + if (_scrollUpButtonHover) { + scrollUpButtonShapeId = 72; + } else { + scrollUpButtonShapeId = 71; + } + } else { + scrollUpButtonShapeId = 70; + } + } else if (_scrollUpButtonHover) { + scrollUpButtonShapeId = 71; + } else { + scrollUpButtonShapeId = 70; + } + _vm->_kia->_shapes->get(scrollUpButtonShapeId)->draw(surface, _scrollBarRect.left, _scrollBarRect.top); + + // draw scroll down button + int scrollDownButtonShapeId = 0; + if (_scrollDownButtonState) { + if (_scrollDownButtonState == 2) { + if (_scrollDownButtonHover) { + scrollDownButtonShapeId = 75; + } else { + scrollDownButtonShapeId = 74; + } + } else { + scrollDownButtonShapeId = 73; + } + } else if (_scrollDownButtonHover) { + scrollDownButtonShapeId = 74; + } else { + scrollDownButtonShapeId = 73; + } + _vm->_kia->_shapes->get(scrollDownButtonShapeId)->draw(surface, _scrollBarRect.left, _scrollBarRect.bottom - 7); + + int scrollAreaSize = _scrollBarRect.bottom - (_scrollBarRect.top + 15); + int scrollBarHeight = 0; + if (_lineCount <= _maxLinesVisible) { + scrollBarHeight = _scrollBarRect.bottom - (_scrollBarRect.top + 15); + } else { + scrollBarHeight = _maxLinesVisible * scrollAreaSize / _lineCount; + } + scrollBarHeight = MAX(scrollBarHeight, 16); + + int v56 = 0; + if (_lineCount <= _maxLinesVisible) { + v56 = 0; + } else { + v56 = _firstLineVisible * (scrollAreaSize - scrollBarHeight) / (_lineCount - _maxLinesVisible); + } + + int v58 = v56 + _scrollBarRect.top + 8; + + if (_scrollBarState == 2) { + draw3DFrame(surface, Common::Rect(_scrollBarRect.left, v58, _scrollBarRect.left + 15, v58 + scrollBarHeight), 1, 1); + } else if (!_scrollBarState && _scrollBarHover) { + draw3DFrame(surface, Common::Rect(_scrollBarRect.left, v56 + _scrollBarRect.top + 8, _scrollBarRect.left + 15, v58 + scrollBarHeight), 0, 1); + } else { + draw3DFrame(surface, Common::Rect(_scrollBarRect.left, v58, _scrollBarRect.left + 15, v58 + scrollBarHeight), 0, 0); + } +} + +void UIScrollBox::checkAll() { + for (int i = 0; i < _lineCount; ++i) { + if (_lines[i]->flags & 0x01) { + _lines[i]->flags |= 0x02; + } + } +} + +void UIScrollBox::uncheckAll() { + for (int i = 0; i < _lineCount; ++i) { + if (_lines[i]->flags & 0x01) { + _lines[i]->flags &= ~0x02; + } + } +} + +void UIScrollBox::toggleCheckBox(int lineData) { + int i = findLine(lineData); + if (i != -1) { + if (_lines[i]->flags & 0x02) { + _lines[i]->flags &= ~0x02; + } else { + _lines[i]->flags |= 0x02; + } + } +} + +bool UIScrollBox::hasLine(int lineData) { + return findLine(lineData) != -1; +} + +void UIScrollBox::resetHighlight(int lineData) { + int i = findLine(lineData); + if (i != -1) { + _lines[i]->flags &= ~0x20; + } +} + +void UIScrollBox::setFlags(int lineData, int flags) { + int i = findLine(lineData); + if (i != -1) { + _lines[i]->flags |= flags; + } +} + +void UIScrollBox::resetFlags(int lineData, int flags) { + int i = findLine(lineData); + if (i != -1) { + _lines[i]->flags &= ~flags; + } +} + +int UIScrollBox::sortFunction(const void *item1, const void *item2) { + Line *line1 = *(Line * const *)item1; + Line *line2 = *(Line * const *)item2; + return line1->text.compareToIgnoreCase(line2->text); +} + +void UIScrollBox::draw3DFrame(Graphics::Surface &surface, Common::Rect rect, bool pressed, int style) { + int color1, color2; + + if (pressed) { + color1 = k3DFrameColors[style + 6]; + color2 = k3DFrameColors[style + 4]; + } else { + color1 = k3DFrameColors[style + 4]; + color2 = k3DFrameColors[style + 6]; + } + + int fillColor = k3DFrameColors[style + 2]; + + surface.fillRect(Common::Rect(rect.left + 1, rect.top + 1, rect.right - 1, rect.bottom - 1), fillColor); + + surface.hLine(rect.left + 1, rect.top, rect.right - 2, color1); + surface.hLine(rect.left + 1, rect.bottom - 1, rect.right - 2, color2); + surface.vLine(rect.left, rect.top, rect.bottom - 2, color1); + surface.vLine(rect.right - 1, rect.top + 1, rect.bottom - 1, color2); + surface.hLine(rect.right - 1, rect.top, rect.right - 1, k3DFrameColors[style]); + surface.hLine(rect.left, rect.bottom - 1, rect.left, k3DFrameColors[style]); +} + +void UIScrollBox::scrollUp() { + if (_firstLineVisible > 0) { + --_firstLineVisible; + } +} + +void UIScrollBox::scrollDown() { + if (_lineCount - _firstLineVisible > _maxLinesVisible) { + ++_firstLineVisible; + } +} + +int UIScrollBox::findLine(int lineData) { + for (int i = 0; i < _lineCount; ++i) { + if (_lines[i]->lineData == lineData) { + return i; + } + } + return -1; +} + +} // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/ui_scroll_box.h b/engines/bladerunner/ui/ui_scroll_box.h new file mode 100644 index 0000000000..1f416baffc --- /dev/null +++ b/engines/bladerunner/ui/ui_scroll_box.h @@ -0,0 +1,137 @@ +/* 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_UI_SCROLLBOX_H +#define BLADERUNNER_UI_SCROLLBOX_H + +#include "bladerunner/ui/ui_component.h" + +#include "common/array.h" +#include "common/rect.h" +#include "common/str.h" + +namespace BladeRunner { + +typedef void UIScrollBoxCallback(void *callbackData, void *source, int lineData, int mouseButton); + +class UIScrollBox : public UIComponent +{ +private: + static const int kLineHeight = 10; + static const int k3DFrameColors[]; + static const int kTextBackgroundColors[]; + static const int kTextColors1[]; + static const int kTextColors2[]; + static const int kTextColors3[]; + static const int kTextColors4[]; + + struct Line { + Common::String text; + int lineData; + int flags; + int checkboxFrame; + }; + + int _selectedLineState; + int _scrollUpButtonState; + int _scrollDownButtonState; + int _scrollAreaUpState; + int _scrollAreaDownState; + int _scrollBarState; + + int _hoveredLine; + int _selectedLineIndex; + + bool _scrollUpButtonHover; + bool _scrollDownButtonHover; + bool _scrollAreaUpHover; + bool _scrollAreaDownHover; + bool _scrollBarHover; + + bool _mouseButton; + + UIScrollBoxCallback *_lineSelectedCallback; + void *_callbackData; + + bool _isVisible; + int _style; + bool _center; + + int _timeLastScroll; + int _timeLastCheckbox; + int _timeLastHighlight; + + int _highlightFrame; + + Common::Rect _rect; + Common::Rect _scrollBarRect; + + int _lineCount; + int _maxLineCount; + Common::Array<Line *> _lines; + int _maxLinesVisible; + int _firstLineVisible; + +public: + UIScrollBox(BladeRunnerEngine *vm, UIScrollBoxCallback *lineSelectedCallback, void *callbackData, int maxLineCount, int style, bool center, Common::Rect rect,Common::Rect scrollBarRect); + ~UIScrollBox(); + + void draw(Graphics::Surface &surface); + + void handleMouseMove(int mouseX, int mouseY); + void handleMouseDown(bool alternateButton); + void handleMouseUp(bool alternateButton); + + void show(); + void hide(); + + void clearLines(); + void addLine(const Common::String &text, int lineData, int flags); + void addLine(const char *text, int lineData, int flags); + void sortLines(); + + int getSelectedLineData(); + + void checkAll(); + void uncheckAll(); + void toggleCheckBox(int lineData); + + bool hasLine(int lineData); + + void resetHighlight(int lineData); + void setFlags(int lineData, int flags); + void resetFlags(int lineData, int flags); + +private: + static int sortFunction(const void *line1, const void *line2); + + void draw3DFrame(Graphics::Surface &surface, Common::Rect rect, bool pressed, int style); + + void scrollUp(); + void scrollDown(); + + int findLine(int lineData); +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/ui/ui_slider.cpp b/engines/bladerunner/ui/ui_slider.cpp new file mode 100644 index 0000000000..d25b7fac2c --- /dev/null +++ b/engines/bladerunner/ui/ui_slider.cpp @@ -0,0 +1,153 @@ +/* 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/ui/ui_slider.h" + +#include "bladerunner/audio_player.h" +#include "bladerunner/bladerunner.h" +#include "bladerunner/game_info.h" + +namespace BladeRunner { + +const uint16 UISlider::kColors[] = { 0x0000, 0x0821, 0x1061, 0x1C82, 0x24C2, 0x2CE3, 0x3524, 0x4145, 0x4586, 0x4DC7, 0x5609, 0x5E4B, 0x668C, 0x6EEE, 0x7730, 0x7B92 }; + +UISlider::UISlider(BladeRunnerEngine *vm, UIComponentCallback *valueChangedCallback, void *callbackData, Common::Rect rect, int maxValue, int value) + : UIComponent(vm) { + + _valueChangedCallback = valueChangedCallback; + _callbackData = callbackData; + + _maxValue = MAX(0, maxValue); + _value = CLIP(value, 0, _maxValue - 1); + + _rect = rect; + _isEnabled = true; + _currentFrameColor = 0; + _hasFocus = false; + _pressedStatus = 0; +} + +void UISlider::draw(Graphics::Surface &surface) { + if (_rect.isEmpty()) { + return; + } + + int frameColor; + if (_pressedStatus == 1) { + frameColor = 10; + } else if (_hasFocus && _pressedStatus != 2 && _isEnabled) { + frameColor = 5; + } else { + frameColor = 0; + } + + if (_currentFrameColor < frameColor) { + ++_currentFrameColor; + } + + if (_currentFrameColor > frameColor) { + --_currentFrameColor; + } + + surface.frameRect(_rect, kColors[_currentFrameColor]); + + int sliderX = 0; + if (_maxValue <= 1) { + sliderX = _rect.left; + } else { + sliderX = _rect.left + ((_value * _rect.width()) / (_maxValue - 1)); + } + + if (_pressedStatus == 1) { + int sliderValue = ((_maxValue - 1) * (_mouseX - _rect.left)) / _rect.width(); + sliderX = _rect.left + ((sliderValue * _rect.width()) / (_maxValue - 1)); + sliderX = CLIP(sliderX, (int)_rect.left, (int)_rect.right); + } + + if (_rect.left + 1 < _rect.right - 1) { + int striding = _rect.left + sliderX; + for (int x = _rect.left + 1; x < _rect.right - 1; x++) { + int colorIndex = 15 - (abs(sliderX - x) >> 2); + + if (!_isEnabled) { + colorIndex /= 2; + } + + if (colorIndex < 3) { + colorIndex = 3; + } + + uint16 color = kColors[colorIndex]; + if ((striding + x) & 1 || x == sliderX) { + color = 0; + } + + surface.vLine(x, _rect.top + 1, _rect.bottom - 2, color); + } + } +} + +void UISlider::handleMouseMove(int mouseX, int mouseY) { + _mouseX = mouseX; + if (_rect.contains(mouseX, mouseY)) { + if (!_hasFocus && _isEnabled && _pressedStatus == 0) { + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(508), 100, 0, 0, 50, 0); + } + _hasFocus = true; + } else { + _hasFocus = false; + } +} + +void UISlider::handleMouseDown(bool alternateButton) { + if (_isEnabled && !alternateButton) { + if (_hasFocus) { + _pressedStatus = 1; + } else { + _pressedStatus = 2; + } + } +} + +void UISlider::handleMouseUp(bool alternateButton) { + if (!alternateButton) { + if (_pressedStatus == 1) { + if (_rect.width() == 0) { + _value = 0; + } else { + _value = ((_maxValue - 1) * (_mouseX - _rect.left)) / _rect.width(); + } + _value = CLIP(_value, 0, _maxValue - 1); + + if (_valueChangedCallback) { + _valueChangedCallback(_callbackData, this); + } + } + _pressedStatus = 0; + } +} + +void UISlider::setValue(int value) { + _value = CLIP(value, 0, _maxValue - 1); +} + +} // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/ui_slider.h b/engines/bladerunner/ui/ui_slider.h new file mode 100644 index 0000000000..7cbd5bfda7 --- /dev/null +++ b/engines/bladerunner/ui/ui_slider.h @@ -0,0 +1,63 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BLADERUNNER_UI_SLIDER_H +#define BLADERUNNER_UI_SLIDER_H + +#include "bladerunner/ui/ui_component.h" + +#include "common/rect.h" + +namespace BladeRunner { + +class UISlider : public UIComponent +{ +private: + static const uint16 kColors[]; + + UIComponentCallback *_valueChangedCallback; + void *_callbackData; + bool _isEnabled; + int _maxValue; + Common::Rect _rect; + int _currentFrameColor; + bool _hasFocus; + int _pressedStatus; + int _mouseX; + +public: + int _value; + + UISlider(BladeRunnerEngine *vm, UIComponentCallback *valueChangedCallback, void *callbackData, Common::Rect rect, int maxValue, int value); + + void draw(Graphics::Surface &surface); + + void handleMouseMove(int mouseX, int mouseY); + void handleMouseDown(bool alternateButton); + void handleMouseUp(bool alternateButton); + + void setValue(int value); +}; + +} // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/vqa_decoder.cpp b/engines/bladerunner/vqa_decoder.cpp index 832e95aa2b..aec4d18e5d 100644 --- a/engines/bladerunner/vqa_decoder.cpp +++ b/engines/bladerunner/vqa_decoder.cpp @@ -182,7 +182,7 @@ bool VQADecoder::loadStream(Common::SeekableReadStream *s) { _videoTrack = new VQAVideoTrack(this, _surface); _audioTrack = new VQAAudioTrack(this); -#if 0 +#if BLADERUNNER_DEBUG_CONSOLE for (int i = 0; i != _loopInfo.loopCount; ++i) { debug("LOOP %2d: %4d %4d %s", i, _loopInfo.loops[i].begin, @@ -507,7 +507,14 @@ bool VQADecoder::readLNIN(Common::SeekableReadStream *s, uint32 size) { uint16 loopUnk3 = s->readUint16LE(); uint16 loopUnk4 = s->readUint16LE(); +#if BLADERUNNER_DEBUG_CONSOLE debug("VQADecoder::readLNIN() Unknown Values: 0x%04x 0x%04x 0x%04x 0x%04x", loopUnk1, loopUnk2, loopUnk3, loopUnk4); +#else + (void)loopUnk1; + (void)loopUnk2; + (void)loopUnk3; + (void)loopUnk4; +#endif if (loopNamesCount != _loopInfo.loopCount) return false; @@ -516,7 +523,7 @@ bool VQADecoder::readLNIN(Common::SeekableReadStream *s, uint32 size) { if (chd.id != kLNIO || chd.size != 4u * loopNamesCount) return false; - uint32 *loopNameOffsets = (uint32*)malloc(loopNamesCount * sizeof(uint32)); + uint32 *loopNameOffsets = (uint32 *)malloc(loopNamesCount * sizeof(uint32)); for (int i = 0; i != loopNamesCount; ++i) { loopNameOffsets[i] = s->readUint32LE(); } @@ -527,7 +534,7 @@ bool VQADecoder::readLNIN(Common::SeekableReadStream *s, uint32 size) { return false; } - char *names = (char*)malloc(roundup(chd.size)); + char *names = (char *)malloc(roundup(chd.size)); s->read(names, roundup(chd.size)); for (int i = 0; i != loopNamesCount; ++i) { @@ -630,7 +637,7 @@ Common::Rational VQADecoder::VQAVideoTrack::getFrameRate() const { void VQADecoder::VQAVideoTrack::decodeVideoFrame(bool forceDraw) { if (_hasNewFrame || forceDraw) { - decodeFrame((uint16*)_surface->getPixels()); + decodeFrame((uint16 *)_surface->getPixels()); _hasNewFrame = false; } } @@ -917,14 +924,14 @@ VQADecoder::VQAAudioTrack::~VQAAudioTrack() { } Audio::SeekableAudioStream *VQADecoder::VQAAudioTrack::decodeAudioFrame() { - int16 *audioFrame = (int16*)malloc(4 * 735); + int16 *audioFrame = (int16 *)malloc(4 * 735); memset(audioFrame, 0, 4 * 735); _adpcmDecoder.decode(_compressedAudioFrame, 735, audioFrame); uint flags = Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN; - return Audio::makeRawStream((byte*)audioFrame, 4 * 735, _frequency, flags, DisposeAfterUse::YES); + return Audio::makeRawStream((byte *)audioFrame, 4 * 735, _frequency, flags, DisposeAfterUse::YES); } bool VQADecoder::VQAAudioTrack::readSND2(Common::SeekableReadStream *s, uint32 size) { diff --git a/engines/bladerunner/vqa_player.cpp b/engines/bladerunner/vqa_player.cpp index 7e820b7db2..1616459d36 100644 --- a/engines/bladerunner/vqa_player.cpp +++ b/engines/bladerunner/vqa_player.cpp @@ -164,7 +164,7 @@ void VQAPlayer::updateLights(Lights *lights) { } bool VQAPlayer::setLoop(int loop, int repeatsCount, int loopSetMode, void (*callback)(void *, int, int), void *callbackData) { -#if 0 +#if BLADERUNNER_DEBUG_CONSOLE debug("VQAPlayer::setBeginAndEndFrameFromLoop(%i, %i, %i), streamLoaded = %i", loop, repeatsCount, loopSetMode, _s != nullptr); #endif if (_s == nullptr) { @@ -185,7 +185,7 @@ bool VQAPlayer::setLoop(int loop, int repeatsCount, int loopSetMode, void (*call } bool VQAPlayer::setBeginAndEndFrame(int begin, int end, int repeatsCount, int loopSetMode, void (*callback)(void *, int, int), void *callbackData) { -#if 0 +#if BLADERUNNER_DEBUG_CONSOLE debug("VQAPlayer::setBeginAndEndFrame(%i, %i, %i, %i), streamLoaded = %i", begin, end, repeatsCount, loopSetMode, _s != nullptr); #endif diff --git a/engines/bladerunner/vqa_player.h b/engines/bladerunner/vqa_player.h index 3a929ef592..d1a212ae32 100644 --- a/engines/bladerunner/vqa_player.h +++ b/engines/bladerunner/vqa_player.h @@ -70,7 +70,7 @@ class VQAPlayer { bool _audioStarted; Audio::SoundHandle _soundHandle; - void (*_callbackLoopEnded)(void*, int frame, int loopId); + void (*_callbackLoopEnded)(void *, int frame, int loopId); void *_callbackData; public: @@ -110,7 +110,7 @@ public: void updateLights(Lights *lights); bool setBeginAndEndFrame(int begin, int end, int repeatsCount, int loopSetMode, void(*callback)(void *, int, int), void *callbackData); - bool setLoop(int loop, int repeatsCount, int loopSetMode, void(*callback)(void*, int, int), void* callbackData); + bool setLoop(int loop, int repeatsCount, int loopSetMode, void(*callback)(void*, int, int), void *callbackData); bool seekToFrame(int frame); diff --git a/engines/bladerunner/waypoints.cpp b/engines/bladerunner/waypoints.cpp index 7f709963df..4d80841e50 100644 --- a/engines/bladerunner/waypoints.cpp +++ b/engines/bladerunner/waypoints.cpp @@ -21,71 +21,72 @@ */ #include "bladerunner/waypoints.h" + namespace BladeRunner { Waypoints::Waypoints(BladeRunnerEngine *vm, int count) { _vm = vm; _count = count; - _waypoints = new Waypoint[count]; -} - -Waypoints::~Waypoints() { - delete[] _waypoints; + _waypoints.resize(count); } -void Waypoints::getXYZ(int waypointId, float *x, float *y, float *z) { +void Waypoints::getXYZ(int waypointId, float *x, float *y, float *z) const { *x = 0; *y = 0; *z = 0; - if (waypointId < 0 || waypointId >= _count || !_waypoints[waypointId]._present) + if (waypointId < 0 || waypointId >= _count || !_waypoints[waypointId].present) { return; + } - *x = _waypoints[waypointId]._position.x; - *y = _waypoints[waypointId]._position.y; - *z = _waypoints[waypointId]._position.z; + *x = _waypoints[waypointId].position.x; + *y = _waypoints[waypointId].position.y; + *z = _waypoints[waypointId].position.z; } -int Waypoints::getSetId(int waypointId) { - if (waypointId < 0 || waypointId >= _count || !_waypoints[waypointId]._present) +int Waypoints::getSetId(int waypointId) const { + if (waypointId < 0 || waypointId >= _count || !_waypoints[waypointId].present) { return -1; - return _waypoints[waypointId]._setId; + } + return _waypoints[waypointId].setId; } bool Waypoints::set(int waypointId, int setId, Vector3 position) { - if (waypointId < 0 || waypointId >= _count) + if (waypointId < 0 || waypointId >= _count) { return false; + } - _waypoints[waypointId]._setId = setId; - _waypoints[waypointId]._position = position; - _waypoints[waypointId]._present = true; + _waypoints[waypointId].setId = setId; + _waypoints[waypointId].position = position; + _waypoints[waypointId].present = true; return true; } bool Waypoints::reset(int waypointId) { - if (waypointId < 0 || waypointId >= _count) + if (waypointId < 0 || waypointId >= _count) { return false; + } - _waypoints[waypointId]._setId = -1; - _waypoints[waypointId]._position.x = 0; - _waypoints[waypointId]._position.y = 0; - _waypoints[waypointId]._position.z = 0; - _waypoints[waypointId]._present = false; + _waypoints[waypointId].setId = -1; + _waypoints[waypointId].position.x = 0; + _waypoints[waypointId].position.y = 0; + _waypoints[waypointId].position.z = 0; + _waypoints[waypointId].present = false; return true; } -float Waypoints::getX(int waypointId) { - return _waypoints[waypointId]._position.x; +float Waypoints::getX(int waypointId) const { + return _waypoints[waypointId].position.x; } -float Waypoints::getY(int waypointId) { - return _waypoints[waypointId]._position.y; +float Waypoints::getY(int waypointId) const { + return _waypoints[waypointId].position.y; } -float Waypoints::getZ(int waypointId) { - return _waypoints[waypointId]._position.z; +float Waypoints::getZ(int waypointId) const { + return _waypoints[waypointId].position.z; } } // End of namespace BladeRunner diff --git a/engines/bladerunner/waypoints.h b/engines/bladerunner/waypoints.h index 8319c77f92..5a2a1fce6a 100644 --- a/engines/bladerunner/waypoints.h +++ b/engines/bladerunner/waypoints.h @@ -30,28 +30,30 @@ namespace BladeRunner { -struct Waypoint { - int _setId; - Vector3 _position; - bool _present; -}; - class Waypoints { +#if BLADERUNNER_DEBUG_RENDERING + friend class BladeRunnerEngine; +#endif + + struct Waypoint { + int setId; + Vector3 position; + bool present; + }; + BladeRunnerEngine *_vm; -public: - int _count; - Waypoint *_waypoints; + int _count; + Common::Array<Waypoint> _waypoints; public: Waypoints(BladeRunnerEngine *vm, int count); - ~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); + void getXYZ(int waypointId, float *x, float *y, float *z) const; + float getX(int waypointId) const; + float getY(int waypointId) const; + float getZ(int waypointId) const; + int getSetId(int waypointId) const; bool set(int waypointId, int setId, Vector3 position); bool reset(int waypointId); diff --git a/engines/bladerunner/zbuffer.cpp b/engines/bladerunner/zbuffer.cpp index 3f2ed9abcc..184755b5f9 100644 --- a/engines/bladerunner/zbuffer.cpp +++ b/engines/bladerunner/zbuffer.cpp @@ -57,7 +57,7 @@ void ZBufferDirtyRects::extendExisting() { } } -int ZBufferDirtyRects::getCount() { +int ZBufferDirtyRects::getCount() const { return _count; } @@ -93,9 +93,9 @@ static int decodePartialZBuffer(const uint8 *src, uint16 *curZBUF, uint32 srcLen uint32 dstRemain = dstSize; uint16 *curzp = curZBUF; - const uint16 *inp = (const uint16*)src; + const uint16 *inp = (const uint16 *)src; - while (dstRemain && (inp - (const uint16*)src) < (std::ptrdiff_t)srcLen) { + while (dstRemain && (inp - (const uint16 *)src) < (std::ptrdiff_t)srcLen) { uint32 count = FROM_LE_16(*inp++); if (count & 0x8000) { @@ -147,7 +147,7 @@ bool ZBuffer::decodeData(const uint8 *data, int size) { if (complete) { resetUpdates(); size_t zbufOutSize; - decompress_lzo1x(data, size, (uint8*)_zbuf1, &zbufOutSize); + decompress_lzo1x(data, size, (uint8 *)_zbuf1, &zbufOutSize); memcpy(_zbuf2, _zbuf1, 2 * _width * _height); } else { clean(); @@ -158,16 +158,17 @@ bool ZBuffer::decodeData(const uint8 *data, int size) { return true; } -uint16 *ZBuffer::getData() { +uint16 *ZBuffer::getData() const { return _zbuf2; } -uint16 ZBuffer::getZValue(int x, int y) { +uint16 ZBuffer::getZValue(int x, int y) const { assert(x >= 0 && x < _width); assert(y >= 0 && y < _height); - if (!_zbuf2) + if (!_zbuf2) { return 0; + } return _zbuf2[y * _width + x]; } diff --git a/engines/bladerunner/zbuffer.h b/engines/bladerunner/zbuffer.h index 3e6f46d81d..edb1822c6d 100644 --- a/engines/bladerunner/zbuffer.h +++ b/engines/bladerunner/zbuffer.h @@ -43,7 +43,7 @@ public: void reset(); bool add(Common::Rect rect); void extendExisting(); - int getCount(); + int getCount() const; bool popRect(Common::Rect *rect); }; @@ -65,8 +65,8 @@ public: void init(int width, int height); bool decodeData(const uint8 *data, int size); - uint16 *getData(); - uint16 getZValue(int x, int y); + uint16 *getData() const; + uint16 getZValue(int x, int y) const; private: void reset(); |