BLADERUNNER: Added basic KIA interface

Settings works
Help works
Clue database works
Fixed code for inserting objects into scene
Reorganization of few files
Unification & code formatting of few older files
This commit is contained in:
Peter Kohaut 2018-01-14 12:12:06 +01:00
parent 3a937f19c0
commit 1e5f9d3078
155 changed files with 7210 additions and 2182 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;
}
bool ActorClues::isFlag4(int clueId) {
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::isPrivate(int clueId) const {
int clueIndex = findClueIndex(clueId);
if (clueIndex == -1) {
return false;
}
return (_clues[clueIndex]._flags & 0x08) >> 3;
return _clues[clueIndex].flags & 0x08;
}
int ActorClues::getField1(int clueId) {
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) 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;
}

View File

@ -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 getCount();
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() 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);
};

View File

@ -32,7 +32,6 @@ class BladeRunnerEngine;
class ActorCombat {
BladeRunnerEngine *_vm;
private:
// int _actorId;
// int _combatOn;
// int _field2;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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);
};

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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();

View File

@ -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/script/init.h"
#include "bladerunner/script/scene.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/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;
}

View File

@ -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;
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 *_textCluetype;
TextResource *_textKIA;
TextResource *_textSpinnerDestinations;
TextResource *_textVK;
TextResource *_textOptions;
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);

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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::setMissSoundId(int row, int column, int soundId) {
_missSoundId[row * 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)];
}
int Combat::getMissSound() {
return _hitSoundId[3 * _vm->_settings->getAmmoType() + _vm->_rnd.getRandomNumber(2)];
}
} // End of namespace BladeRunner

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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();

View File

@ -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();

View File

@ -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);
};

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
flags[flag / 32] &= ~(1 << (flag % 32));
assert(flag >= 0 && flag <= _flagCount);
_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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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()) {

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);
}
}

View File

@ -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();
};

View File

@ -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 \

View File

@ -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();

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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;

View File

@ -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();
};

View File

@ -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);

View File

@ -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);
};

View File

@ -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);

View File

@ -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);

View File

@ -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++;

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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) {

View File

@ -29,9 +29,9 @@ namespace BladeRunner {
class BladeRunnerEngine;
class ScriptESPER : ScriptBase {
class ESPERScript : ScriptBase {
public:
ScriptESPER(BladeRunnerEngine *vm)
ESPERScript(BladeRunnerEngine *vm)
: ScriptBase(vm) {
}

View File

@ -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:

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -29,9 +29,9 @@ namespace BladeRunner {
class BladeRunnerEngine;
class ScriptVK : ScriptBase {
class VKScript : ScriptBase {
public:
ScriptVK(BladeRunnerEngine *vm)
VKScript(BladeRunnerEngine *vm)
: ScriptBase(vm) {
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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 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) const;
void calculateColor(Vector3 viewPosition, Vector3 position, float *outCoeficient, Color *outColor);
private:
Fog *findFog(const char* fogName);
Fog *findFog(const char *fogName) const;
};
} // End of namespace BladeRunner

View File

@ -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;

View File

@ -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

Some files were not shown because too many files have changed in this diff Show More