aboutsummaryrefslogtreecommitdiff
path: root/engines/bladerunner
diff options
context:
space:
mode:
Diffstat (limited to 'engines/bladerunner')
-rw-r--r--engines/bladerunner/actor.cpp226
-rw-r--r--engines/bladerunner/actor.h20
-rw-r--r--engines/bladerunner/actor_clues.cpp46
-rw-r--r--engines/bladerunner/actor_clues.h9
-rw-r--r--engines/bladerunner/actor_combat.cpp75
-rw-r--r--engines/bladerunner/actor_combat.h10
-rw-r--r--engines/bladerunner/actor_dialogue_queue.cpp66
-rw-r--r--engines/bladerunner/actor_dialogue_queue.h8
-rw-r--r--engines/bladerunner/actor_walk.cpp50
-rw-r--r--engines/bladerunner/actor_walk.h7
-rw-r--r--engines/bladerunner/ambient_sounds.cpp131
-rw-r--r--engines/bladerunner/ambient_sounds.h52
-rw-r--r--engines/bladerunner/archive.cpp30
-rw-r--r--engines/bladerunner/archive.h7
-rw-r--r--engines/bladerunner/audio_player.cpp2
-rw-r--r--engines/bladerunner/audio_speech.cpp8
-rw-r--r--engines/bladerunner/audio_speech.h3
-rw-r--r--engines/bladerunner/bladerunner.cpp139
-rw-r--r--engines/bladerunner/bladerunner.h12
-rw-r--r--engines/bladerunner/boundingbox.cpp12
-rw-r--r--engines/bladerunner/boundingbox.h4
-rw-r--r--engines/bladerunner/combat.cpp29
-rw-r--r--engines/bladerunner/combat.h6
-rw-r--r--engines/bladerunner/crimes_database.cpp12
-rw-r--r--engines/bladerunner/crimes_database.h8
-rw-r--r--engines/bladerunner/debugger.cpp10
-rw-r--r--engines/bladerunner/dialogue_menu.cpp54
-rw-r--r--engines/bladerunner/dialogue_menu.h11
-rw-r--r--engines/bladerunner/fog.cpp5
-rw-r--r--engines/bladerunner/fog.h3
-rw-r--r--engines/bladerunner/game_flags.cpp10
-rw-r--r--engines/bladerunner/game_flags.h6
-rw-r--r--engines/bladerunner/game_info.cpp66
-rw-r--r--engines/bladerunner/game_info.h18
-rw-r--r--engines/bladerunner/item.cpp62
-rw-r--r--engines/bladerunner/item.h10
-rw-r--r--engines/bladerunner/items.cpp44
-rw-r--r--engines/bladerunner/items.h11
-rw-r--r--engines/bladerunner/light.cpp4
-rw-r--r--engines/bladerunner/light.h3
-rw-r--r--engines/bladerunner/module.mk2
-rw-r--r--engines/bladerunner/movement_track.cpp34
-rw-r--r--engines/bladerunner/movement_track.h7
-rw-r--r--engines/bladerunner/music.cpp63
-rw-r--r--engines/bladerunner/music.h11
-rw-r--r--engines/bladerunner/obstacles.cpp62
-rw-r--r--engines/bladerunner/obstacles.h7
-rw-r--r--engines/bladerunner/overlays.cpp47
-rw-r--r--engines/bladerunner/overlays.h10
-rw-r--r--engines/bladerunner/police_maze.cpp64
-rw-r--r--engines/bladerunner/police_maze.h54
-rw-r--r--engines/bladerunner/police_maze_track.cpp80
-rw-r--r--engines/bladerunner/police_maze_track.h65
-rw-r--r--engines/bladerunner/regions.cpp19
-rw-r--r--engines/bladerunner/regions.h6
-rw-r--r--engines/bladerunner/savefile.cpp148
-rw-r--r--engines/bladerunner/savefile.h50
-rw-r--r--engines/bladerunner/scene.cpp48
-rw-r--r--engines/bladerunner/scene.h12
-rw-r--r--engines/bladerunner/scene_objects.cpp73
-rw-r--r--engines/bladerunner/scene_objects.h39
-rw-r--r--engines/bladerunner/script/ai_script.cpp7
-rw-r--r--engines/bladerunner/script/ai_script.h4
-rw-r--r--engines/bladerunner/script/police_maze.cpp68
-rw-r--r--engines/bladerunner/script/police_maze.h40
-rw-r--r--engines/bladerunner/script/script.cpp6
-rw-r--r--engines/bladerunner/script/script.h4
-rw-r--r--engines/bladerunner/set.cpp93
-rw-r--r--engines/bladerunner/set.h34
-rw-r--r--engines/bladerunner/set_effects.cpp8
-rw-r--r--engines/bladerunner/set_effects.h6
-rw-r--r--engines/bladerunner/settings.cpp48
-rw-r--r--engines/bladerunner/settings.h20
-rw-r--r--engines/bladerunner/text_resource.cpp6
-rw-r--r--engines/bladerunner/ui/elevator.cpp3
-rw-r--r--engines/bladerunner/ui/kia.cpp2
-rw-r--r--engines/bladerunner/ui/kia_log.cpp2
-rw-r--r--engines/bladerunner/ui/kia_log.h2
-rw-r--r--engines/bladerunner/ui/spinner.cpp10
-rw-r--r--engines/bladerunner/ui/spinner.h6
-rw-r--r--engines/bladerunner/ui/ui_scroll_box.cpp2
-rw-r--r--engines/bladerunner/waypoints.cpp20
-rw-r--r--engines/bladerunner/waypoints.h6
83 files changed, 1544 insertions, 1043 deletions
diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp
index aae1085834..998791d88a 100644
--- a/engines/bladerunner/actor.cpp
+++ b/engines/bladerunner/actor.cpp
@@ -52,7 +52,6 @@ Actor::Actor(BladeRunnerEngine *vm, int actorId) {
_walkInfo = new ActorWalk(vm);
_movementTrack = new MovementTrack();
_clues = new ActorClues(vm, (actorId && actorId != 99) ? 2 : 4);
- _bbox = new BoundingBox();
_combatInfo = new ActorCombat(vm);
_friendlinessToOther.resize(_vm->_gameInfo->getActorCount());
@@ -65,7 +64,6 @@ Actor::Actor(BladeRunnerEngine *vm, int actorId) {
Actor::~Actor() {
delete _combatInfo;
- delete _bbox;
delete _clues;
delete _movementTrack;
delete _walkInfo;
@@ -355,7 +353,7 @@ void Actor::setAtXYZ(const Vector3 &position, int facing, bool snapFacing, bool
_vm->_sceneObjects->remove(_id + kSceneObjectOffsetActors);
if (_vm->_scene->getSetId() == _setId) {
- _vm->_sceneObjects->addActor(_id + kSceneObjectOffsetActors, _bbox, &_screenRectangle, true, moving, _isTarget, retired);
+ _vm->_sceneObjects->addActor(_id + kSceneObjectOffsetActors, _bbox, _screenRectangle, true, moving, _isTarget, retired);
}
}
@@ -469,7 +467,7 @@ bool Actor::loopWalkToItem(int itemId, int destinationOffset, int interruptible,
return loopWalk(itemPosition, destinationOffset, interruptible, runFlag, _position, width, 24.0f, a5, isRunningFlag, false);
}
-bool Actor::loopWalkToSceneObject(const char *objectName, int destinationOffset, bool interruptible, bool runFlag, bool a5, bool *isRunningFlag) {
+bool Actor::loopWalkToSceneObject(const Common::String &objectName, int destinationOffset, bool interruptible, bool runFlag, bool a5, bool *isRunningFlag) {
int sceneObject = _vm->_scene->_set->findObject(objectName);
if (sceneObject < 0) {
return true;
@@ -760,21 +758,21 @@ void Actor::setFacing(int facing, bool halfOrSet) {
void Actor::setBoundingBox(const Vector3 &position, bool retired) {
if (retired) {
- _bbox->setXYZ(position.x - (_retiredWidth / 2.0f),
- position.y,
- position.z - (_retiredWidth / 2.0f),
+ _bbox.setXYZ(position.x - (_retiredWidth / 2.0f),
+ position.y,
+ position.z - (_retiredWidth / 2.0f),
- position.x + (_retiredWidth / 2.0f),
- position.y + _retiredHeight,
- position.z + (_retiredWidth / 2.0f));
+ position.x + (_retiredWidth / 2.0f),
+ position.y + _retiredHeight,
+ position.z + (_retiredWidth / 2.0f));
} else {
- _bbox->setXYZ(position.x - 12.0f,
- position.y + 6.0f,
- position.z - 12.0f,
+ _bbox.setXYZ(position.x - 12.0f,
+ position.y + 6.0f,
+ position.z - 12.0f,
- position.x + 12.0f,
- position.y + 72.0f,
- position.z + 12.0f);
+ position.x + 12.0f,
+ position.y + 72.0f,
+ position.z + 12.0f);
}
}
@@ -820,7 +818,7 @@ void Actor::faceActor(int otherActorId, bool animate) {
faceXYZ(otherActor->_position, animate);
}
-void Actor::faceObject(const char *objectName, bool animate) {
+void Actor::faceObject(const Common::String &objectName, bool animate) {
int objectId = _vm->_scene->findObject(objectName);
if (objectId == -1) {
return;
@@ -1066,13 +1064,10 @@ int Actor::getGoal() const {
}
void Actor::speechPlay(int sentenceId, bool voiceOver) {
- char name[13];
- sprintf(name, "%02d-%04d%s.AUD", _id, sentenceId, _vm->_languageCode);
- int balance;
+ Common::String name = Common::String::format( "%02d-%04d%s.AUD", _id, sentenceId, _vm->_languageCode.c_str());
- if (voiceOver || _id == BladeRunnerEngine::kActorVoiceOver) {
- balance = 0;
- } else {
+ int balance = 0;
+ if (!voiceOver && _id != BladeRunnerEngine::kActorVoiceOver) {
// Vector3 pos = _vm->_view->_frameViewMatrix * _position;
int screenX = 320; //, screenY = 0;
//TODO: transform to screen space using fov;
@@ -1226,66 +1221,66 @@ bool Actor::walkToNearestPoint(const Vector3 &destination, float distance) {
return false;
}
-void Actor::save(SaveFile &f) {
- f.write(_id);
- f.write(_setId);
- f.write(_position);
- f.write(_facing);
- f.write(_targetFacing);
- f.write(0); // TODO: _timer4RemainDefault
-
- f.write(_honesty);
- f.write(_intelligence);
- f.write(_stability);
- f.write(_combatAggressiveness);
- f.write(_goalNumber);
-
- f.write(_currentHP);
- f.write(_maxHP);
-
- f.write(_movementTrackPaused);
- f.write(_movementTrackNextWaypointId);
- f.write(_movementTrackNextDelay);
- f.write(_movementTrackNextAngle);
- f.write(_movementTrackNextRunning);
-
- f.write(0); // TODO: _clueType
- f.write(_isMoving);
- f.write(_isTarget);
- f.write(_inCombat);
- f.write(_isInvisible);
- f.write(_isRetired);
- f.write(_isImmuneToObstacles);
-
- f.write(_animationMode);
- f.write(_fps);
- f.write(_frameMs);
- f.write(_animationId);
- f.write(_animationFrame);
-
- f.write(_movementTrackWalkingToWaypointId);
- f.write(_movementTrackDelayOnNextWaypoint);
-
- f.write(_screenRectangle);
- f.write(_retiredWidth);
- f.write(_retiredHeight);
- f.write(_damageAnimIfMoving);
- f.write(0); // TODO: _actorFieldU6
- f.write(0); // TODO: _actorFieldU7
- f.write(_scale);
+void Actor::save(SaveFileWriteStream &f) {
+ f.writeInt(_id);
+ f.writeInt(_setId);
+ f.writeVector3(_position);
+ f.writeInt(_facing);
+ f.writeInt(_targetFacing);
+ f.writeInt(0); // TODO: _timer4RemainDefault
+
+ f.writeInt(_honesty);
+ f.writeInt(_intelligence);
+ f.writeInt(_stability);
+ f.writeInt(_combatAggressiveness);
+ f.writeInt(_goalNumber);
+
+ f.writeInt(_currentHP);
+ f.writeInt(_maxHP);
+
+ f.writeBool(_movementTrackPaused);
+ f.writeInt(_movementTrackNextWaypointId);
+ f.writeInt(_movementTrackNextDelay);
+ f.writeInt(_movementTrackNextAngle);
+ f.writeBool(_movementTrackNextRunning);
+
+ f.writeInt(0); // TODO: _clueType
+ f.writeBool(_isMoving);
+ f.writeBool(_isTarget);
+ f.writeBool(_inCombat);
+ f.writeBool(_isInvisible);
+ f.writeBool(_isRetired);
+ f.writeBool(_isImmuneToObstacles);
+
+ f.writeInt(_animationMode);
+ f.writeInt(_fps);
+ f.writeInt(_frameMs);
+ f.writeInt(_animationId);
+ f.writeInt(_animationFrame);
+
+ f.writeInt(_movementTrackWalkingToWaypointId);
+ f.writeInt(_movementTrackDelayOnNextWaypoint);
+
+ f.writeRect(_screenRectangle);
+ f.writeInt(_retiredWidth);
+ f.writeInt(_retiredHeight);
+ f.writeInt(_damageAnimIfMoving);
+ f.writeInt(0); // TODO: _actorFieldU6
+ f.writeInt(0); // TODO: _actorFieldU7
+ f.writeFloat(_scale);
for (int i = 0; i < 7; ++i) {
- f.write(_timersLeft[i]);
+ f.writeInt(_timersLeft[i]);
}
uint32 now = _vm->getTotalPlayTime(); // TODO: should be last lock time
for (int i = 0; i < 7; ++i) {
- f.write(_timersLast[i] - now);
+ f.writeInt(_timersLast[i] - now);
}
int actorCount = _vm->_gameInfo->getActorCount();
for (int i = 0; i != actorCount; ++i) {
- f.write(_friendlinessToOther[i]);
+ f.writeInt(_friendlinessToOther[i]);
}
_clues->save(f);
@@ -1294,12 +1289,89 @@ void Actor::save(SaveFile &f) {
_walkInfo->save(f);
- _bbox->save(f);
+ f.writeBoundingBox(_bbox);
_combatInfo->save(f);
- f.write(_animationModeCombatIdle);
- f.write(_animationModeCombatWalk);
- f.write(_animationModeCombatRun);
+ f.writeInt(_animationModeCombatIdle);
+ f.writeInt(_animationModeCombatWalk);
+ f.writeInt(_animationModeCombatRun);
+}
+
+void Actor::load(SaveFileReadStream &f) {
+ _id = f.readInt();
+ _setId = f.readInt();
+ _position = f.readVector3();
+ _facing = f.readInt();
+ _targetFacing = f.readInt();
+ f.skip(4); // TODO: _timer4RemainDefault
+
+ _honesty = f.readInt();
+ _intelligence = f.readInt();
+ _stability = f.readInt();
+ _combatAggressiveness = f.readInt();
+ _goalNumber = f.readInt();
+
+ _currentHP = f.readInt();
+ _maxHP = f.readInt();
+
+ _movementTrackPaused = f.readBool();
+ _movementTrackNextWaypointId = f.readInt();
+ _movementTrackNextDelay = f.readInt();
+ _movementTrackNextAngle = f.readInt();
+ _movementTrackNextRunning = f.readBool();
+
+ f.skip(4); // TODO: _clueType
+ _isMoving = f.readBool();
+ _isTarget = f.readBool();
+ _inCombat = f.readBool();
+ _isInvisible = f.readBool();
+ _isRetired = f.readBool();
+ _isImmuneToObstacles = f.readBool();
+
+ _animationMode = f.readInt();
+ _fps = f.readInt();
+ _frameMs = f.readInt();
+ _animationId = f.readInt();
+ _animationFrame = f.readInt();
+
+ _movementTrackWalkingToWaypointId = f.readInt();
+ _movementTrackDelayOnNextWaypoint = f.readInt();
+
+ _screenRectangle = f.readRect();
+ _retiredWidth = f.readInt();
+ _retiredHeight = f.readInt();
+ _damageAnimIfMoving = f.readInt();
+ f.skip(4); // TODO: _actorFieldU6
+ f.skip(4); // TODO: _actorFieldU7
+ _scale = f.readFloat();
+
+ for (int i = 0; i < 7; ++i) {
+ _timersLeft[i] = f.readInt();
+ }
+
+ uint32 now = _vm->getTotalPlayTime(); // TODO: should be last lock time
+ for (int i = 0; i < 7; ++i) {
+ _timersLast[i] = f.readInt() + now;
+ }
+
+ int actorCount = _vm->_gameInfo->getActorCount();
+ for (int i = 0; i != actorCount; ++i) {
+ _friendlinessToOther[i] = f.readInt();
+ }
+
+ _clues->load(f);
+
+ _movementTrack->load(f);
+
+ _walkInfo->load(f);
+
+ _bbox = f.readBoundingBox();
+
+ _combatInfo->load(f);
+
+ _animationModeCombatIdle = f.readInt();
+ _animationModeCombatWalk = f.readInt();
+ _animationModeCombatRun = f.readInt();
}
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/actor.h b/engines/bladerunner/actor.h
index 55ffc4f30e..7498d2bf51 100644
--- a/engines/bladerunner/actor.h
+++ b/engines/bladerunner/actor.h
@@ -23,6 +23,7 @@
#ifndef BLADERUNNER_ACTOR_H
#define BLADERUNNER_ACTOR_H
+#include "bladerunner/boundingbox.h"
#include "bladerunner/vector.h"
#include "common/array.h"
@@ -36,14 +37,15 @@ class ActorWalk;
class BladeRunnerEngine;
class BoundingBox;
class MovementTrack;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class View;
class Actor {
BladeRunnerEngine *_vm;
public:
- BoundingBox *_bbox;
+ BoundingBox _bbox;
Common::Rect _screenRectangle;
MovementTrack *_movementTrack;
ActorWalk *_walkInfo;
@@ -147,7 +149,7 @@ public:
bool walkTo(bool runFlag, const Vector3 &destination, bool a3);
bool loopWalkToActor(int otherActorId, int destinationOffset, int interruptible, bool runFlag, bool a5, bool *isRunningFlag);
bool loopWalkToItem(int itemId, int destinationOffset, int interruptible, bool runFlag, bool a5, bool *isRunningFlag);
- bool loopWalkToSceneObject(const char *objectName, int destinationOffset, bool interruptible, bool runFlag, bool a5, bool *isRunningFlag);
+ bool loopWalkToSceneObject(const Common::String &objectName, int destinationOffset, bool interruptible, bool runFlag, bool a5, bool *isRunningFlag);
bool loopWalkToWaypoint(int waypointId, int destinationOffset, int interruptible, bool runFlag, bool a5, bool *isRunningFlag);
bool loopWalkToXYZ(const Vector3 &destination, int destinationOffset, bool interruptible, bool runFlag, bool a5, bool *isRunningFlag);
bool asyncWalkToWaypoint(int waypointId, int destinationOffset, bool runFlag, bool a5);
@@ -160,8 +162,8 @@ public:
int getSetId() const;
void setSetId(int setId);
- BoundingBox *getBoundingBox() const { return _bbox; }
- Common::Rect *getScreenRectangle() { return &_screenRectangle; }
+ const BoundingBox &getBoundingBox() const { return _bbox; }
+ const Common::Rect &getScreenRectangle() { return _screenRectangle; }
int getWalkbox() const { return _walkboxId; }
bool isRetired() const { return _isRetired; }
@@ -179,7 +181,7 @@ public:
void stopWalking(bool value);
void faceActor(int otherActorId, bool animate);
- void faceObject(const char *objectName, bool animate);
+ void faceObject(const Common::String &objectName, bool animate);
void faceItem(int itemId, bool animate);
void faceWaypoint(int waypointId, bool animate);
void faceXYZ(float x, float y, float z, bool animate);
@@ -247,6 +249,9 @@ public:
bool isObstacleBetween(const Vector3 &target);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
+
static int findTargetUnderMouse(BladeRunnerEngine *vm, int mouseX, int mouseY);
private:
@@ -257,9 +262,6 @@ private:
bool walkFindU2(Vector3 *newDestination, float targetWidth, int destinationOffset, float targetSize, const Vector3 &startPosition, const Vector3 &targetPosition);
bool walkToNearestPoint(const Vector3 &destination, float distance);
//bool walkFindU3(int actorId, Vector3 from, int distance, Vector3 *out);
-
-public:
- void save(SaveFile &f);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/actor_clues.cpp b/engines/bladerunner/actor_clues.cpp
index 89db6feb47..0c25ffc19f 100644
--- a/engines/bladerunner/actor_clues.cpp
+++ b/engines/bladerunner/actor_clues.cpp
@@ -217,21 +217,41 @@ void ActorClues::remove(int index) {
_clues[index].field8 = 0;
}
-void ActorClues::save(SaveFile &f) {
- f.write(_count);
- f.write(_maxCount);
+void ActorClues::save(SaveFileWriteStream &f) {
+ f.writeInt(_count);
+ f.writeInt(_maxCount);
for (int i = 0; i < _count; ++i) {
Clue &c = _clues[i];
- f.write(c.clueId);
- f.write(c.weight);
- f.write(c.fromActorId);
- f.write(c.field3);
- f.write(c.field4);
- f.write(c.field5);
- f.write(c.field6);
- f.write(c.field7);
- f.write(c.field8);
- f.write(c.flags);
+ f.writeInt(c.clueId);
+ f.writeInt(c.weight);
+ f.writeInt(c.fromActorId);
+ f.writeInt(c.field3);
+ f.writeInt(c.field4);
+ f.writeInt(c.field5);
+ f.writeInt(c.field6);
+ f.writeInt(c.field7);
+ f.writeInt(c.field8);
+ f.writeByte(c.flags);
+ }
+}
+
+void ActorClues::load(SaveFileReadStream &f) {
+ _count = f.readInt();
+ _maxCount = f.readInt();
+ _clues.clear();
+ _clues.resize(_maxCount);
+ for (int i = 0; i < _count; ++i) {
+ Clue &c = _clues[i];
+ c.clueId = f.readInt();
+ c.weight = f.readInt();
+ c.fromActorId = f.readInt();
+ c.field3 = f.readInt();
+ c.field4 = f.readInt();
+ c.field5 = f.readInt();
+ c.field6 = f.readInt();
+ c.field7 = f.readInt();
+ c.field8 = f.readInt();
+ c.flags = f.readByte();
}
}
diff --git a/engines/bladerunner/actor_clues.h b/engines/bladerunner/actor_clues.h
index 03ccff20fd..79181cc20c 100644
--- a/engines/bladerunner/actor_clues.h
+++ b/engines/bladerunner/actor_clues.h
@@ -28,7 +28,8 @@
namespace BladeRunner {
class BladeRunnerEngine;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class ActorClues {
struct Clue {
@@ -41,7 +42,7 @@ class ActorClues {
int field6;
int field7;
int field8;
- unsigned char flags;
+ byte flags;
};
BladeRunnerEngine *_vm;
@@ -75,8 +76,8 @@ public:
void removeAll();
- void save(SaveFile &f);
- //loadgame
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
private:
bool exists(int clueId) const;
diff --git a/engines/bladerunner/actor_combat.cpp b/engines/bladerunner/actor_combat.cpp
index 7a60d6d85a..4bcce5d3bf 100644
--- a/engines/bladerunner/actor_combat.cpp
+++ b/engines/bladerunner/actor_combat.cpp
@@ -50,31 +50,6 @@ void ActorCombat::setup() {
reset();
}
-void ActorCombat::save(SaveFile &f) {
- // TODO
- f.write(0); // _actorId
- f.write(0); // _combatOn
- f.write(0); // _field2
- f.write(0); // _field3
- f.write(0); // _otherActorId
- f.write(0); // _field5
- f.write(0); // _field6
- f.write(0); // _field7
- f.write(0); // _field8
- f.write(0); // _field9
- f.write(0); // _field10
- f.write(0); // _field11
- f.write(0); // _field12
- f.write(0); // _actorHp
- f.write(0); // _field14
- f.write(0); // _field15
- f.write(0); // _actorPosition
- f.write(0); // _otherActorPosition
- f.write(0); // _availableCoversCount
- f.write(0); // _availableFleeWaypointsCount
- f.write(0); // _field24
-}
-
void ActorCombat::combatOn(int actorId, int initialState, bool rangedAttackFlag, int enemyId, int waypointType, int fleeRatio, int coverRatio, int actionRatio, int damage, int range, bool unstoppable) {
_actorId = actorId;
_state = initialState;
@@ -316,11 +291,59 @@ void ActorCombat::hitAttempt() {
}
}
+void ActorCombat::save(SaveFileWriteStream &f) {
+ f.writeInt(_actorId);
+ f.writeBool(_active);
+ f.writeInt(_state);
+ f.writeBool(_rangedAttack);
+ f.writeInt(_enemyId);
+ f.writeInt(_waypointType);
+ f.writeInt(_damage);
+ f.writeInt(_fleeRatio);
+ f.writeInt(_coverRatio);
+ f.writeInt(_actionRatio);
+ f.writeInt(_fleeRatioConst);
+ f.writeInt(_coverRatioConst);
+ f.writeInt(_actionRatioConst);
+ f.writeInt(_range);
+ f.writeInt(_unstoppable);
+ f.writeInt(_actorHp);
+ f.writeInt(_fleeingTowards);
+ f.writeVector3(_actorPosition);
+ f.writeVector3(_enemyPosition);
+ f.writeInt(_coversWaypointCount);
+ f.writeInt(_fleeWaypointsCount);
+}
+
+void ActorCombat::load(SaveFileReadStream &f) {
+ _actorId = f.readInt();
+ _active = f.readBool();
+ _state = f.readInt();
+ _rangedAttack = f.readBool();
+ _enemyId = f.readInt();
+ _waypointType = f.readInt();
+ _damage = f.readInt();
+ _fleeRatio = f.readInt();
+ _coverRatio = f.readInt();
+ _actionRatio = f.readInt();
+ _fleeRatioConst = f.readInt();
+ _coverRatioConst = f.readInt();
+ _actionRatioConst = f.readInt();
+ _range = f.readInt();
+ _unstoppable = f.readInt();
+ _actorHp = f.readInt();
+ _fleeingTowards = f.readInt();
+ _actorPosition = f.readVector3();
+ _enemyPosition = f.readVector3();
+ _coversWaypointCount = f.readInt();
+ _fleeWaypointsCount = f.readInt();
+}
+
void ActorCombat::reset() {
_active = false;
_actorId = -1;
_state = -1;
- _rangedAttack = -1;
+ _rangedAttack = false;
_enemyId = -1;
_waypointType = -1;
_damage = 0;
diff --git a/engines/bladerunner/actor_combat.h b/engines/bladerunner/actor_combat.h
index a621c3d6ff..2f65f1904d 100644
--- a/engines/bladerunner/actor_combat.h
+++ b/engines/bladerunner/actor_combat.h
@@ -28,7 +28,8 @@
namespace BladeRunner {
class BladeRunnerEngine;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class ActorCombat {
BladeRunnerEngine *_vm;
@@ -36,7 +37,7 @@ class ActorCombat {
int _actorId;
bool _active;
int _state;
- int _rangedAttack;
+ bool _rangedAttack;
int _enemyId;
int _waypointType;
int _damage;
@@ -66,10 +67,11 @@ public:
void tick();
- void save(SaveFile &f);
-
void hitAttempt();
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
+
private:
void reset();
diff --git a/engines/bladerunner/actor_dialogue_queue.cpp b/engines/bladerunner/actor_dialogue_queue.cpp
index 5f0ad60426..48fcf8a6ab 100644
--- a/engines/bladerunner/actor_dialogue_queue.cpp
+++ b/engines/bladerunner/actor_dialogue_queue.cpp
@@ -54,7 +54,7 @@ void ActorDialogueQueue::add(int actorId, int sentenceId, int animationMode) {
if (actorId == 0 || actorId == BladeRunnerEngine::kActorVoiceOver) {
animationMode = -1;
}
- if (_entries.size() < 25) {
+ if (_entries.size() < kMaxEntries) {
Entry entry;
entry.isNotPause = true;
entry.isPause = false;
@@ -68,7 +68,7 @@ void ActorDialogueQueue::add(int actorId, int sentenceId, int animationMode) {
}
void ActorDialogueQueue::addPause(int delay) {
- if (_entries.size() < 25) {
+ if (_entries.size() < kMaxEntries) {
Entry entry;
entry.isNotPause = false;
entry.isPause = true;
@@ -160,30 +160,58 @@ void ActorDialogueQueue::tick() {
}
}
-void ActorDialogueQueue::save(SaveFile &f) {
+void ActorDialogueQueue::save(SaveFileWriteStream &f) {
int count = (int)_entries.size();
- f.write(count);
+ f.writeInt(count);
for (int i = 0; i < count; ++i) {
Entry &e = _entries[i];
- f.write(e.isNotPause);
- f.write(e.isPause);
- f.write(e.actorId);
- f.write(e.sentenceId);
- f.write(e.animationMode);
- f.write(e.delay);
+ f.writeBool(e.isNotPause);
+ f.writeBool(e.isPause);
+ f.writeInt(e.actorId);
+ f.writeInt(e.sentenceId);
+ f.writeInt(e.animationMode);
+ f.writeInt(e.delay);
}
- f.padBytes((25 - count) * 24);
-
- f.write(_isNotPause);
- f.write(_actorId);
- f.write(_sentenceId);
- f.write(_animationMode);
- f.write(_animationModePrevious);
- f.write(_isPause);
- f.write(_delay);
+ f.padBytes((kMaxEntries - count) * 24);
+
+ f.writeBool(_isNotPause);
+ f.writeInt(_actorId);
+ f.writeInt(_sentenceId);
+ f.writeInt(_animationMode);
+ f.writeInt(_animationModePrevious);
+ f.writeBool(_isPause);
+ f.writeInt(_delay);
// f.write(_timeLast);
}
+void ActorDialogueQueue::load(SaveFileReadStream &f) {
+ _entries.clear();
+ int count = f.readInt();
+ assert(count <= kMaxEntries);
+ _entries.resize(count);
+ for (int i = 0; i < count; ++i) {
+ Entry &e = _entries[i];
+ e.isNotPause = f.readBool();
+ e.isPause = f.readBool();
+ e.actorId = f.readInt();
+ e.sentenceId = f.readInt();
+ e.animationMode = f.readInt();
+ e.delay = f.readInt();
+ }
+
+ f.skip((kMaxEntries - count) * 24);
+
+ _isNotPause = f.readBool();
+ _actorId = f.readInt();
+ _sentenceId = f.readInt();
+ _animationMode = f.readInt();
+ _animationModePrevious = f.readInt();
+ _isPause = f.readBool();
+ _delay = f.readInt();
+
+ _timeLast = 0;
+}
+
void ActorDialogueQueue::clear() {
_entries.clear();
_isNotPause = false;
diff --git a/engines/bladerunner/actor_dialogue_queue.h b/engines/bladerunner/actor_dialogue_queue.h
index e26b6cf1a1..832bcc9dab 100644
--- a/engines/bladerunner/actor_dialogue_queue.h
+++ b/engines/bladerunner/actor_dialogue_queue.h
@@ -28,9 +28,12 @@
namespace BladeRunner {
class BladeRunnerEngine;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class ActorDialogueQueue {
+ static const int kMaxEntries = 25;
+
struct Entry {
bool isNotPause;
bool isPause;
@@ -63,7 +66,8 @@ public:
void flush(int a1, bool callScript);
void tick();
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
private:
void clear();
diff --git a/engines/bladerunner/actor_walk.cpp b/engines/bladerunner/actor_walk.cpp
index d376e36785..b4587333a1 100644
--- a/engines/bladerunner/actor_walk.cpp
+++ b/engines/bladerunner/actor_walk.cpp
@@ -239,25 +239,51 @@ void ActorWalk::run(int actorId) {
_vm->_actors[actorId]->changeAnimationMode(animationMode, false);
}
-void ActorWalk::save(SaveFile &f) {
- f.write(_walking);
- f.write(_running);
- f.write(_destination);
+void ActorWalk::save(SaveFileWriteStream &f) {
+ f.writeInt(_walking);
+ f.writeInt(_running);
+ f.writeVector3(_destination);
// _originalDestination is not saved
- f.write(_current);
- f.write(_next);
- f.write(_facing);
+ f.writeVector3(_current);
+ f.writeVector3(_next);
+ f.writeInt(_facing);
assert(_nearActors.size() <= 20);
for (Common::HashMap<int, bool>::const_iterator it = _nearActors.begin(); it != _nearActors.end(); ++it) {
- f.write(it->_key);
- f.write(it->_value);
+ f.writeInt(it->_key);
+ f.writeBool(it->_value);
}
f.padBytes(8 * (20 - _nearActors.size()));
- f.write((int)_nearActors.size());
+ f.writeInt(_nearActors.size());
- f.write(0); // _notUsed
- f.write(_status);
+ f.writeInt(0); // _notUsed
+ f.writeInt(_status);
+}
+
+void ActorWalk::load(SaveFileReadStream &f) {
+ _walking = f.readInt();
+ _running = f.readInt();
+ _destination = f.readVector3();
+ // _originalDestination is not saved
+ _current = f.readVector3();
+ _next = f.readVector3();
+ _facing = f.readInt();
+
+ int actorId[20];
+ bool isNear[20];
+
+ for (int i = 0; i < 20; ++i) {
+ actorId[i] = f.readInt();
+ isNear[i] = f.readBool();
+ }
+
+ int count = f.readInt();
+ for (int i = 0; i < count; ++i) {
+ _nearActors.setVal(actorId[i], isNear[i]);
+ }
+
+ f.skip(4); // _notUsed
+ _status = f.readInt();
}
bool ActorWalk::isXYZEmpty(float x, float y, float z, int actorId) const {
diff --git a/engines/bladerunner/actor_walk.h b/engines/bladerunner/actor_walk.h
index 265421458f..45298e2794 100644
--- a/engines/bladerunner/actor_walk.h
+++ b/engines/bladerunner/actor_walk.h
@@ -29,7 +29,8 @@
namespace BladeRunner {
class BladeRunnerEngine;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class ActorWalk {
BladeRunnerEngine *_vm;
@@ -61,7 +62,9 @@ public:
void stop(int actorId, bool immediately, int combatAnimationMode, int animationMode);
void run(int actorId);
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
+
private:
int nextOnPath(int actorId, const Vector3 &from, const Vector3 &to, Vector3 &next) const;
diff --git a/engines/bladerunner/ambient_sounds.cpp b/engines/bladerunner/ambient_sounds.cpp
index 6477f27c8e..81b6174ab9 100644
--- a/engines/bladerunner/ambient_sounds.cpp
+++ b/engines/bladerunner/ambient_sounds.cpp
@@ -69,25 +69,23 @@ void AmbientSounds::addSound(
int panStartMin, int panStartMax,
int panEndMin, int panEndMax,
int priority, int unk) {
- const char *name = _vm->_gameInfo->getSfxTrack(sfxId);
sort(volumeMin, volumeMax);
sort(panStartMin, panStartMax);
sort(panEndMin, panEndMax);
addSoundByName(
- name,
- timeMin, timeMax,
- volumeMin, volumeMax,
- panStartMin, panStartMax,
- panEndMin, panEndMax,
- priority, unk
+ _vm->_gameInfo->getSfxTrack(sfxId),
+ timeMin, timeMax,
+ volumeMin, volumeMax,
+ panStartMin, panStartMax,
+ panEndMin, panEndMax,
+ priority, unk
);
}
void AmbientSounds::removeNonLoopingSound(int sfxId, bool stopPlaying) {
- const char *name = _vm->_gameInfo->getSfxTrack(sfxId);
- int32 hash = mix_id(name);
+ int32 hash = MIXArchive::getHash(_vm->_gameInfo->getSfxTrack(sfxId));
int index = findNonLoopingTrackByHash(hash);
if (index >= 0) {
removeNonLoopingSoundByIndex(index, stopPlaying);
@@ -105,8 +103,7 @@ void AmbientSounds::addSpeech(int actorId, int sentenceId, int timeMin, int time
sort(panStartMin, panStartMax);
sort(panEndMin, panEndMax);
- char name[13];
- sprintf(name, "%02d-%04d%s.AUD", actorId, sentenceId, _vm->_languageCode);
+ Common::String name = Common::String::format( "%02d-%04d%s.AUD", actorId, sentenceId, _vm->_languageCode.c_str());
addSoundByName(name,
timeMin, timeMax,
volumeMin, volumeMax,
@@ -116,15 +113,12 @@ void AmbientSounds::addSpeech(int actorId, int sentenceId, int timeMin, int time
}
void AmbientSounds::playSound(int sfxId, int volume, int panStart, int panEnd, int priority) {
- const char *name = _vm->_gameInfo->getSfxTrack(sfxId);
-
- _vm->_audioPlayer->playAud(name, volume * _ambientVolume / 100, panStart, panEnd, priority, kAudioPlayerOverrideVolume);
+ _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(sfxId), volume * _ambientVolume / 100, panStart, panEnd, priority, kAudioPlayerOverrideVolume);
}
void AmbientSounds::addLoopingSound(int sfxId, int volume, int pan, int delay) {
- const char *name = _vm->_gameInfo->getSfxTrack(sfxId);
-
- int32 hash = mix_id(name);
+ const Common::String &name = _vm->_gameInfo->getSfxTrack(sfxId);
+ int32 hash = MIXArchive::getHash(name);
if (findLoopingTrackByHash(hash) >= 0) {
return;
@@ -137,8 +131,7 @@ void AmbientSounds::addLoopingSound(int sfxId, int volume, int pan, int delay) {
LoopingSound &track = _loopingSounds[i];
track.isActive = true;
- strncpy(track.name, name, sizeof(track.name));
- track.name[sizeof(track.name) - 1] = 0;
+ track.name = name;
track.hash = hash;
track.pan = pan;
track.volume = volume;
@@ -162,8 +155,7 @@ void AmbientSounds::addLoopingSound(int sfxId, int volume, int pan, int delay) {
}
void AmbientSounds::adjustLoopingSound(int sfxId, int volume, int pan, int delay) {
- const char *name = _vm->_gameInfo->getSfxTrack(sfxId);
- int32 hash = mix_id(name);
+ int32 hash = MIXArchive::getHash(_vm->_gameInfo->getSfxTrack(sfxId));
int index = findLoopingTrackByHash(hash);
if (index >= 0 && _loopingSounds[index].audioPlayerTrack != -1 && _vm->_audioPlayer->isActive(_loopingSounds[index].audioPlayerTrack)) {
@@ -179,8 +171,7 @@ void AmbientSounds::adjustLoopingSound(int sfxId, int volume, int pan, int delay
}
void AmbientSounds::removeLoopingSound(int sfxId, int delay) {
- const char *name = _vm->_gameInfo->getSfxTrack(sfxId);
- int32 hash = mix_id(name);
+ int32 hash = MIXArchive::getHash(_vm->_gameInfo->getSfxTrack(sfxId));
int index = findLoopingTrackByHash(hash);
if (index >= 0) {
removeLoopingSoundByIndex(index, delay);
@@ -298,15 +289,12 @@ int AmbientSounds::findLoopingTrackByHash(int32 hash) const {
}
void AmbientSounds::addSoundByName(
- const char *name,
+ const Common::String &name,
int timeMin, int timeMax,
int volumeMin, int volumeMax,
int panStartMin, int panStartMax,
int panEndMin, int panEndMax,
int priority, int unk) {
- if (strlen(name) > 12) {
- error("AmbientSounds::addSoundByName: Overlong name '%s'", name);
- }
int i = findAvailableNonLoopingTrack();
if (i < 0) {
@@ -318,9 +306,8 @@ void AmbientSounds::addSoundByName(
uint32 now = _vm->getTotalPlayTime();
track.isActive = true;
- strncpy(track.name, name, sizeof(track.name));
- track.name[sizeof(track.name) - 1] = 0;
- track.hash = mix_id(name);
+ track.name = name;
+ track.hash = MIXArchive::getHash(name);
track.timeMin = 1000 * timeMin;
track.timeMax = 1000 * timeMax;
track.nextPlayTime = now + _vm->_rnd.getRandomNumberRng(track.timeMin, track.timeMax);
@@ -356,46 +343,82 @@ void AmbientSounds::removeLoopingSoundByIndex(int index, int delay) {
}
}
track.isActive = false;
- track.name[0] = 0;
+ track.name.clear();
track.hash = 0;
track.audioPlayerTrack = -1;
track.volume = 0;
track.pan = 0;
}
-void AmbientSounds::save(SaveFile &f) {
- f.write(false); // TODO: _isDisabled
+void AmbientSounds::save(SaveFileWriteStream &f) {
+ f.writeBool(false); // TODO: _isDisabled
for (int i = 0; i != kNonLoopingSounds; ++i) {
// 73 bytes per non-looping sound
NonLoopingSound &s = _nonLoopingSounds[i];
- f.write(s.isActive);
- f.write(s.name, 13);
- f.write(s.hash);
- f.write(s.audioPlayerTrack);
- f.write(s.timeMin);
- f.write(s.timeMax);
- f.write(s.nextPlayTime);
- f.write(s.volumeMin);
- f.write(s.volumeMax);
- f.write(s.volume);
- f.write(s.panStartMin);
- f.write(s.panStartMax);
- f.write(s.panEndMin);
- f.write(s.panEndMax);
- f.write(s.priority);
+ f.writeBool(s.isActive);
+ f.writeStringSz(s.name, 13);
+ f.writeSint32LE(s.hash);
+ f.writeInt(s.audioPlayerTrack);
+ f.writeInt(s.timeMin);
+ f.writeInt(s.timeMax);
+ f.writeUint32LE(s.nextPlayTime);
+ f.writeInt(s.volumeMin);
+ f.writeInt(s.volumeMax);
+ f.writeInt(s.volume);
+ f.writeInt(s.panStartMin);
+ f.writeInt(s.panStartMax);
+ f.writeInt(s.panEndMin);
+ f.writeInt(s.panEndMax);
+ f.writeInt(s.priority);
f.padBytes(4); // field_45
}
for (int i = 0; i != kLoopingSounds; ++i) {
// 33 bytes per looping sound
LoopingSound &s = _loopingSounds[i];
- f.write(s.isActive);
- f.write(s.name, 13);
- f.write(s.hash);
- f.write(s.audioPlayerTrack);
- f.write(s.volume);
- f.write(s.pan);
+ f.writeBool(s.isActive);
+ f.writeStringSz(s.name, 13);
+ f.writeSint32LE(s.hash);
+ f.writeInt(s.audioPlayerTrack);
+ f.writeInt(s.volume);
+ f.writeInt(s.pan);
+ }
+}
+
+void AmbientSounds::load(SaveFileReadStream &f) {
+ f.skip(4); // TODO: _isDisabled
+
+ for (int i = 0; i != kNonLoopingSounds; ++i) {
+ // 73 bytes per non-looping sound
+ NonLoopingSound &s = _nonLoopingSounds[i];
+ s.isActive = f.readBool();
+ s.name = f.readStringSz(13);
+ s.hash = f.readSint32LE();
+ s.audioPlayerTrack = f.readInt();
+ s.timeMin = f.readInt();
+ s.timeMax = f.readInt();
+ s.nextPlayTime = f.readUint32LE();
+ s.volumeMin = f.readInt();
+ s.volumeMax = f.readInt();
+ s.volume = f.readInt();
+ s.panStartMin = f.readInt();
+ s.panStartMax = f.readInt();
+ s.panEndMin = f.readInt();
+ s.panEndMax = f.readInt();
+ s.priority = f.readInt();
+ f.skip(4); // field_45
+ }
+
+ for (int i = 0; i != kLoopingSounds; ++i) {
+ // 33 bytes per looping sound
+ LoopingSound &s = _loopingSounds[i];
+ s.isActive = f.readBool();
+ s.name = f.readStringSz(13);
+ s.hash = f.readSint32LE();
+ s.audioPlayerTrack = f.readInt();
+ s.volume = f.readInt();
+ s.pan = f.readInt();
}
}
diff --git a/engines/bladerunner/ambient_sounds.h b/engines/bladerunner/ambient_sounds.h
index 6e14c56cec..de08965a11 100644
--- a/engines/bladerunner/ambient_sounds.h
+++ b/engines/bladerunner/ambient_sounds.h
@@ -25,40 +25,43 @@
#include "audio/audiostream.h"
+#include "common/str.h"
+
namespace BladeRunner {
class BladeRunnerEngine;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class AmbientSounds {
static const int kNonLoopingSounds = 25;
static const int kLoopingSounds = 3;
struct NonLoopingSound {
- bool isActive;
- char name[13];
- int32 hash;
- int32 audioPlayerTrack;
- int32 timeMin;
- int32 timeMax;
- uint32 nextPlayTime;
- int32 volumeMin;
- int32 volumeMax;
- int32 volume;
- int32 panStartMin;
- int32 panStartMax;
- int32 panEndMin;
- int32 panEndMax;
- int32 priority;
+ bool isActive;
+ Common::String name;
+ int32 hash;
+ int audioPlayerTrack;
+ int timeMin;
+ int timeMax;
+ uint32 nextPlayTime;
+ int volumeMin;
+ int volumeMax;
+ int volume;
+ int panStartMin;
+ int panStartMax;
+ int panEndMin;
+ int panEndMax;
+ int priority;
};
struct LoopingSound {
- bool isActive;
- char name[13];
- int32 hash;
- int audioPlayerTrack;
- int32 volume;
- int pan;
+ bool isActive;
+ Common::String name;
+ int32 hash;
+ int audioPlayerTrack;
+ int volume;
+ int pan;
};
BladeRunnerEngine *_vm;
@@ -104,7 +107,8 @@ public:
int getVolume() const;
void playSample();
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
private:
int findAvailableNonLoopingTrack() const;
@@ -122,7 +126,7 @@ private:
// playVolumeAdjustSound
void addSoundByName(
- const char *name,
+ const Common::String &name,
int timeMin, int timeMax,
int volumeMin, int volumeMax,
int panStartMin, int panStartMax,
diff --git a/engines/bladerunner/archive.cpp b/engines/bladerunner/archive.cpp
index 8088e1ac67..c116eeb94f 100644
--- a/engines/bladerunner/archive.cpp
+++ b/engines/bladerunner/archive.cpp
@@ -51,7 +51,7 @@ bool MIXArchive::open(const Common::String &filename) {
_entries.resize(_entryCount);
for (uint16 i = 0; i != _entryCount; ++i) {
- _entries[i].id = _fd.readSint32LE();
+ _entries[i].hash = _fd.readUint32LE();
_entries[i].offset = _fd.readUint32LE();
_entries[i].length = _fd.readUint32LE();
@@ -61,7 +61,7 @@ bool MIXArchive::open(const Common::String &filename) {
// Verify that the entries are sorted by id. Note that id is signed.
if (i > 0) {
- assert(_entries[i].id > _entries[i - 1].id);
+ assert(_entries[i].hash > _entries[i - 1].hash);
}
}
@@ -86,7 +86,7 @@ bool MIXArchive::isOpen() const {
#define ROL(n) ((n << 1) | ((n >> 31) & 1))
-int32 mix_id(const Common::String &name) {
+int32 MIXArchive::getHash(const Common::String &name) {
char buffer[12] = { 0 };
for (uint i = 0; i != name.size() && i < 12u; ++i) {
@@ -103,11 +103,10 @@ int32 mix_id(const Common::String &name) {
id = ROL(id) + t;
}
- return reinterpret_cast<int32&>(id);
+ return id;
}
-static
-int32 tlk_id(const Common::String &name) {
+static uint32 tlk_id(const Common::String &name) {
char buffer[12] = { 0 };
for (uint i = 0; i != name.size() && i < 12u; ++i)
@@ -124,15 +123,15 @@ int32 tlk_id(const Common::String &name) {
return 10000 * actor_id + speech_id;
}
-uint32 MIXArchive::indexForId(int32 id) const {
+uint32 MIXArchive::indexForHash(int32 hash) const {
uint32 lo = 0, hi = _entryCount;
while (lo < hi) {
uint32 mid = lo + (hi - lo) / 2;
- if (id > _entries[mid].id) {
+ if (hash > _entries[mid].hash) {
lo = mid + 1;
- } else if (id < _entries[mid].id) {
+ } else if (hash < _entries[mid].hash) {
hi = mid;
} else {
return mid;
@@ -142,14 +141,15 @@ uint32 MIXArchive::indexForId(int32 id) const {
}
Common::SeekableReadStream *MIXArchive::createReadStreamForMember(const Common::String &name) {
- int32 id;
+ int32 hash;
- if (_isTLK)
- id = tlk_id(name);
- else
- id = mix_id(name);
+ if (_isTLK) {
+ hash = tlk_id(name);
+ } else {
+ hash = MIXArchive::getHash(name);
+ }
- uint32 i = indexForId(id);
+ uint32 i = indexForHash(hash);
if (i == _entryCount) {
return nullptr;
diff --git a/engines/bladerunner/archive.h b/engines/bladerunner/archive.h
index 7bec41f97a..9f7c67920d 100644
--- a/engines/bladerunner/archive.h
+++ b/engines/bladerunner/archive.h
@@ -34,6 +34,8 @@ public:
MIXArchive();
~MIXArchive();
+ static int32 getHash(const Common::String &name);
+
bool open(const Common::String &filename);
void close();
bool isOpen() const;
@@ -50,17 +52,16 @@ private:
uint32 _size;
struct ArchiveEntry {
- int32 id;
+ int32 hash;
uint32 offset;
uint32 length;
};
Common::Array<ArchiveEntry> _entries;
- uint32 indexForId(int32 id) const;
+ uint32 indexForHash(int32 hash) const;
};
-int32 mix_id(const Common::String &name);
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/audio_player.cpp b/engines/bladerunner/audio_player.cpp
index e1ef0263b6..5186888dd2 100644
--- a/engines/bladerunner/audio_player.cpp
+++ b/engines/bladerunner/audio_player.cpp
@@ -253,7 +253,7 @@ int AudioPlayer::playAud(const Common::String &name, int volume, int panFrom, in
}
/* Load audio resource and store in cache. Playback will happen directly from there. */
- int32 hash = mix_id(name);
+ int32 hash = MIXArchive::getHash(name);
if (!_cache->findByHash(hash)) {
Common::SeekableReadStream *r = _vm->getResourceStream(name);
if (!r) {
diff --git a/engines/bladerunner/audio_speech.cpp b/engines/bladerunner/audio_speech.cpp
index 69883cbce2..87f73737d4 100644
--- a/engines/bladerunner/audio_speech.cpp
+++ b/engines/bladerunner/audio_speech.cpp
@@ -58,12 +58,12 @@ AudioSpeech::~AudioSpeech() {
delete[] _data;
}
-bool AudioSpeech::playSpeech(const char *name, int pan) {
+bool AudioSpeech::playSpeech(const Common::String &name, int pan) {
// debug("AudioSpeech::playSpeech(\"%s\")", name);
Common::ScopedPtr<Common::SeekableReadStream> r(_vm->getResourceStream(name));
if (!r) {
- warning("AudioSpeech::playSpeech: AUD resource \"%s\" not found", name);
+ warning("AudioSpeech::playSpeech: AUD resource \"%s\" not found", name.c_str());
return false;
}
@@ -78,7 +78,7 @@ bool AudioSpeech::playSpeech(const char *name, int pan) {
r->read(_data, r->size());
if (r->err()) {
- warning("AudioSpeech::playSpeech: Error reading resource \"%s\"", name);
+ warning("AudioSpeech::playSpeech: Error reading resource \"%s\"", name.c_str());
return false;
}
@@ -117,7 +117,7 @@ bool AudioSpeech::isPlaying() const {
bool AudioSpeech::playSpeechLine(int actorId, int sentenceId, int volume, int a4, int priority) {
int balance = _vm->_actors[actorId]->soundBalance();
- Common::String name = Common::String::format("%02d-%04d%s.AUD", actorId, sentenceId, _vm->_languageCode);
+ Common::String name = Common::String::format("%02d-%04d%s.AUD", actorId, sentenceId, _vm->_languageCode.c_str());
return _vm->_audioPlayer->playAud(name, _speechVolume * volume / 100, balance, balance, priority, kAudioPlayerOverrideVolume);
}
diff --git a/engines/bladerunner/audio_speech.h b/engines/bladerunner/audio_speech.h
index 010499f480..5406f1d8e5 100644
--- a/engines/bladerunner/audio_speech.h
+++ b/engines/bladerunner/audio_speech.h
@@ -23,6 +23,7 @@
#ifndef BLADERUNNER_AUDIO_SPEECH_H
#define BLADERUNNER_AUDIO_SPEECH_H
+#include "common/str.h"
#include "common/types.h"
namespace BladeRunner {
@@ -44,7 +45,7 @@ public:
AudioSpeech(BladeRunnerEngine *vm);
~AudioSpeech();
- bool playSpeech(const char *name, int balance = 0);
+ bool playSpeech(const Common::String &name, int balance = 0);
void stopSpeech();
bool isPlaying() const;
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index 805461ce3c..f481accfbd 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -45,7 +45,6 @@
#include "bladerunner/outtake.h"
#include "bladerunner/obstacles.h"
#include "bladerunner/overlays.h"
-#include "bladerunner/police_maze.h"
#include "bladerunner/regions.h"
#include "bladerunner/savefile.h"
#include "bladerunner/scene.h"
@@ -356,8 +355,6 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
// TODO: Set actor ids (redundant?)
_policeMaze = new PoliceMaze(this);
- if (!_policeMaze->init())
- return false;
_textActorNames = new TextResource(this);
if (!_textActorNames->open("ACTORS"))
@@ -827,8 +824,7 @@ void BladeRunnerEngine::gameTick() {
// TODO: Process AUD
if (_walkSoundId >= 0) {
- const char *name = _gameInfo->getSfxTrack(_walkSoundId);
- _audioPlayer->playAud(name, _walkSoundVolume, _walkSoundBalance, _walkSoundBalance, 50, 0);
+ _audioPlayer->playAud(_gameInfo->getSfxTrack(_walkSoundId), _walkSoundVolume, _walkSoundBalance, _walkSoundBalance, 50, 0);
_walkSoundId = -1;
}
@@ -1196,8 +1192,8 @@ void BladeRunnerEngine::handleMouseClickRegion(int regionId, int x, int y, bool
}
void BladeRunnerEngine::handleMouseClick3DObject(int objectId, bool buttonDown, bool isClickable, bool isTarget) {
- const char *objectName = _scene->objectGetName(objectId);
- debug("Clicked on object %s", objectName);
+ const Common::String &objectName = _scene->objectGetName(objectId);
+ debug("Clicked on object %s", objectName.c_str());
if (_isWalkingInterruptible && objectId != _walkingToObjectId) {
_isWalkingInterruptible = false;
@@ -1230,7 +1226,7 @@ void BladeRunnerEngine::handleMouseClick3DObject(int objectId, bool buttonDown,
_walkingToActorId = -1;
_isInsideScriptObject = true;
- _sceneScript->clickedOn3DObject(objectName, false);
+ _sceneScript->clickedOn3DObject(objectName.c_str(), false);
_isInsideScriptObject = false;
}
} else {
@@ -1246,7 +1242,7 @@ void BladeRunnerEngine::handleMouseClick3DObject(int objectId, bool buttonDown,
//TODO mouse::randomize(Mouse);
_isInsideScriptObject = true;
- _sceneScript->clickedOn3DObject(objectName, true);
+ _sceneScript->clickedOn3DObject(objectName.c_str(), true);
_isInsideScriptObject = false;
}
}
@@ -1597,53 +1593,29 @@ bool BladeRunnerEngine::saveGame(const Common::String &filename, byte *thumbnail
return false;
}
- SaveFile s(commonSaveFile);
+ SaveFileWriteStream s;
s.padBytes(9600); // TODO: thumbnail
- s.write(-1.0f);
-
+ s.writeFloat(-1.0f);
_settings->save(s);
- // s.debug(" - SCENE - ");
_scene->save(s);
- // s.debug(" - EXIST - ");
_scene->_exits->save(s);
- // s.debug(" - REGIONS - ");
_scene->_regions->save(s);
- // s.debug(" - SET - ");
_scene->_set->save(s);
-
- // s.debug(" - GAMEVARS - ");
for (uint i = 0; i != _gameInfo->getGlobalVarCount(); ++i) {
- s.write(_gameVars[i]);
+ s.writeInt(_gameVars[i]);
}
-
- // TODO
- // _music->save(s);
- // s.debug(" - MUSIC - ");
- s.padBytes(0x56);
-
+ _music->save(s);
// _audioPlayer->save(s) // zero func
// _audioSpeech->save(s) // zero func
-
- // s.debug(" - COMBAT - ");
_combat->save(s);
- // s.debug(" - GAMEFLAGS - ");
_gameFlags->save(s);
- // s.debug(" - ITEMS - ");
_items->save(s);
- // s.debug(" - SCENEOBJECTS - ");
_sceneObjects->save(s);
- // s.debug(" - AMBIENTSOUNDS - ");
_ambientSounds->save(s);
- // s.debug(" - OVERLAYS - ");
_overlays->save(s);
- // s.debug(" - SPINNER - ");
_spinner->save(s);
-
- // TODO
- // _scores->save(s);
- s.padBytes(0x28);
-
+ s.padBytes(0x28); // TODO: _scores->save(s);
_dialogueMenu->save(s);
_obstacles->save(s);
_actorDialogueQueue->save(s);
@@ -1652,12 +1624,12 @@ bool BladeRunnerEngine::saveGame(const Common::String &filename, byte *thumbnail
for (uint i = 0; i != _gameInfo->getActorCount(); ++i) {
_actors[i]->save(s);
- int animationState, animationFrame, a3, a4;
- _aiScripts->queryAnimationState(i, &animationState, &animationFrame, &a3, &a4);
- s.write(animationState);
- s.write(animationFrame);
- s.write(a3);
- s.write(a4);
+ int animationState, animationFrame, animationStateNext, nextAnimation;
+ _aiScripts->queryAnimationState(i, &animationState, &animationFrame, &animationStateNext, &nextAnimation);
+ s.writeInt(animationState);
+ s.writeInt(animationFrame);
+ s.writeInt(animationStateNext);
+ s.writeInt(nextAnimation);
}
_actors[kActorVoiceOver]->save(s);
@@ -1667,11 +1639,86 @@ bool BladeRunnerEngine::saveGame(const Common::String &filename, byte *thumbnail
s.finalize();
assert(0 && "ok");
+ commonSaveFile->writeUint32LE(s.size() + 4);
+ commonSaveFile->write(s.getData(), s.size());
+
return !commonSaveFile->err();
}
-void BladeRunnerEngine::ISez(const char *str) {
- debug("\t%s", str);
+void BladeRunnerEngine::loadGame(const Common::String &filename, byte *thumbnail) {
+ warning("BladeRunnerEngine::loadGame not finished");
+
+ if (!playerHasControl() || _sceneScript->isInsideScript() || _aiScripts->isInsideScript()) {
+ return;
+ }
+
+ Common::InSaveFile *commonSaveFile = getSaveFileManager()->openForLoading(filename);
+ if (commonSaveFile->err()) {
+ return;
+ }
+
+ void *buf = malloc(commonSaveFile->size());
+ int dataSize = commonSaveFile->read(buf, commonSaveFile->size());
+
+ SaveFileReadStream s((const byte*)buf, dataSize);
+
+ _ambientSounds->removeAllNonLoopingSounds(true);
+ _ambientSounds->removeAllLoopingSounds(1);
+ _music->stop(2);
+ _audioSpeech->stopSpeech();
+ _actorDialogueQueue->flush(true, false);
+
+ int size = s.readInt();
+
+ if (size != dataSize) {
+ return;
+ }
+
+ s.skip(9600); // thumbnail
+ _settings->load(s);
+ _scene->load(s);
+ _scene->_exits->load(s);
+ _scene->_regions->load(s);
+ _scene->_set->load(s);
+ for (uint i = 0; i != _gameInfo->getGlobalVarCount(); ++i) {
+ _gameVars[i] = s.readInt();
+ }
+ _music->load(s);
+ // _audioPlayer->load(s) // zero func
+ // _audioSpeech->load(s) // zero func
+ _combat->load(s);
+ _gameFlags->load(s);
+ _items->load(s);
+ _sceneObjects->load(s);
+ _ambientSounds->load(s);
+ _overlays->load(s);
+ _spinner->load(s);
+ s.skip(0x28); // TODO: _scores->load(s);
+ _dialogueMenu->load(s);
+ _obstacles->load(s);
+ _actorDialogueQueue->load(s);
+ _waypoints->load(s);
+
+ for (uint i = 0; i != _gameInfo->getActorCount(); ++i) {
+ _actors[i]->load(s);
+
+ int animationState = s.readInt();
+ int animationFrame = s.readInt();
+ int animationStateNext = s.readInt();
+ int nextAnimation = s.readInt();
+ _aiScripts->setAnimationState(i, animationState, animationFrame, animationStateNext, nextAnimation);
+ }
+ _actors[kActorVoiceOver]->load(s);
+
+ _policeMaze->load(s);
+ _crimesDatabase->load(s);
+
+ _settings->setNewSetAndScene(_settings->getSet(), _settings->getScene());
+ _settings->setChapter(_settings->getChapter());
+}
+
+void BladeRunnerEngine::ISez(const Common::String &str) {
+ debug("\t%s", str.c_str());
}
void BladeRunnerEngine::blitToScreen(const Graphics::Surface &src) {
diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h
index 7561db2acf..32747cc514 100644
--- a/engines/bladerunner/bladerunner.h
+++ b/engines/bladerunner/bladerunner.h
@@ -104,10 +104,10 @@ public:
static const int kActorCount = 100;
static const int kActorVoiceOver = kActorCount - 1;
- bool _gameIsRunning;
- bool _windowIsActive;
- int _playerLosesControlCounter;
- const char *_languageCode;
+ bool _gameIsRunning;
+ bool _windowIsActive;
+ int _playerLosesControlCounter;
+ Common::String _languageCode;
ActorDialogueQueue *_actorDialogueQueue;
ScreenEffects *_screenEffects;
@@ -261,11 +261,11 @@ public:
void playerGainsControl();
bool saveGame(const Common::String &filename, byte *thumbnail);
- void loadGame();
+ void loadGame(const Common::String &filename, byte *thumbnail);
void newGame();
void autoSaveGame();
- void ISez(const char *str);
+ void ISez(const Common::String &str);
void blitToScreen(const Graphics::Surface &src);
diff --git a/engines/bladerunner/boundingbox.cpp b/engines/bladerunner/boundingbox.cpp
index aea2dc0a24..40b7d4285a 100644
--- a/engines/bladerunner/boundingbox.cpp
+++ b/engines/bladerunner/boundingbox.cpp
@@ -84,16 +84,4 @@ float BoundingBox::getZ1() const {
return _vertices[1].z;
}
-void BoundingBox::save(SaveFile &f) {
- f.write(_vertices[0].x);
- f.write(_vertices[0].y);
- f.write(_vertices[0].z);
- f.write(_vertices[1].x);
- f.write(_vertices[1].y);
- f.write(_vertices[1].z);
-
- // Bounding boxes have a lot of extra data that's never actually used
- f.padBytes(8*8*4);
-}
-
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/boundingbox.h b/engines/bladerunner/boundingbox.h
index 0397a86266..0206f0bbdc 100644
--- a/engines/bladerunner/boundingbox.h
+++ b/engines/bladerunner/boundingbox.h
@@ -27,7 +27,7 @@
namespace BladeRunner {
-class SaveFile;
+class SaveFileWriteStream;
class BoundingBox {
Vector3 _vertices[2];
@@ -45,8 +45,6 @@ public:
float getZ0() const;
float getZ1() const;
-
- void save(SaveFile &f);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/combat.cpp b/engines/bladerunner/combat.cpp
index eefcebccba..e1dc6b1044 100644
--- a/engines/bladerunner/combat.cpp
+++ b/engines/bladerunner/combat.cpp
@@ -127,8 +127,8 @@ void Combat::shoot(int actorId, Vector3 &to, int screenX) {
distanceFromCenter = 100 * -------------------------------
abs(right - left) / 2
*/
- Common::Rect *rect = actor->getScreenRectangle();
- int distanceFromCenter = CLIP(100 * (screenX - abs((rect->right + rect->left) / 2)) / abs((rect->right - rect->left) / 2), 0, 100);
+ const Common::Rect &rect = actor->getScreenRectangle();
+ int distanceFromCenter = CLIP(100 * (screenX - abs((rect.right + rect.left) / 2)) / abs((rect.right - rect.left) / 2), 0, 100);
int damage = (100 - distanceFromCenter) * _ammoDamage[_vm->_settings->getAmmoType()] / 100;
@@ -205,14 +205,25 @@ int Combat::findCoverWaypoint(int waypointType, int actorId, int enemyId) const
return result;
}
-void Combat::save(SaveFile &f) {
- f.write(_active);
- f.write(_enabled);
- for (int i = 0; i != 9; ++i) {
- f.write(_hitSoundId[i]);
+void Combat::save(SaveFileWriteStream &f) {
+ f.writeBool(_active);
+ f.writeBool(_enabled);
+ for (int i = 0; i != kSoundCount; ++i) {
+ f.writeInt(_hitSoundId[i]);
}
- for (int i = 0; i != 9; ++i) {
- f.write(_missSoundId[i]);
+ for (int i = 0; i != kSoundCount; ++i) {
+ f.writeInt(_missSoundId[i]);
+ }
+}
+
+void Combat::load(SaveFileReadStream &f) {
+ _active = f.readBool();
+ _enabled = f.readBool();
+ for (int i = 0; i != kSoundCount; ++i) {
+ _hitSoundId[i] = f.readInt();
+ }
+ for (int i = 0; i != kSoundCount; ++i) {
+ _missSoundId[i] = f.readInt();
}
}
diff --git a/engines/bladerunner/combat.h b/engines/bladerunner/combat.h
index 670f580011..e0038d677e 100644
--- a/engines/bladerunner/combat.h
+++ b/engines/bladerunner/combat.h
@@ -30,7 +30,8 @@
namespace BladeRunner {
class BladeRunnerEngine;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class Vector3;
class Combat {
@@ -90,7 +91,8 @@ public:
int findFleeWaypoint(int setId, int enemyId, const Vector3& position) const;
int findCoverWaypoint(int waypointType, int actorId, int enemyId) const;
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/crimes_database.cpp b/engines/bladerunner/crimes_database.cpp
index 131c871654..e9faa22b41 100644
--- a/engines/bladerunner/crimes_database.cpp
+++ b/engines/bladerunner/crimes_database.cpp
@@ -29,7 +29,7 @@
namespace BladeRunner {
-CrimesDatabase::CrimesDatabase(BladeRunnerEngine *vm, const char *cluesResource, int crimeCount) {
+CrimesDatabase::CrimesDatabase(BladeRunnerEngine *vm, const Common::String &cluesResource, int crimeCount) {
_crimeCount = crimeCount;
_crimes.resize(_crimeCount);
@@ -71,10 +71,16 @@ const char *CrimesDatabase::getClueText(int clueId) const {
return _cluesText->getText(clueId);
}
-void CrimesDatabase::save(SaveFile &f) {
+void CrimesDatabase::save(SaveFileWriteStream &f) {
for (int i = 0; i < _crimeCount; ++i) {
uint8 c = _crimes[i];
- f.write(c);
+ f.writeByte(c);
+ }
+}
+
+void CrimesDatabase::load(SaveFileReadStream &f) {
+ for (int i = 0; i < _crimeCount; ++i) {
+ _crimes[i] = f.readByte();
}
}
diff --git a/engines/bladerunner/crimes_database.h b/engines/bladerunner/crimes_database.h
index 1374d52424..9bb83f148f 100644
--- a/engines/bladerunner/crimes_database.h
+++ b/engines/bladerunner/crimes_database.h
@@ -28,7 +28,8 @@
namespace BladeRunner {
class BladeRunnerEngine;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class TextResource;
class CrimesDatabase {
@@ -38,7 +39,7 @@ class CrimesDatabase {
TextResource *_cluesText;
public:
- CrimesDatabase(BladeRunnerEngine *vm, const char *cluesResource, int crimeCount);
+ CrimesDatabase(BladeRunnerEngine *vm, const Common::String &cluesResource, int crimeCount);
~CrimesDatabase();
void setCrime(int clueId, int crimeId);
@@ -49,7 +50,8 @@ public:
const char *getClueText(int clueId) const;
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/debugger.cpp b/engines/bladerunner/debugger.cpp
index 2c9b7e6f74..87ab5d2cc1 100644
--- a/engines/bladerunner/debugger.cpp
+++ b/engines/bladerunner/debugger.cpp
@@ -386,9 +386,9 @@ void Debugger::drawSceneObjects() {
for (int i = 0; i < count; i++) {
SceneObjects::SceneObject *sceneObject = &_vm->_sceneObjects->_sceneObjects[_vm->_sceneObjects->_sceneObjectsSortedByDistance[i]];
- const BoundingBox *bbox = sceneObject->boundingBox;
+ const BoundingBox &bbox = sceneObject->boundingBox;
Vector3 a, b;
- bbox->getXYZ(&a.x, &a.y, &a.z, &b.x, &b.y, &b.z);
+ bbox.getXYZ(&a.x, &a.y, &a.z, &b.x, &b.y, &b.z);
Vector3 pos = _vm->_view->calculateScreenPosition(0.5 * (a + b));
int color;
@@ -398,7 +398,7 @@ void Debugger::drawSceneObjects() {
case kSceneObjectTypeActor:
color = 0x7C00; // 11111 00000 00000;
drawBBox(a, b, _vm->_view, &_vm->_surfaceFront, color);
- _vm->_surfaceFront.frameRect(*sceneObject->screenRectangle, color);
+ _vm->_surfaceFront.frameRect(sceneObject->screenRectangle, color);
_vm->_mainFont->drawColor(_vm->_textActorNames->getText(sceneObject->id - kSceneObjectOffsetActors), _vm->_surfaceFront, pos.x, pos.y, color);
break;
case kSceneObjectTypeItem:
@@ -406,7 +406,7 @@ void Debugger::drawSceneObjects() {
char itemText[40];
drawBBox(a, b, _vm->_view, &_vm->_surfaceFront, color);
sprintf(itemText, "item %i", sceneObject->id - kSceneObjectOffsetItems);
- _vm->_surfaceFront.frameRect(*sceneObject->screenRectangle, color);
+ _vm->_surfaceFront.frameRect(sceneObject->screenRectangle, color);
_vm->_mainFont->drawColor(itemText, _vm->_surfaceFront, pos.x, pos.y, color);
break;
case kSceneObjectTypeObject:
@@ -417,7 +417,7 @@ void Debugger::drawSceneObjects() {
color = 0x03E0; // 00000 11111 00000;
}
drawBBox(a, b, _vm->_view, &_vm->_surfaceFront, color);
- _vm->_surfaceFront.frameRect(*sceneObject->screenRectangle, color);
+ _vm->_surfaceFront.frameRect(sceneObject->screenRectangle, color);
_vm->_mainFont->drawColor(_vm->_scene->objectGetName(sceneObject->id - kSceneObjectOffsetObjects), _vm->_surfaceFront, pos.x, pos.y, color);
break;
}
diff --git a/engines/bladerunner/dialogue_menu.cpp b/engines/bladerunner/dialogue_menu.cpp
index 7b7223fe94..744183a51f 100644
--- a/engines/bladerunner/dialogue_menu.cpp
+++ b/engines/bladerunner/dialogue_menu.cpp
@@ -365,27 +365,51 @@ bool DialogueMenu::waitingForInput() const {
return _waitingForInput;
}
-void DialogueMenu::save(SaveFile &f) {
- f.write(_isVisible);
- f.write(_waitingForInput);
- f.write(_selectedItemIndex);
- f.write(_listSize);
+void DialogueMenu::save(SaveFileWriteStream &f) {
+ f.writeBool(_isVisible);
+ f.writeBool(_waitingForInput);
+ f.writeInt(_selectedItemIndex);
+ f.writeInt(_listSize);
- f.write(_neverRepeatListSize);
+ f.writeInt(_neverRepeatListSize);
for (int i = 0; i < 100; ++i) {
- f.write(_neverRepeatValues[i]);
+ f.writeInt(_neverRepeatValues[i]);
}
for (int i = 0; i < 100; ++i) {
- f.write(_neverRepeatWasSelected[i]);
+ f.writeBool(_neverRepeatWasSelected[i]);
}
for (int i = 0; i < 10; ++i) {
- f.write(_items[i].text, 50);
- f.write(_items[i].answerValue);
- f.write(_items[i].colorIntensity);
- f.write(_items[i].priorityPolite);
- f.write(_items[i].priorityNormal);
- f.write(_items[i].prioritySurly);
- f.write(_items[i].isDone);
+ f.writeStringSz(_items[i].text, 50);
+ f.writeInt(_items[i].answerValue);
+ f.writeInt(_items[i].colorIntensity);
+ f.writeInt(_items[i].priorityPolite);
+ f.writeInt(_items[i].priorityNormal);
+ f.writeInt(_items[i].prioritySurly);
+ f.writeInt(_items[i].isDone);
+ }
+}
+
+void DialogueMenu::load(SaveFileReadStream &f) {
+ _isVisible = f.readBool();
+ _waitingForInput = f.readBool();
+ _selectedItemIndex = f.readInt();
+ _listSize = f.readInt();
+
+ _neverRepeatListSize = f.readInt();
+ for (int i = 0; i < 100; ++i) {
+ _neverRepeatValues[i] = f.readInt();
+ }
+ for (int i = 0; i < 100; ++i) {
+ _neverRepeatWasSelected[i] = f.readBool();
+ }
+ for (int i = 0; i < 10; ++i) {
+ _items[i].text = f.readStringSz(50);
+ _items[i].answerValue = f.readInt();
+ _items[i].colorIntensity = f.readInt();
+ _items[i].priorityPolite = f.readInt();
+ _items[i].priorityNormal = f.readInt();
+ _items[i].prioritySurly = f.readInt();
+ _items[i].isDone = f.readInt();
}
}
diff --git a/engines/bladerunner/dialogue_menu.h b/engines/bladerunner/dialogue_menu.h
index b06cf9dfb6..6dfd3efdc6 100644
--- a/engines/bladerunner/dialogue_menu.h
+++ b/engines/bladerunner/dialogue_menu.h
@@ -33,7 +33,8 @@
namespace BladeRunner {
class BladeRunnerEngine;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class TextResource;
class DialogueMenu {
@@ -97,16 +98,14 @@ public:
void mouseUp();
bool waitingForInput() const;
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
+
private:
bool showAt(int x, int y);
int getAnswerIndex(int answer) const;
const char *getText(int id) const;
void calculatePosition(int unusedX = 0, int unusedY = 0);
-
-public:
- void save(SaveFile &f);
-
-private:
void clear();
void reset();
diff --git a/engines/bladerunner/fog.cpp b/engines/bladerunner/fog.cpp
index fff27b0558..c732b598c2 100644
--- a/engines/bladerunner/fog.cpp
+++ b/engines/bladerunner/fog.cpp
@@ -27,7 +27,6 @@
namespace BladeRunner {
Fog::Fog() {
- _name[0] = 0;
_frameCount = 0;
_animatedParameters = 0;
_fogDensity = 0.0f;
@@ -55,7 +54,9 @@ Fog::~Fog() {
int Fog::readCommon(Common::ReadStream *stream) {
int offset = stream->readUint32LE();
- stream->read(_name, 20);
+ char buf[20];
+ stream->read(buf, sizeof(buf));
+ _name = buf;
_fogColor.r = stream->readFloatLE();
_fogColor.g = stream->readFloatLE();
_fogColor.b = stream->readFloatLE();
diff --git a/engines/bladerunner/fog.h b/engines/bladerunner/fog.h
index 95ac550fd1..e952d24165 100644
--- a/engines/bladerunner/fog.h
+++ b/engines/bladerunner/fog.h
@@ -38,7 +38,8 @@ class Fog {
friend class SetEffects;
protected:
- char _name[20];
+ Common::String _name;
+
int _frameCount;
int _animatedParameters;
Matrix4x3 _matrix;
diff --git a/engines/bladerunner/game_flags.cpp b/engines/bladerunner/game_flags.cpp
index 1e0b58378e..6fdcb89363 100644
--- a/engines/bladerunner/game_flags.cpp
+++ b/engines/bladerunner/game_flags.cpp
@@ -73,9 +73,15 @@ bool GameFlags::query(int flag) const {
return !!(_flags[flag / 32] & (1 << (flag % 32)));
}
-void GameFlags::save(SaveFile &f) {
+void GameFlags::save(SaveFileWriteStream &f) {
for (int i = 0; i != _flagCount / 32 + 1; ++i) {
- f.write(_flags[i]);
+ f.writeUint32LE(_flags[i]);
+ }
+}
+
+void GameFlags::load(SaveFileReadStream &f) {
+ for (int i = 0; i != _flagCount / 32 + 1; ++i) {
+ _flags[i] = f.readUint32LE();
}
}
diff --git a/engines/bladerunner/game_flags.h b/engines/bladerunner/game_flags.h
index b409e858b0..837537f689 100644
--- a/engines/bladerunner/game_flags.h
+++ b/engines/bladerunner/game_flags.h
@@ -27,7 +27,8 @@
namespace BladeRunner {
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class GameFlags {
uint32 *_flags;
@@ -43,7 +44,8 @@ public:
void reset(int flag);
bool query(int flag) const;
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/game_info.cpp b/engines/bladerunner/game_info.cpp
index db664c0f2d..9dc261bc31 100644
--- a/engines/bladerunner/game_info.cpp
+++ b/engines/bladerunner/game_info.cpp
@@ -31,10 +31,6 @@ namespace BladeRunner {
GameInfo::GameInfo(BladeRunnerEngine *vm) {
_vm = vm;
- _sceneNames = nullptr;
- _sfxTracks = nullptr;
- _musicTracks = nullptr;
- _outtakes = nullptr;
_actorCount = 0;
_playerId = 0;
_flagCount = 0;
@@ -53,18 +49,12 @@ GameInfo::GameInfo(BladeRunnerEngine *vm) {
_fleeWaypointCount = 0;
}
-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)
+ if (!s) {
return false;
+ }
uint32 unk;
_actorCount = s->readUint32LE(); /* 00 */
@@ -88,25 +78,33 @@ bool GameInfo::open(const Common::String &name) {
(void)unk;
- _sceneNames = new char[_sceneNamesCount][5];
- for (uint32 i = 0; i != _sceneNamesCount; ++i)
- s->read(_sceneNames[i], 5);
+ char buf[9];
+
+ _sceneNames.resize(_sceneNamesCount);
+ for (uint32 i = 0; i != _sceneNamesCount; ++i) {
+ s->read(buf, 5);
+ _sceneNames[i] = buf;
+ }
- _sfxTracks = new char[_sfxTrackCount][13];
+ _sfxTracks.resize(_sfxTrackCount);
for (uint32 i = 0; i != _sfxTrackCount; ++i) {
- s->read(_sfxTracks[i], 9);
- strcat(_sfxTracks[i], ".AUD");
+ s->read(buf, 9);
+ _sfxTracks[i] = buf;
+ _sfxTracks[i] += ".AUD";
}
- _musicTracks = new char[_musicTrackCount][13];
+ _musicTracks.resize(_musicTrackCount);
for (uint32 i = 0; i != _musicTrackCount; ++i) {
- s->read(_musicTracks[i], 9);
- strcat(_musicTracks[i], ".AUD");
+ s->read(buf, 9);
+ _musicTracks[i] = buf;
+ _musicTracks[i] += ".AUD";
}
- _outtakes = new char[_outtakeCount][13];
- for (uint32 i = 0; i != _outtakeCount; ++i)
- s->read(_outtakes[i], 9);
+ _outtakes.resize(_outtakeCount);
+ for (uint32 i = 0; i != _outtakeCount; ++i) {
+ s->read(buf, 9);
+ _outtakes[i] = buf;
+ }
#if BLADERUNNER_DEBUG_CONSOLE
debug("\nScene names\n----------------");
@@ -135,34 +133,38 @@ bool GameInfo::open(const Common::String &name) {
return !err;
}
-const char *GameInfo::getSceneName(int i) const {
+const Common::String &GameInfo::getSceneName(int i) const {
if (i < 0 || i >= (int)_sceneNamesCount) {
warning("GameInfo::getSceneName: unknown id \"%i\"", i);
- return nullptr;
+ static Common::String str("UNKNOWN_SCENE");
+ return str;
}
return _sceneNames[i];
}
-const char *GameInfo::getSfxTrack(int i) const {
+const Common::String &GameInfo::getSfxTrack(int i) const {
if (i < 0 || i >= (int)_sfxTrackCount) {
warning("GameInfo::getSfxTrack: unknown id \"%i\"", i);
- return nullptr;
+ static Common::String str("UNKNOWN_SFX_TRACK");
+ return str;
}
return _sfxTracks[i];
}
-const char *GameInfo::getMusicTrack(int i) const {
+const Common::String &GameInfo::getMusicTrack(int i) const {
if (i < 0 || i >= (int)_musicTrackCount) {
warning("GameInfo::getMusicTrack: unknown id \"%i\"", i);
- return nullptr;
+ static Common::String str("UNKNOWN_MUSIC_TRACK");
+ return str;
}
return _musicTracks[i];
}
-const char *GameInfo::getOuttake(int i) const {
+const Common::String &GameInfo::getOuttake(int i) const {
if (i < 0 || i >= (int)_outtakeCount) {
warning("GameInfo::getOuttake: unknown id \"%i\"", i);
- return nullptr;
+ static Common::String str("UNKNOWN_OUTTAKE");
+ return str;
}
return _outtakes[i];
}
diff --git a/engines/bladerunner/game_info.h b/engines/bladerunner/game_info.h
index bc7fc1eeec..857efa9e0b 100644
--- a/engines/bladerunner/game_info.h
+++ b/engines/bladerunner/game_info.h
@@ -23,6 +23,7 @@
#ifndef BLADERUNNER_GAME_INFO_H
#define BLADERUNNER_GAME_INFO_H
+#include "common/array.h"
#include "common/str.h"
namespace BladeRunner {
@@ -49,14 +50,13 @@ class GameInfo {
uint32 _coverWaypointCount;
uint32 _fleeWaypointCount;
- char (*_sceneNames)[5];
- char (*_sfxTracks)[13];
- char (*_musicTracks)[13];
- char (*_outtakes)[13];
+ Common::Array<Common::String> _sceneNames;
+ Common::Array<Common::String> _sfxTracks;
+ Common::Array<Common::String> _musicTracks;
+ Common::Array<Common::String> _outtakes;
public:
GameInfo(BladeRunnerEngine *vm);
- ~GameInfo();
bool open(const Common::String &name);
@@ -77,10 +77,10 @@ public:
uint32 getCoverWaypointCount() const { return _coverWaypointCount; }
uint32 getFleeWaypointCount() const { return _fleeWaypointCount; }
- const char *getSceneName(int i) const;
- const char *getSfxTrack(int i) const;
- const char *getMusicTrack(int i) const;
- const char *getOuttake(int i) const;
+ const Common::String &getSceneName(int i) const;
+ const Common::String &getSfxTrack(int i) const;
+ const Common::String &getMusicTrack(int i) const;
+ const Common::String &getOuttake(int i) const;
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/item.cpp b/engines/bladerunner/item.cpp
index bf09efb0e6..9aa50e366f 100644
--- a/engines/bladerunner/item.cpp
+++ b/engines/bladerunner/item.cpp
@@ -174,26 +174,48 @@ bool Item::isUnderMouse(int mouseX, int mouseY) const {
&& mouseY <= _screenRectangle.bottom + 10;
}
-void Item::save(SaveFile &f) {
- f.write(_setId);
- f.write(_itemId);
- _boundingBox.save(f);
- f.write(_screenRectangle);
- f.write(_animationId);
- f.write(_position);
- f.write(_facing);
- f.write(_angle);
- f.write(_width);
- f.write(_height);
- f.write(_screenX);
- f.write(_screenY);
- f.write(_depth);
- f.write(_isTarget);
- f.write(_isSpinning);
- f.write(_facingChange);
- f.write(0.0f); // _viewAngle
- f.write(_isVisible);
- f.write(_isPoliceMazeEnemy);
+void Item::save(SaveFileWriteStream &f) {
+ f.writeInt(_setId);
+ f.writeInt(_itemId);
+ f.writeBoundingBox(_boundingBox);
+ f.writeRect(_screenRectangle);
+ f.writeInt(_animationId);
+ f.writeVector3(_position);
+ f.writeInt(_facing);
+ f.writeFloat(_angle);
+ f.writeInt(_width);
+ f.writeInt(_height);
+ f.writeInt(_screenX);
+ f.writeInt(_screenY);
+ f.writeFloat(_depth);
+ f.writeBool(_isTarget);
+ f.writeBool(_isSpinning);
+ f.writeInt(_facingChange);
+ f.writeFloat(0.0f); // _viewAngle
+ f.writeBool(_isVisible);
+ f.writeBool(_isPoliceMazeEnemy);
+}
+
+void Item::load(SaveFileReadStream &f) {
+ _setId = f.readInt();
+ _itemId = f.readInt();
+ _boundingBox = f.readBoundingBox();
+ _screenRectangle = f.readRect();
+ _animationId = f.readInt();
+ _position = f.readVector3();
+ _facing = f.readInt();
+ _angle = f.readFloat();
+ _width = f.readInt();
+ _height = f.readInt();
+ _screenX = f.readInt();
+ _screenY = f.readInt();
+ _depth = f.readFloat();
+ _isTarget = f.readBool();
+ _isSpinning = f.readBool();
+ _facingChange = f.readInt();
+ f.skip(4);
+ _isVisible = f.readBool();
+ _isPoliceMazeEnemy = f.readBool();
}
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/item.h b/engines/bladerunner/item.h
index bf07a118bd..9a28d9b1d4 100644
--- a/engines/bladerunner/item.h
+++ b/engines/bladerunner/item.h
@@ -32,7 +32,8 @@ namespace BladeRunner {
class BladeRunnerEngine;
class Items;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class Item {
friend class Items;
@@ -66,8 +67,8 @@ public:
void setXYZ(Vector3 position);
void getWidthHeight(int *width, int *height) const;
- BoundingBox *getBoundingBox() { return &_boundingBox; }
- Common::Rect *getScreenRectangle() { return &_screenRectangle; }
+ const BoundingBox &getBoundingBox() { return _boundingBox; }
+ const Common::Rect &getScreenRectangle() { return _screenRectangle; }
int getFacing() const { return _facing; }
void setFacing(int facing) { _facing = facing; }
@@ -86,7 +87,8 @@ public:
bool isUnderMouse(int mouseX, int mouseY) const;
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
};
}
diff --git a/engines/bladerunner/items.cpp b/engines/bladerunner/items.cpp
index 7fe769cb93..caae3ae683 100644
--- a/engines/bladerunner/items.cpp
+++ b/engines/bladerunner/items.cpp
@@ -89,7 +89,7 @@ bool Items::addToWorld(int itemId, int animationId, int setId, Vector3 position,
item->setup(itemId, setId, animationId, position, facing, height, width, isTargetFlag, isVisible, isPoliceMazeEnemy);
if (addToSetFlag && setId == _vm->_scene->getSetId()) {
- return _vm->_sceneObjects->addItem(itemId + kSceneObjectOffsetItems, &item->_boundingBox, &item->_screenRectangle, isTargetFlag, isVisible);
+ return _vm->_sceneObjects->addItem(itemId + kSceneObjectOffsetItems, item->_boundingBox, item->_screenRectangle, isTargetFlag, isVisible);
}
return true;
}
@@ -102,7 +102,7 @@ bool Items::addToSet(int setId) {
for (int i = 0; i < itemCount; i++) {
Item *item = _items[i];
if (item->_setId == setId) {
- _vm->_sceneObjects->addItem(item->_itemId + kSceneObjectOffsetItems, &item->_boundingBox, &item->_screenRectangle, item->isTarget(), item->_isVisible);
+ _vm->_sceneObjects->addItem(item->_itemId + kSceneObjectOffsetItems, item->_boundingBox, item->_screenRectangle, item->isTarget(), item->_isVisible);
}
}
return true;
@@ -184,19 +184,19 @@ void Items::setIsObstacle(int itemId, bool val) {
_vm->_sceneObjects->setIsClickable(itemId + kSceneObjectOffsetItems, val);
}
-BoundingBox *Items::getBoundingBox(int itemId) {
+const BoundingBox &Items::getBoundingBox(int itemId) {
int itemIndex = findItem(itemId);
- if (itemIndex == -1) {
- return nullptr;
- }
+ // if (itemIndex == -1) {
+ // return nullptr;
+ // }
return _items[itemIndex]->getBoundingBox();
}
-Common::Rect *Items::getScreenRectangle(int itemId) {
+const Common::Rect &Items::getScreenRectangle(int itemId) {
int itemIndex = findItem(itemId);
- if (itemIndex == -1) {
- return nullptr;
- }
+ // if (itemIndex == -1) {
+ // return nullptr;
+ // }
return _items[itemIndex]->getScreenRectangle();
}
@@ -243,10 +243,10 @@ int Items::findItem(int itemId) const {
return -1;
}
-void Items::save(SaveFile &f) {
+void Items::save(SaveFileWriteStream &f) {
int size = (int)_items.size();
- f.write(size);
+ f.writeInt(size);
int i;
for (i = 0; i != size; ++i) {
_items[i]->save(f);
@@ -258,4 +258,24 @@ void Items::save(SaveFile &f) {
}
}
+void Items::load(SaveFileReadStream &f) {
+ for (int i = _items.size() - 1; i >= 0; i--) {
+ delete _items.remove_at(i);
+ }
+ _items.resize(f.readInt());
+
+ int size = (int)_items.size();
+
+ int i;
+ for (i = 0; i != size; ++i) {
+ _items[i] = new Item(_vm);
+ _items[i]->load(f);
+ }
+
+ // Always read out 100 items
+ for (; i != 100; ++i) {
+ f.skip(0x174); // bbox + rect + 18 float fields
+ }
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/items.h b/engines/bladerunner/items.h
index cc9af734b2..e3971057bb 100644
--- a/engines/bladerunner/items.h
+++ b/engines/bladerunner/items.h
@@ -30,7 +30,8 @@
namespace BladeRunner {
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class Items {
BladeRunnerEngine *_vm;
@@ -59,14 +60,16 @@ public:
bool isVisible(int itemId) const;
int findTargetUnderMouse(int mouseX, int mouseY) const;
- BoundingBox *getBoundingBox(int itemId);
- Common::Rect *getScreenRectangle(int itemId);
+ const BoundingBox &getBoundingBox(int itemId);
+ const Common::Rect &getScreenRectangle(int itemId);
int getFacing(int itemId) const;
void setFacing(int itemId, int facing);
void spinInWorld(int itemId);
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
+
private:
int findItem(int itemId) const;
};
diff --git a/engines/bladerunner/light.cpp b/engines/bladerunner/light.cpp
index 615958281a..2231e0460e 100644
--- a/engines/bladerunner/light.cpp
+++ b/engines/bladerunner/light.cpp
@@ -69,7 +69,9 @@ void Light::read(Common::ReadStream *stream, int frameCount, int frame, int anim
int size = stream->readUint32LE();
size = size - 32;
- stream->read(_name, 20);
+ char buf[20];
+ stream->read(buf, sizeof(buf));
+ _name = buf;
_animatedParameters = stream->readUint32LE();
diff --git a/engines/bladerunner/light.h b/engines/bladerunner/light.h
index 1ef9f3082c..31e40e0b45 100644
--- a/engines/bladerunner/light.h
+++ b/engines/bladerunner/light.h
@@ -42,7 +42,8 @@ class Light {
friend class SliceRenderer;
protected:
- char _name[20];
+ Common::String _name;
+
int _frameCount;
int _animated;
int _animatedParameters;
diff --git a/engines/bladerunner/module.mk b/engines/bladerunner/module.mk
index f4bf926aa0..5fb39b8289 100644
--- a/engines/bladerunner/module.mk
+++ b/engines/bladerunner/module.mk
@@ -40,8 +40,6 @@ MODULE_OBJS = \
obstacles.o \
outtake.o \
overlays.o \
- police_maze.o \
- police_maze_track.o \
regions.o \
savefile.o \
scene.o \
diff --git a/engines/bladerunner/movement_track.cpp b/engines/bladerunner/movement_track.cpp
index 5a6407ed3a..322d92ef31 100644
--- a/engines/bladerunner/movement_track.cpp
+++ b/engines/bladerunner/movement_track.cpp
@@ -109,17 +109,31 @@ bool MovementTrack::next(int *waypointId, int *delay, int *angle, bool *run) {
}
}
-void MovementTrack::save(SaveFile &f) {
- f.write(_currentIndex);
- f.write(_lastIndex);
- f.write(_hasNext);
- f.write(_paused);
- for (int i = 0; i < 100; ++i) {
+void MovementTrack::save(SaveFileWriteStream &f) {
+ f.writeInt(_currentIndex);
+ f.writeInt(_lastIndex);
+ f.writeBool(_hasNext);
+ f.writeBool(_paused);
+ for (int i = 0; i < kSize; ++i) {
Entry &e = _entries[i];
- f.write(e.waypointId);
- f.write(e.delay);
- f.write(e.angle);
- f.write(e.run);
+ f.writeInt(e.waypointId);
+ f.writeInt(e.delay);
+ f.writeInt(e.angle);
+ f.writeBool(e.run);
+ }
+}
+
+void MovementTrack::load(SaveFileReadStream &f) {
+ _currentIndex = f.readInt();
+ _lastIndex = f.readInt();
+ _hasNext = f.readBool();
+ _paused = f.readBool();
+ for (int i = 0; i < kSize; ++i) {
+ Entry &e = _entries[i];
+ e.waypointId = f.readInt();
+ e.delay = f.readInt();
+ e.angle = f.readInt();
+ e.run = f.readBool();
}
}
diff --git a/engines/bladerunner/movement_track.h b/engines/bladerunner/movement_track.h
index 2d59fd98c7..2eab4cdedb 100644
--- a/engines/bladerunner/movement_track.h
+++ b/engines/bladerunner/movement_track.h
@@ -29,7 +29,8 @@ namespace BladeRunner {
class BladeRunnerEngine;
class BoundingBox;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class MovementTrack {
static const int kSize = 100;
@@ -60,7 +61,9 @@ public:
bool hasNext() const;
bool next(int *waypointId, int *delay, int *angle, bool *run);
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
+
private:
void reset();
};
diff --git a/engines/bladerunner/music.cpp b/engines/bladerunner/music.cpp
index 818d412ba9..05412dd8e0 100644
--- a/engines/bladerunner/music.cpp
+++ b/engines/bladerunner/music.cpp
@@ -26,6 +26,7 @@
#include "bladerunner/aud_stream.h"
#include "bladerunner/bladerunner.h"
#include "bladerunner/game_info.h"
+#include "bladerunner/savefile.h"
#include "common/timer.h"
@@ -167,6 +168,68 @@ void Music::playSample() {
}
}
+void Music::save(SaveFileWriteStream &f) {
+ f.writeBool(_isNextPresent);
+ f.writeBool(_isPlaying);
+ f.writeBool(_isPaused);
+ f.writeStringSz(_current.name, 13);
+ f.writeInt(_current.volume);
+ f.writeInt(_current.pan);
+ f.writeInt(_current.timeFadeIn);
+ f.writeInt(_current.timePlay);
+ f.writeInt(_current.loop);
+ f.writeInt(_current.timeFadeOut);
+ f.writeStringSz(_next.name, 13);
+ f.writeInt(_next.volume);
+ f.writeInt(_next.pan);
+ f.writeInt(_next.timeFadeIn);
+ f.writeInt(_next.timePlay);
+ f.writeInt(_next.loop);
+ f.writeInt(_next.timeFadeOut);
+}
+
+void Music::load(SaveFileReadStream &f) {
+ _isNextPresent = f.readBool();
+ _isPlaying = f.readBool();
+ _isPaused = f.readBool();
+ _current.name = f.readStringSz(13);
+ _current.volume = f.readInt();
+ _current.pan = f.readInt();
+ _current.timeFadeIn = f.readInt();
+ _current.timePlay = f.readInt();
+ _current.loop = f.readInt();
+ _current.timeFadeOut = f.readInt();
+ _next.name = f.readStringSz(13);
+ _next.volume = f.readInt();
+ _next.pan = f.readInt();
+ _next.timeFadeIn = f.readInt();
+ _next.timePlay = f.readInt();
+ _next.loop = f.readInt();
+ _next.timeFadeOut = f.readInt();
+
+ stop(2);
+ if (_isPlaying) {
+ if (_channel == -1) {
+ play(_current.name,
+ _current.volume,
+ _current.pan,
+ _current.timeFadeIn,
+ _current.timePlay,
+ _current.loop,
+ _current.timeFadeOut);
+ } else {
+ _isNextPresent = true;
+ _next.name = _current.name;
+ _next.volume = _current.volume;
+ _next.pan = _current.pan;
+ _next.timeFadeIn = _current.timeFadeIn;
+ _next.timePlay = _current.timePlay;
+ _next.loop = _current.loop;
+ _next.timeFadeOut = _current.timeFadeOut;
+ }
+ }
+}
+
void Music::adjustVolume(int volume, int delay) {
if (_channel >= 0) {
_vm->_audioMixer->adjustVolume(_channel, volume, delay);
diff --git a/engines/bladerunner/music.h b/engines/bladerunner/music.h
index de19942a20..b4dc284def 100644
--- a/engines/bladerunner/music.h
+++ b/engines/bladerunner/music.h
@@ -30,6 +30,8 @@ namespace BladeRunner {
class AudStream;
class BladeRunnerEngine;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class Music {
struct Track {
@@ -47,9 +49,9 @@ class Music {
Common::Mutex _mutex;
int _musicVolume;
int _channel;
- int _isNextPresent;
- int _isPlaying;
- int _isPaused;
+ bool _isNextPresent;
+ bool _isPlaying;
+ bool _isPaused;
Track _current;
Track _next;
byte *_data;
@@ -68,6 +70,9 @@ public:
int getVolume();
void playSample();
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
+
private:
void adjustVolume(int volume, int delay);
void adjustPan(int pan, int delay);
diff --git a/engines/bladerunner/obstacles.cpp b/engines/bladerunner/obstacles.cpp
index 603d514513..ada41df7b3 100644
--- a/engines/bladerunner/obstacles.cpp
+++ b/engines/bladerunner/obstacles.cpp
@@ -68,28 +68,64 @@ void Obstacles::backup() {
void Obstacles::restore() {}
-void Obstacles::save(SaveFile &f) {
- f.write(_backup);
- f.write(_count);
+void Obstacles::save(SaveFileWriteStream &f) {
+ f.writeBool(_backup);
+ f.writeInt(_count);
for (int i = 0; i < _count; ++i) {
Polygon &p = _polygonsBackup[i];
- f.write(p.isPresent);
- f.write(p.verticeCount);
- f.write(p.left);
- f.write(p.bottom);
- f.write(p.right);
- f.write(p.top);
+ f.writeBool(p.isPresent);
+ f.writeInt(p.verticeCount);
+ f.writeFloat(p.left);
+ f.writeFloat(p.bottom);
+ f.writeFloat(p.right);
+ f.writeFloat(p.top);
for (int j = 0; j < kPolygonVertexCount; ++j) {
- f.write(p.vertices[j]);
+ f.writeVector2(p.vertices[j]);
}
for (int j = 0; j < kPolygonVertexCount; ++j) {
- f.write(p.vertexType[j]);
+ f.writeInt(p.vertexType[j]);
}
}
for (int i = 0; i < kVertexCount; ++i) {
- f.write(_vertices[i]);
+ f.writeVector2(_vertices[i]);
}
- f.write(_verticeCount);
+ f.writeInt(_verticeCount);
+}
+
+void Obstacles::load(SaveFileReadStream &f) {
+ for (int i = 0; i < kPolygonCount; ++i) {
+ _polygons[i].isPresent = false;
+ _polygons[i].verticeCount = 0;
+ _polygonsBackup[i].isPresent = false;
+ _polygonsBackup[i].verticeCount = 0;
+ }
+
+ _backup = f.readBool();
+ _count = f.readInt();
+ for (int i = 0; i < _count; ++i) {
+ Polygon &p = _polygonsBackup[i];
+ p.isPresent = f.readBool();
+ p.verticeCount = f.readInt();
+ p.left = f.readFloat();
+ p.bottom = f.readFloat();
+ p.right = f.readFloat();
+ p.top = f.readFloat();
+ for (int j = 0; j < kPolygonVertexCount; ++j) {
+ p.vertices[j] = f.readVector2();
+ }
+ for (int j = 0; j < kPolygonVertexCount; ++j) {
+ p.vertexType[j] = f.readInt();
+ }
+ }
+
+ for (int i = 0; i < kPolygonCount; ++i) {
+ _polygons[i] = _polygonsBackup[i];
+ }
+
+ for (int i = 0; i < kVertexCount; ++i) {
+ _vertices[i] = f.readVector2();
+ }
+ _verticeCount = f.readInt();
}
diff --git a/engines/bladerunner/obstacles.h b/engines/bladerunner/obstacles.h
index fc06fe6920..b50c51e64c 100644
--- a/engines/bladerunner/obstacles.h
+++ b/engines/bladerunner/obstacles.h
@@ -28,7 +28,8 @@
namespace BladeRunner {
class BladeRunnerEngine;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class Obstacles {
static const int kVertexCount = 150;
@@ -64,7 +65,9 @@ public:
bool find(const Vector3 &from, const Vector3 &to, Vector3 *next) const;
void backup();
void restore();
- void save(SaveFile &f);
+
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/overlays.cpp b/engines/bladerunner/overlays.cpp
index 0f011ad4d1..65ba83f15d 100644
--- a/engines/bladerunner/overlays.cpp
+++ b/engines/bladerunner/overlays.cpp
@@ -59,8 +59,8 @@ Overlays::~Overlays() {
int Overlays::play(const Common::String &name, int loopId, bool loopForever, bool startNow, int a6) {
assert(name.size() <= 12);
- int id = mix_id(name);
- int index = findById(id);
+ int32 hash = MIXArchive::getHash(name);
+ int index = findByHash(hash);
if (index < 0) {
index = findEmpty();
if (index < 0) {
@@ -68,7 +68,7 @@ int Overlays::play(const Common::String &name, int loopId, bool loopForever, boo
}
_videos[index].loaded = true;
_videos[index].name = name;
- _videos[index].id = id;
+ _videos[index].hash = hash;
_videos[index].vqaPlayer = new VQAPlayer(_vm, &_vm->_surfaceFront);
// repeat forever
@@ -87,8 +87,7 @@ int Overlays::play(const Common::String &name, int loopId, bool loopForever, boo
}
void Overlays::remove(const Common::String &name) {
- int id = mix_id(name);
- int index = findById(id);
+ int index = findByHash(MIXArchive::getHash(name));
if (index >= 0) {
resetSingle(index);
}
@@ -113,9 +112,9 @@ void Overlays::tick() {
}
}
-int Overlays::findById(int32 id) const {
+int Overlays::findByHash(int32 hash) const {
for (int i = 0; i < kOverlayVideos; ++i) {
- if (_videos[i].loaded && _videos[i].id == id) {
+ if (_videos[i].loaded && _videos[i].hash == hash) {
return i;
}
}
@@ -138,7 +137,7 @@ void Overlays::resetSingle(int i) {
_videos[i].vqaPlayer = nullptr;
}
_videos[i].loaded = false;
- _videos[i].id = 0;
+ _videos[i].hash = 0;
_videos[i].field2 = -1;
_videos[i].name.clear();
}
@@ -147,18 +146,34 @@ void Overlays::reset() {
_videos.clear();
}
-void Overlays::save(SaveFile &f) {
+void Overlays::save(SaveFileWriteStream &f) {
for (int i = 0; i < kOverlayVideos; ++i) {
// 37 bytes per overlay
Video &ov = _videos[i];
- f.write(ov.loaded);
- f.write(nullptr);
- f.write(ov.name, 13);
- f.write(ov.id);
- f.write(ov.field0);
- f.write(ov.field1);
- f.write(ov.field2);
+ f.writeBool(ov.loaded);
+ f.writeInt(0); // vqaPlayer pointer
+ f.writeStringSz(ov.name, 13);
+ f.writeSint32LE(ov.hash);
+ f.writeInt(ov.field0);
+ f.writeInt(ov.field1);
+ f.writeInt(ov.field2);
+ }
+}
+
+void Overlays::load(SaveFileReadStream &f) {
+ for (int i = 0; i < kOverlayVideos; ++i) {
+ // 37 bytes per overlay
+ Video &ov = _videos[i];
+
+ ov.loaded = f.readBool();
+ f.skip(4); // vqaPlayer pointer
+ ov.vqaPlayer = nullptr;
+ ov.name = f.readStringSz(13);
+ ov.hash = f.readSint32LE();
+ ov.field0 = f.readInt();
+ ov.field1 = f.readInt();
+ ov.field2 = f.readInt();
}
}
diff --git a/engines/bladerunner/overlays.h b/engines/bladerunner/overlays.h
index fc8dfa11d4..405acbc264 100644
--- a/engines/bladerunner/overlays.h
+++ b/engines/bladerunner/overlays.h
@@ -33,7 +33,8 @@ struct Surface;
namespace BladeRunner {
class BladeRunnerEngine;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class VQAPlayer;
class Overlays {
@@ -43,7 +44,7 @@ class Overlays {
bool loaded;
VQAPlayer *vqaPlayer;
Common::String name;
- int32 id;
+ int32 hash;
int field0;
int field1;
int field2;
@@ -62,10 +63,11 @@ public:
void removeAll();
void tick();
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
private:
- int findById(int32 id) const;
+ int findByHash(int32 hash) const;
int findEmpty() const;
void resetSingle(int i);
diff --git a/engines/bladerunner/police_maze.cpp b/engines/bladerunner/police_maze.cpp
deleted file mode 100644
index 223171d0be..0000000000
--- a/engines/bladerunner/police_maze.cpp
+++ /dev/null
@@ -1,64 +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/police_maze.h"
-
-#include "bladerunner/bladerunner.h"
-
-#include "bladerunner/police_maze_track.h"
-#include "bladerunner/savefile.h"
-
-namespace BladeRunner {
-
-PoliceMaze::PoliceMaze(BladeRunnerEngine *vm) : _vm(vm) {
- reset();
-}
-
-PoliceMaze::~PoliceMaze() {
- reset();
-}
-
-bool PoliceMaze::init() {
- return true;
-}
-
-void PoliceMaze::save(SaveFile &f) {
- f.write(_tracksCount);
- f.write(_a2);
- f.write(_a3);
- for (int i = 0; i < 64; ++i) {
- _tracks[i]->save(f);
- }
-}
-
-void PoliceMaze::reset() {
- _tracksCount = 0;
- _a2 = 0;
- _a3 = 0;
- for (int i = 0; i < 64; ++i) {
- _tracks[i] = nullptr;
- }
- _a4 = 0;
- _a5 = 0;
-}
-
-} // End of namespace BladeRunner
diff --git a/engines/bladerunner/police_maze.h b/engines/bladerunner/police_maze.h
deleted file mode 100644
index 4bd06bb868..0000000000
--- a/engines/bladerunner/police_maze.h
+++ /dev/null
@@ -1,54 +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_POLICE_MAZE_H
-#define BLADERUNNER_POLICE_MAZE_H
-
-namespace BladeRunner {
-
-class BladeRunnerEngine;
-class PoliceMazeTrack;
-class SaveFile;
-
-class PoliceMaze {
- BladeRunnerEngine *_vm;
-
- PoliceMazeTrack *_tracks[64];
- int _tracksCount;
- int _a2;
- int _a3;
- int _a4;
- int _a5;
-
-public:
- PoliceMaze(BladeRunnerEngine *vm);
- ~PoliceMaze();
-
- bool init();
-
- void save(SaveFile &f);
- void reset();
-};
-
-} // End of namespace BladeRunner
-
-#endif
diff --git a/engines/bladerunner/police_maze_track.cpp b/engines/bladerunner/police_maze_track.cpp
deleted file mode 100644
index 988f90499c..0000000000
--- a/engines/bladerunner/police_maze_track.cpp
+++ /dev/null
@@ -1,80 +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/police_maze_track.h"
-
-#include "bladerunner/bladerunner.h"
-
-#include "bladerunner/savefile.h"
-
-namespace BladeRunner {
-
-PoliceMazeTrack::PoliceMazeTrack(BladeRunnerEngine *vm) : _vm(vm) {
- reset();
-}
-
-PoliceMazeTrack::~PoliceMazeTrack() {
- reset();
-}
-
-void PoliceMazeTrack::save(SaveFile &f) {
- f.write(_isPresent);
- f.write(_itemId);
- f.write(_count);
- f.write(_dataIndex);
- f.write(_a6);
- f.write(_a7);
- f.write(_pointIndex);
- f.write(_a9);
- f.write(_rotating);
- f.write(_maxAngle);
- f.write(_angleChange);
- f.write(_a13);
-
- for (int i = 0; i < 100; ++i) {
- f.write(_points[i]);
- }
-
- f.write(_a4);
- f.write(_a5);
- }
-
-void PoliceMazeTrack::reset() {
- _isPresent = false;
- _itemId = -1;
- _count = 0;
- _data = 0;
- _dataIndex = 0;
- _a4 = 0;
- _a5 = 0;
- _time = 0;
- _a6 = 0;
- _a7 = 0;
- _pointIndex = 0;
- _a9 = 0;
- _rotating = 0;
- _maxAngle = 0;
- _angleChange = 0;
- _a13 = 1;
-}
-
-} // End of namespace BladeRunner
diff --git a/engines/bladerunner/police_maze_track.h b/engines/bladerunner/police_maze_track.h
deleted file mode 100644
index 9de7a1b624..0000000000
--- a/engines/bladerunner/police_maze_track.h
+++ /dev/null
@@ -1,65 +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_POLICE_MAZE_TRACK_H
-#define BLADERUNNER_POLICE_MAZE_TRACK_H
-
-#include "bladerunner/vector.h"
-
-namespace BladeRunner {
-
-class BladeRunnerEngine;
-class SaveFile;
-
-class PoliceMazeTrack {
- BladeRunnerEngine *_vm;
-
- int _time;
- bool _isPresent;
- int _itemId;
- int _count;
- Vector2 _points[100];
- int _data;
- int _dataIndex;
- int _a4;
- int _a5;
- int _a6;
- int _a7;
- int _pointIndex;
- int _a9;
- int _rotating;
- int _maxAngle;
- int _angleChange;
- int _a13;
-
-public:
- PoliceMazeTrack(BladeRunnerEngine *vm);
- ~PoliceMazeTrack();
-
- void save(SaveFile &f);
-
- void reset();
-};
-
-} // End of namespace BladeRunner
-
-#endif
diff --git a/engines/bladerunner/regions.cpp b/engines/bladerunner/regions.cpp
index 51b2bae2d7..f74186240b 100644
--- a/engines/bladerunner/regions.cpp
+++ b/engines/bladerunner/regions.cpp
@@ -101,12 +101,21 @@ void Regions::enable() {
_enabled = true;
}
-void Regions::save(SaveFile &f) {
- f.write(_enabled);
+void Regions::save(SaveFileWriteStream &f) {
+ f.writeBool(_enabled);
for (int i = 0; i != 10; ++i) {
- f.write(_regions[i].rectangle);
- f.write(_regions[i].type);
- f.write(_regions[i].present);
+ f.writeRect(_regions[i].rectangle);
+ f.writeInt(_regions[i].type);
+ f.writeInt(_regions[i].present);
+ }
+}
+
+void Regions::load(SaveFileReadStream &f) {
+ _enabled = f.readBool();
+ for (int i = 0; i != 10; ++i) {
+ _regions[i].rectangle = f.readRect();
+ _regions[i].type = f.readInt();
+ _regions[i].present = f.readInt();
}
}
diff --git a/engines/bladerunner/regions.h b/engines/bladerunner/regions.h
index ed4dcba1dc..aae3627650 100644
--- a/engines/bladerunner/regions.h
+++ b/engines/bladerunner/regions.h
@@ -30,7 +30,8 @@
namespace BladeRunner {
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class Regions {
friend class Debugger;
@@ -57,7 +58,8 @@ public:
void setEnabled(bool enabled);
void enable();
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/savefile.cpp b/engines/bladerunner/savefile.cpp
index ff1ff75165..3528a6bb82 100644
--- a/engines/bladerunner/savefile.cpp
+++ b/engines/bladerunner/savefile.cpp
@@ -30,91 +30,137 @@
namespace BladeRunner {
-SaveFile::SaveFile(Common::OutSaveFile *saveFile)
- : _saveFile(saveFile),
- _stream(DisposeAfterUse::YES)
-{
+SaveFileWriteStream::SaveFileWriteStream()
+ : MemoryWriteStreamDynamic(DisposeAfterUse::YES) {
}
-void SaveFile::finalize() {
- _saveFile->writeUint32LE(_stream.size() + 4);
- _saveFile->write(_stream.getData(), _stream.size());
- _saveFile->finalize();
+void SaveFileWriteStream::debug(char *p) {
+ write(p, strlen(p) + 1);
}
-void SaveFile::padBytes(int count) {
+void SaveFileWriteStream::padBytes(int count) {
for (int i = 0; i < count; ++i) {
- _stream.writeByte(0);
+ writeByte(0);
}
}
-void SaveFile::write(bool v) {
- _stream.writeUint32LE(v);
+void SaveFileWriteStream::writeInt(int v) {
+ writeUint32LE(v);
}
-void SaveFile::write(int v) {
- _stream.writeUint32LE(v);
+void SaveFileWriteStream::writeFloat(int v) {
+ writeFloatLE(v);
}
-void SaveFile::write(uint32 v) {
- _stream.writeUint32LE(v);
+void SaveFileWriteStream::writeBool(bool v) {
+ writeUint32LE(v);
}
-void SaveFile::write(byte v) {
- _stream.writeByte(v);
+void SaveFileWriteStream::writeStringSz(const Common::String &s, int sz) {
+ assert(s.size() < (uint)sz);
+ write(s.begin(), s.size());
+ padBytes((uint)sz - s.size());
}
-void SaveFile::write(float v) {
- _stream.writeFloatLE(v);
+void SaveFileWriteStream::writeVector2(const Vector2 &v) {
+ writeFloatLE(v.x);
+ writeFloatLE(v.y);
}
-void SaveFile::debug(char *p) {
- _stream.write(p, strlen(p) + 1);
+void SaveFileWriteStream::writeVector3(const Vector3 &v) {
+ writeFloatLE(v.x);
+ writeFloatLE(v.y);
+ writeFloatLE(v.z);
}
-void SaveFile::write(char *p, int sz) {
- _stream.write(p, sz);
+void SaveFileWriteStream::writeRect(const Common::Rect &v) {
+ writeUint32LE(v.left);
+ writeUint32LE(v.top);
+ writeUint32LE(v.right);
+ writeUint32LE(v.bottom);
}
-void SaveFile::write(Common::String &s, int sz) {
- assert(s.size() < (uint)sz);
- _stream.write(s.begin(), s.size());
- padBytes((uint)sz - s.size());
+void SaveFileWriteStream::writeBoundingBox(const BoundingBox &v) {
+ float x0, y0, z0, x1, y1, z1;
+
+ v.getXYZ(&x0, &y0, &z0, &x1, &y1, &z1);
+ writeFloatLE(x0);
+ writeFloatLE(y0);
+ writeFloatLE(z0);
+ writeFloatLE(x1);
+ writeFloatLE(y1);
+ writeFloatLE(z1);
+
+ // Bounding boxes have a lot of extra data that's never actually used
+ for (int i = 0; i != 96; ++i) {
+ writeFloatLE(0.0f);
+ }
}
-void SaveFile::write(const Vector2 &v) {
- _stream.writeFloatLE(v.x);
- _stream.writeFloatLE(v.y);
+SaveFileReadStream::SaveFileReadStream(const byte *dataPtr, uint32 dataSize)
+ : MemoryReadStream(dataPtr, dataSize, DisposeAfterUse::YES) {
}
-void SaveFile::write(const Vector3 &v) {
- _stream.writeFloatLE(v.x);
- _stream.writeFloatLE(v.y);
- _stream.writeFloatLE(v.z);
+int SaveFileReadStream::readInt() {
+ return readUint32LE();
}
-void SaveFile::write(const Common::Rect &v) {
- _stream.writeUint32LE(v.left);
- _stream.writeUint32LE(v.top);
- _stream.writeUint32LE(v.right);
- _stream.writeUint32LE(v.bottom);
+float SaveFileReadStream::readFloat() {
+ return readFloatLE();
}
-void SaveFile::write(const BoundingBox &v) {
+bool SaveFileReadStream::readBool() {
+ return readUint32LE();
+}
+
+Common::String SaveFileReadStream::readStringSz(int sz) {
+ char *buf = (char *)malloc(sz);
+ read(buf, sz);
+ Common::String result = buf;
+ free(buf);
+ return result;
+}
+
+Vector2 SaveFileReadStream::readVector2() {
+ Vector2 result;
+ result.x = readFloatLE();
+ result.y = readFloatLE();
+ return result;
+}
+
+Vector3 SaveFileReadStream::readVector3() {
+ Vector3 result;
+ result.x = readFloatLE();
+ result.y = readFloatLE();
+ result.z = readFloatLE();
+ return result;
+}
+
+Common::Rect SaveFileReadStream::readRect() {
+ Common::Rect result;
+ result.left = readUint32LE();
+ result.top = readUint32LE();
+ result.right = readUint32LE();
+ result.bottom = readUint32LE();
+ return result;
+}
+
+BoundingBox SaveFileReadStream::readBoundingBox() {
float x0, y0, z0, x1, y1, z1;
- v.getXYZ(&x0, &y0, &z0, &x1, &y1, &z1);
- _stream.writeFloatLE(x0);
- _stream.writeFloatLE(y0);
- _stream.writeFloatLE(z0);
- _stream.writeFloatLE(x1);
- _stream.writeFloatLE(y1);
- _stream.writeFloatLE(z1);
+ x0 = readFloatLE();
+ y0 = readFloatLE();
+ z0 = readFloatLE();
+ x1 = readFloatLE();
+ y1 = readFloatLE();
+ z1 = readFloatLE();
// Bounding boxes have a lot of extra data that's never actually used
- for (int i = 0; i != 96; ++i) {
- _stream.writeFloatLE(0.0f);
- }
+ skip(384);
+
+ return BoundingBox(x0, y0, z0, x1, y1, z1);
}
+
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/savefile.h b/engines/bladerunner/savefile.h
index 8c5dc0aa80..4dfdb20bd4 100644
--- a/engines/bladerunner/savefile.h
+++ b/engines/bladerunner/savefile.h
@@ -27,9 +27,9 @@
#include "common/types.h"
namespace Common {
- class OutSaveFile;
- class String;
- struct Rect;
+class OutSaveFile;
+class String;
+struct Rect;
}
namespace BladeRunner {
@@ -38,28 +38,36 @@ class Vector2;
class Vector3;
class BoundingBox;
-class SaveFile {
- Common::OutSaveFile *_saveFile;
- Common::MemoryWriteStreamDynamic _stream;
+class SaveFileWriteStream : public Common::MemoryWriteStreamDynamic {
public:
- SaveFile(Common::OutSaveFile *saveFile);
+ SaveFileWriteStream();
- // bool err();
- void finalize();
+ void debug(char *p);
void padBytes(int count);
- void write(bool v);
- void write(int v);
- void write(uint32 v);
- void write(byte v);
- void write(float v);
- void debug(char *p);
- void write(char *p, int sz);
- void write(Common::String &s, int sz);
- void write(const Vector2 &v);
- void write(const Vector3 &v);
- void write(const Common::Rect &v);
- void write(const BoundingBox &v);
+
+ void writeInt(int v);
+ void writeFloat(int v);
+ void writeBool(bool v);
+ void writeStringSz(const Common::String &s, int sz);
+ void writeVector2(const Vector2 &v);
+ void writeVector3(const Vector3 &v);
+ void writeRect(const Common::Rect &v);
+ void writeBoundingBox(const BoundingBox &v);
+};
+
+class SaveFileReadStream : public Common::MemoryReadStream {
+public:
+ SaveFileReadStream(const byte *dataPtr, uint32 dataSize);
+
+ int readInt();
+ float readFloat();
+ bool readBool();
+ Common::String readStringSz(int sz);
+ Vector2 readVector2();
+ Vector3 readVector3();
+ Common::Rect readRect();
+ BoundingBox readBoundingBox();
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/scene.cpp b/engines/bladerunner/scene.cpp
index d12c85e56b..fe8dbc7b61 100644
--- a/engines/bladerunner/scene.cpp
+++ b/engines/bladerunner/scene.cpp
@@ -331,7 +331,7 @@ void Scene::loopStartSpecial(int specialLoopMode, int loopId, bool immediately)
}
}
-int Scene::findObject(const char *objectName) {
+int Scene::findObject(const Common::String &objectName) {
return _set->findObject(objectName);
}
@@ -377,7 +377,7 @@ void Scene::objectSetIsTarget(int objectId, bool isTarget, bool sceneLoaded) {
}
}
-const char *Scene::objectGetName(int objectId) {
+const Common::String &Scene::objectGetName(int objectId) {
return _set->objectGetName(objectId);
}
@@ -414,20 +414,36 @@ void Scene::loopEndedStatic(void *data, int frame, int loopId) {
((Scene *)data)->loopEnded(frame, loopId);
}
-void Scene::save(SaveFile &f) {
- f.write(_setId);
- f.write(_sceneId);
- f.write(_defaultLoop);
- f.write(_defaultLoopSet);
- f.write(_defaultLoopPreloadedSet);
- f.write(_specialLoopMode);
- f.write(_specialLoop);
- f.write(_nextSetId);
- f.write(_nextSceneId);
- f.write(_frame);
- f.write(_actorStartPosition);
- f.write(_actorStartFacing);
- f.write(_playerWalkedIn);
+void Scene::save(SaveFileWriteStream &f) {
+ f.writeInt(_setId);
+ f.writeInt(_sceneId);
+ f.writeInt(_defaultLoop);
+ f.writeBool(_defaultLoopSet);
+ f.writeBool(_defaultLoopPreloadedSet);
+ f.writeInt(_specialLoopMode);
+ f.writeInt(_specialLoop);
+ f.writeInt(_nextSetId);
+ f.writeInt(_nextSceneId);
+ f.writeInt(_frame);
+ f.writeVector3(_actorStartPosition);
+ f.writeInt(_actorStartFacing);
+ f.writeBool(_playerWalkedIn);
+}
+
+void Scene::load(SaveFileReadStream &f) {
+ _setId = f.readInt();
+ _sceneId = f.readInt();
+ _defaultLoop = f.readInt();
+ _defaultLoopSet = f.readBool();
+ _defaultLoopPreloadedSet = f.readBool();
+ _specialLoopMode = f.readInt();
+ _specialLoop = f.readInt();
+ _nextSetId = f.readInt();
+ _nextSceneId = f.readInt();
+ _frame = f.readInt();
+ _actorStartPosition = f.readVector3();
+ _actorStartFacing = f.readInt();
+ _playerWalkedIn = f.readBool();
}
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/scene.h b/engines/bladerunner/scene.h
index b1963e8c15..0403cd331e 100644
--- a/engines/bladerunner/scene.h
+++ b/engines/bladerunner/scene.h
@@ -25,12 +25,15 @@
#include "bladerunner/vector.h"
+#include "common/str.h"
+
namespace BladeRunner {
class BladeRunnerEngine;
class BoundingBox;
class Regions;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class Set;
class VQAPlayer;
@@ -81,16 +84,17 @@ public:
bool didPlayerWalkIn() { bool r = _playerWalkedIn; _playerWalkedIn = false; return r; }
- int findObject(const char *objectName);
+ int findObject(const Common::String &objectName);
bool objectSetHotMouse(int objectId);
bool objectGetBoundingBox(int objectId, BoundingBox *boundingBox);
void objectSetIsClickable(int objectId, bool isClickable, bool sceneLoaded);
void objectSetIsObstacle(int objectId, bool isObstacle, bool sceneLoaded, bool updateWalkpath);
void objectSetIsObstacleAll(bool isObstacle, bool sceneLoaded);
void objectSetIsTarget(int objectId, bool isTarget, bool sceneLoaded);
- const char *objectGetName(int objectId);
+ const Common::String &objectGetName(int objectId);
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
private:
void loopEnded(int frame, int loopId);
diff --git a/engines/bladerunner/scene_objects.cpp b/engines/bladerunner/scene_objects.cpp
index f68dccc0dd..6857416197 100644
--- a/engines/bladerunner/scene_objects.cpp
+++ b/engines/bladerunner/scene_objects.cpp
@@ -65,16 +65,16 @@ void SceneObjects::clear() {
_count = 0;
}
-bool SceneObjects::addActor(int sceneObjectId, BoundingBox *boundingBox, Common::Rect *screenRectangle, bool isClickable, bool isMoving, bool isTarget, bool isRetired) {
+bool SceneObjects::addActor(int sceneObjectId, const BoundingBox &boundingBox, const Common::Rect &screenRectangle, bool isClickable, bool isMoving, bool isTarget, bool isRetired) {
return addSceneObject(sceneObjectId, kSceneObjectTypeActor, boundingBox, screenRectangle, isClickable, false, 0, isTarget, isMoving, isRetired);
}
-bool SceneObjects::addObject(int sceneObjectId, BoundingBox *boundingBox, bool isClickable, bool isObstacle, uint8 unknown1, bool isTarget) {
+bool SceneObjects::addObject(int sceneObjectId, const BoundingBox &boundingBox, bool isClickable, bool isObstacle, uint8 unknown1, bool isTarget) {
Common::Rect rect(-1, -1, -1, -1);
- return addSceneObject(sceneObjectId, kSceneObjectTypeObject, boundingBox, &rect, isClickable, isObstacle, unknown1, isTarget, false, false);
+ return addSceneObject(sceneObjectId, kSceneObjectTypeObject, boundingBox, rect, isClickable, isObstacle, unknown1, isTarget, false, false);
}
-bool SceneObjects::addItem(int sceneObjectId, BoundingBox *boundingBox, Common::Rect *screenRectangle, bool isTarget, bool isObstacle) {
+bool SceneObjects::addItem(int sceneObjectId, const BoundingBox &boundingBox, const Common::Rect &screenRectangle, bool isTarget, bool isObstacle) {
return addSceneObject(sceneObjectId, kSceneObjectTypeItem, boundingBox, screenRectangle, isObstacle, 0, 0, isTarget, 0, 0);
}
@@ -111,7 +111,7 @@ int SceneObjects::findByXYZ(bool *isClickable, bool *isObstacle, bool *isTarget,
if ((findClickables && sceneObject->isClickable) ||
(findObstacles && sceneObject->isObstacle) ||
(findTargets && sceneObject->isTarget)) {
- BoundingBox boundingBox = *sceneObject->boundingBox;
+ BoundingBox boundingBox = sceneObject->boundingBox;
if (sceneObject->type == kSceneObjectTypeActor) {
boundingBox.expand(-4.0, 0.0, -4.0, 4.0, 0.0, 4.0);
@@ -156,7 +156,7 @@ bool SceneObjects::existsOnXZ(int exceptSceneObjectId, float x, float z, bool mo
if (isObstacle && sceneObject->id != 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;
}
@@ -177,7 +177,7 @@ int SceneObjects::findById(int sceneObjectId) const {
return -1;
}
-bool SceneObjects::addSceneObject(int sceneObjectId, SceneObjectType sceneObjectType, BoundingBox *boundingBox, Common::Rect *screenRectangle, bool isClickable, bool isObstacle, uint8 unknown1, bool isTarget, bool isMoving, bool isRetired) {
+bool SceneObjects::addSceneObject(int sceneObjectId, SceneObjectType sceneObjectType, const BoundingBox &boundingBox, const Common::Rect &screenRectangle, bool isClickable, bool isObstacle, uint8 unknown1, bool isTarget, bool isMoving, bool isRetired) {
int index = findEmpty();
if (index == -1) {
return false;
@@ -195,7 +195,7 @@ bool SceneObjects::addSceneObject(int sceneObjectId, SceneObjectType sceneObject
_sceneObjects[index].isMoving = isMoving;
_sceneObjects[index].isRetired = isRetired;
- float centerZ = (_sceneObjects[index].boundingBox->getZ0() + _sceneObjects[index].boundingBox->getZ1()) / 2.0f;
+ float centerZ = (_sceneObjects[index].boundingBox.getZ0() + _sceneObjects[index].boundingBox.getZ1()) / 2.0f;
float distanceToCamera = fabs(-centerZ - _view->_cameraPosition.y); // y<->z is intentional, not a bug
_sceneObjects[index].distanceToCamera = distanceToCamera;
@@ -247,7 +247,7 @@ bool SceneObjects::isBetween(float sourceX, float sourceZ, float targetX, float
}
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);
Vector2 intersection;
return lineIntersection(Vector2(sourceX, sourceZ), Vector2(targetX, targetZ), Vector2(objectX1, objectZ1), Vector2(objectX2, objectZ1), &intersection)
@@ -265,7 +265,7 @@ bool SceneObjects::isObstacleBetween(const Vector3 &source, const Vector3 &targe
}
float objectX1, objectY1, objectZ1, objectX2, objectY2, objectZ2;
- sceneObject->boundingBox->getXYZ(&objectX1, &objectY1, &objectZ1, &objectX2, &objectY2, &objectZ2);
+ sceneObject->boundingBox.getXYZ(&objectX1, &objectY1, &objectZ1, &objectX2, &objectY2, &objectZ2);
if (84.0f <= objectY1 - source.y || 72.0f >= objectY2 - source.y) {
continue;
@@ -321,31 +321,52 @@ void SceneObjects::updateObstacles() {
const SceneObject *sceneObject = &_sceneObjects[index];
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);
}
}
_vm->_obstacles->backup();
}
-void SceneObjects::save(SaveFile &f) {
- f.write(_count);
+void SceneObjects::save(SaveFileWriteStream &f) {
+ f.writeInt(_count);
for (int i = 0; i < kSceneObjectCount; ++i) {
- f.write(_sceneObjects[i].id);
- f.write(_sceneObjects[i].type);
- f.write(_sceneObjects[i].boundingBox);
- f.write(_sceneObjects[i].screenRectangle);
- f.write(_sceneObjects[i].distanceToCamera);
- f.write(_sceneObjects[i].isPresent);
- f.write(_sceneObjects[i].isClickable);
- f.write(_sceneObjects[i].isObstacle);
- f.write(_sceneObjects[i].unknown1);
- f.write(_sceneObjects[i].isTarget);
- f.write(_sceneObjects[i].isMoving);
- f.write(_sceneObjects[i].isRetired);
+ f.writeInt(_sceneObjects[i].id);
+ f.writeInt(_sceneObjects[i].type);
+ f.writeBoundingBox(_sceneObjects[i].boundingBox);
+ f.writeRect(_sceneObjects[i].screenRectangle);
+ f.writeFloat(_sceneObjects[i].distanceToCamera);
+ f.writeBool(_sceneObjects[i].isPresent);
+ f.writeBool(_sceneObjects[i].isClickable);
+ f.writeBool(_sceneObjects[i].isObstacle);
+ f.writeInt(_sceneObjects[i].unknown1);
+ f.writeBool(_sceneObjects[i].isTarget);
+ f.writeBool(_sceneObjects[i].isMoving);
+ f.writeBool(_sceneObjects[i].isRetired);
}
for (int i = 0; i < kSceneObjectCount; ++i) {
- f.write(_sceneObjectsSortedByDistance[i]);
+ f.writeInt(_sceneObjectsSortedByDistance[i]);
+ }
+}
+
+void SceneObjects::load(SaveFileReadStream &f) {
+ _count = f.readInt();
+ for (int i = 0; i < kSceneObjectCount; ++i) {
+ _sceneObjects[i].id = f.readInt();
+ _sceneObjects[i].type = (SceneObjectType)f.readInt();
+ _sceneObjects[i].boundingBox = f.readBoundingBox();
+ _sceneObjects[i].screenRectangle = f.readRect();
+ _sceneObjects[i].distanceToCamera = f.readFloat();
+ _sceneObjects[i].isPresent = f.readBool();
+ _sceneObjects[i].isClickable = f.readBool();
+ _sceneObjects[i].isObstacle = f.readBool();
+ _sceneObjects[i].unknown1 = f.readInt();
+ _sceneObjects[i].isTarget = f.readBool();
+ _sceneObjects[i].isMoving = f.readBool();
+ _sceneObjects[i].isRetired = f.readBool();
+ }
+ for (int i = 0; i < kSceneObjectCount; ++i) {
+ _sceneObjectsSortedByDistance[i] = f.readInt();
}
}
diff --git a/engines/bladerunner/scene_objects.h b/engines/bladerunner/scene_objects.h
index 2f154db754..a6d552017c 100644
--- a/engines/bladerunner/scene_objects.h
+++ b/engines/bladerunner/scene_objects.h
@@ -30,7 +30,8 @@
namespace BladeRunner {
class BladeRunnerEngine;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class View;
enum SceneObjectType {
@@ -46,18 +47,18 @@ class SceneObjects {
static const int kSceneObjectCount = 115;
struct SceneObject {
- int id;
- SceneObjectType type;
- const BoundingBox *boundingBox;
- const Common::Rect *screenRectangle;
- float distanceToCamera;
- bool isPresent;
- bool isClickable;
- bool isObstacle;
- int unknown1;
- bool isTarget;
- bool isMoving;
- bool isRetired;
+ int id;
+ SceneObjectType type;
+ BoundingBox boundingBox;
+ Common::Rect screenRectangle;
+ float distanceToCamera;
+ bool isPresent;
+ bool isClickable;
+ bool isObstacle;
+ int unknown1;
+ bool isTarget;
+ bool isMoving;
+ bool isRetired;
};
BladeRunnerEngine *_vm;
@@ -71,9 +72,9 @@ public:
SceneObjects(BladeRunnerEngine *vm, View *view);
~SceneObjects();
- bool addActor(int sceneObjectId, BoundingBox *boundingBox, Common::Rect *screenRectangle, bool isClickable, bool isMoving, bool isTarget, bool isRetired);
- bool addObject(int sceneObjectId, BoundingBox *boundingBox, bool isClickable, bool isObstacle, uint8 unknown1, bool isTarget);
- bool addItem(int sceneObjectId, BoundingBox *boundingBox, Common::Rect *screenRectangle, bool isTarget, bool isObstacle);
+ bool addActor(int sceneObjectId, const BoundingBox &boundingBox, const Common::Rect &screenRectangle, bool isClickable, bool isMoving, bool isTarget, bool isRetired);
+ bool addObject(int sceneObjectId, const BoundingBox &boundingBox, bool isClickable, bool isObstacle, uint8 unknown1, bool isTarget);
+ bool addItem(int sceneObjectId, const BoundingBox &boundingBox, const Common::Rect &screenRectangle, bool isTarget, bool isObstacle);
bool remove(int sceneObjectId);
void clear();
int findByXYZ(bool *isClickable, bool *isObstacle, bool *isTarget, Vector3 &position, bool findClickables, bool findObstacles, bool findTargets) const;
@@ -87,10 +88,12 @@ public:
void setIsTarget(int sceneObjectId, bool isTarget);
void updateObstacles();
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
+
private:
int findById(int sceneObjectId) const;
- bool addSceneObject(int sceneObjectId, SceneObjectType sceneObjectType, BoundingBox *boundingBox, Common::Rect *screenRectangle, bool isClickable, bool isObstacle, uint8 unknown1, bool isTarget, bool isMoving, bool isRetired);
+ bool addSceneObject(int sceneObjectId, SceneObjectType sceneObjectType, const BoundingBox &boundingBox, const Common::Rect &screenRectangle, bool isClickable, bool isObstacle, uint8 unknown1, bool isTarget, bool isMoving, bool isRetired);
int findEmpty() const;
};
diff --git a/engines/bladerunner/script/ai_script.cpp b/engines/bladerunner/script/ai_script.cpp
index 257e323c5b..b328824de1 100644
--- a/engines/bladerunner/script/ai_script.cpp
+++ b/engines/bladerunner/script/ai_script.cpp
@@ -22,9 +22,8 @@
#include "bladerunner/script/ai_script.h"
-#include "bladerunner/bladerunner.h"
-
#include "bladerunner/actor.h"
+#include "bladerunner/bladerunner.h"
namespace BladeRunner {
@@ -358,7 +357,7 @@ void AIScripts::setAnimationState(int actor, int animationState, int animationFr
}
-void AIScripts::queryAnimationState(int actor, int *animationState, int *animationFrame, int *animationStateNext, int *nextAnimation) {
+void AIScripts::queryAnimationState(int actor, int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
if (actor >= _actorCount) {
return;
}
@@ -366,7 +365,7 @@ void AIScripts::queryAnimationState(int actor, int *animationState, int *animati
_inScriptCounter++;
if (_AIScripts[actor]) {
_AIScripts[actor]->FledCombat();
- _AIScripts[actor]->QueryAnimationState(animationState, animationFrame, animationStateNext, nextAnimation);
+ _AIScripts[actor]->QueryAnimationState(animationState, animationFrame, animationStateNext, animationNext);
}
_inScriptCounter--;
}
diff --git a/engines/bladerunner/script/ai_script.h b/engines/bladerunner/script/ai_script.h
index 5e782d0820..03789ae542 100644
--- a/engines/bladerunner/script/ai_script.h
+++ b/engines/bladerunner/script/ai_script.h
@@ -61,7 +61,7 @@ public:
virtual bool GoalChanged(int currentGoalNumber, int newGoalNumber) = 0;
virtual bool UpdateAnimation(int *animation, int *frame) = 0;
virtual bool ChangeAnimationMode(int mode) = 0;
- virtual void QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *nextAnimation) = 0;
+ virtual void QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) = 0;
virtual void SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) = 0;
virtual bool ReachedMovementTrackWaypoint(int waypointId) = 0;
virtual void FledCombat() = 0;
@@ -566,7 +566,7 @@ public:
bool reachedMovementTrackWaypoint(int actor, int waypointId);
void updateAnimation(int actor, int *animation, int *frame);
void changeAnimationMode(int actor, int mode);
- void queryAnimationState(int actor, int *animationState, int *animationFrame, int *animationStateNext, int *nextAnimation);
+ void queryAnimationState(int actor, int *animationState, int *animationFrame, int *animationStateNext, int *animationNext);
void setAnimationState(int actor, int animationState, int animationFrame, int animationStateNext, int animationNext);
void fledCombat(int actor);
diff --git a/engines/bladerunner/script/police_maze.cpp b/engines/bladerunner/script/police_maze.cpp
index 3aa3ebbfc8..68bb84a762 100644
--- a/engines/bladerunner/script/police_maze.cpp
+++ b/engines/bladerunner/script/police_maze.cpp
@@ -24,6 +24,7 @@
#include "bladerunner/game_constants.h"
#include "bladerunner/items.h"
#include "bladerunner/mouse.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/scene.h"
#include "bladerunner/scene_objects.h"
#include "bladerunner/script/police_maze.h"
@@ -122,6 +123,24 @@ void PoliceMaze::tick() {
}
}
+void PoliceMaze::save(SaveFileWriteStream &f) {
+ f.writeBool(_isPaused);
+ f.writeBool(_isActive);
+ f.writeBool(_isEnding);
+ for (int i = 0; i < kNumMazeTracks; ++i) {
+ _tracks[i]->save(f);
+ }
+}
+
+void PoliceMaze::load(SaveFileReadStream &f) {
+ _isPaused = f.readBool();
+ _isActive = f.readBool();
+ _isEnding = f.readBool();
+ for (int i = 0; i < kNumMazeTracks; ++i) {
+ _tracks[i]->load(f);
+ }
+}
+
PoliceMazeTargetTrack::PoliceMazeTargetTrack(BladeRunnerEngine *vm) : ScriptBase(vm) {
reset();
}
@@ -139,7 +158,7 @@ void PoliceMazeTargetTrack::reset() {
_timeLeftUpdate = 0;
_timeLeftWait = 0;
_time = 0;
- _isWaiting = false;
+ _isWaiting = false;
_isMoving = false;
_pointIndex = 0;
_pointTarget = 0;
@@ -528,8 +547,8 @@ bool PoliceMazeTargetTrack::tick() {
void PoliceMazeTargetTrack::readdObject(int itemId) {
if (_vm->_sceneObjects->remove(itemId + kSceneObjectOffsetItems)) {
- BoundingBox *boundingBox = _vm->_items->getBoundingBox(itemId);
- Common::Rect *screenRect = _vm->_items->getScreenRectangle(itemId);
+ const BoundingBox &boundingBox = _vm->_items->getBoundingBox(itemId);
+ const Common::Rect &screenRect = _vm->_items->getScreenRectangle(itemId);
bool targetable = _vm->_items->isTarget(itemId);
bool obstacle = _vm->_items->isVisible(itemId);
@@ -537,5 +556,48 @@ void PoliceMazeTargetTrack::readdObject(int itemId) {
}
}
+void PoliceMazeTargetTrack::save(SaveFileWriteStream &f) {
+ f.writeBool(_isPresent);
+ f.writeInt(_itemId);
+ f.writeInt(_pointCount);
+ f.writeInt(_dataIndex);
+ f.writeBool(_isWaiting);
+ f.writeBool(_isMoving);
+ f.writeInt(_pointIndex);
+ f.writeInt(_pointTarget);
+ f.writeBool(_isRotating);
+ f.writeInt(_angleTarget);
+ f.writeInt(_angleDelta);
+ f.writeBool(_isPaused);
+
+ for (int i = 0; i < kNumTrackPoints; ++i) {
+ f.writeVector3(_points[i]);
+ }
+
+ f.writeInt(_timeLeftUpdate);
+ f.writeInt(_timeLeftWait);
+}
+
+void PoliceMazeTargetTrack::load(SaveFileReadStream &f) {
+ _isPresent = f.readBool();
+ _itemId = f.readInt();
+ _pointCount = f.readInt();
+ _dataIndex = f.readInt();
+ _isWaiting = f.readBool();
+ _isMoving = f.readBool();
+ _pointIndex = f.readInt();
+ _pointTarget = f.readInt();
+ _isRotating = f.readBool();
+ _angleTarget = f.readInt();
+ _angleDelta = f.readInt();
+ _isPaused = f.readBool();
+
+ for (int i = 0; i < kNumTrackPoints; ++i) {
+ _points[i] = f.readVector3();
+ }
+
+ _timeLeftUpdate = f.readInt();
+ _timeLeftWait = f.readInt();
+}
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/script/police_maze.h b/engines/bladerunner/script/police_maze.h
index e53d68e373..725fbd4319 100644
--- a/engines/bladerunner/script/police_maze.h
+++ b/engines/bladerunner/script/police_maze.h
@@ -34,25 +34,27 @@ enum {
};
class BladeRunnerEngine;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class PoliceMazeTargetTrack : ScriptBase {
- uint32 _time;
- bool _isPresent;
- int _itemId;
- int _pointCount;
- Vector3 _points[kNumTrackPoints];
+ uint32 _time;
+ bool _isPresent;
+ int _itemId;
+ int _pointCount;
+ Vector3 _points[kNumTrackPoints];
const int *_data;
- int _dataIndex;
- int32 _timeLeftUpdate;
- int32 _timeLeftWait;
- bool _isWaiting;
- int _isMoving;
- int _pointIndex;
- int _pointTarget;
- bool _isRotating;
- int _angleTarget;
- int _angleDelta;
- bool _isPaused;
+ int _dataIndex;
+ int32 _timeLeftUpdate;
+ int32 _timeLeftWait;
+ bool _isWaiting;
+ int _isMoving;
+ int _pointIndex;
+ int _pointTarget;
+ bool _isRotating;
+ int _angleTarget;
+ int _angleDelta;
+ bool _isPaused;
public:
PoliceMazeTargetTrack(BladeRunnerEngine *vm);
@@ -70,6 +72,9 @@ public:
void setTime(uint32 t) { _time = t; }
void readdObject(int itemId);
+
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
};
class PoliceMaze : ScriptBase {
@@ -91,6 +96,9 @@ public:
void clear(bool isLoadingGame);
void setPauseState(bool state);
void activate();
+
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/script/script.cpp b/engines/bladerunner/script/script.cpp
index 6c7d8f5bd9..6d981fe3e3 100644
--- a/engines/bladerunner/script/script.cpp
+++ b/engines/bladerunner/script/script.cpp
@@ -832,8 +832,7 @@ int ScriptBase::Random_Query(int min, int max) {
}
void ScriptBase::Sound_Play(int id, int volume, int panFrom, int panTo, int priority) {
- const char *name = _vm->_gameInfo->getSfxTrack(id);
- _vm->_audioPlayer->playAud(name, volume, panFrom, panTo, priority);
+ _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(id), volume, panFrom, panTo, priority);
}
void ScriptBase::Sound_Play_Speech_Line(int actorId, int sentenceId, int volume, int a4, int priority) {
@@ -899,8 +898,7 @@ void ScriptBase::Footstep_Sound_Override_Off() {
}
bool ScriptBase::Music_Play(int musicId, int volume, int pan, int timeFadeIn, int timePlay, int loop, int timeFadeOut) {
- const char *musicName = _vm->_gameInfo->getMusicTrack(musicId);
- return _vm->_music->play(musicName, volume, pan, timeFadeIn, timePlay, loop, timeFadeOut);
+ return _vm->_music->play(_vm->_gameInfo->getMusicTrack(musicId), volume, pan, timeFadeIn, timePlay, loop, timeFadeOut);
}
void ScriptBase::Music_Adjust(int volume, int pan, int delay) {
diff --git a/engines/bladerunner/script/script.h b/engines/bladerunner/script/script.h
index 5e1e160498..09c372d009 100644
--- a/engines/bladerunner/script/script.h
+++ b/engines/bladerunner/script/script.h
@@ -23,11 +23,11 @@
#ifndef BLADERUNNER_SCRIPT_H
#define BLADERUNNER_SCRIPT_H
-#include "common/str.h"
-
#include "bladerunner/bladerunner.h"
#include "bladerunner/game_constants.h"
+#include "common/str.h"
+
namespace BladeRunner {
class BladeRunnerEngine;
diff --git a/engines/bladerunner/set.cpp b/engines/bladerunner/set.cpp
index 6a83294c4c..ac026a4d76 100644
--- a/engines/bladerunner/set.cpp
+++ b/engines/bladerunner/set.cpp
@@ -68,8 +68,10 @@ bool Set::open(const Common::String &name) {
_objectCount = s->readUint32LE();
assert(_objectCount <= 85);
+ char buf[20];
for (int i = 0; i < _objectCount; ++i) {
- s->read(_objects[i].name, 20);
+ s->read(buf, sizeof(buf));
+ _objects[i].name = buf;
float x0, y0, z0, x1, y1, z1;
x0 = s->readFloatLE();
@@ -96,7 +98,9 @@ bool Set::open(const Common::String &name) {
for (int i = 0; i < _walkboxCount; ++i) {
float x, z;
- s->read(_walkboxes[i].name, 20);
+ s->read(buf, sizeof(buf));
+ _walkboxes[i].name = buf;
+
_walkboxes[i].altitude = s->readFloatLE();
_walkboxes[i].vertexCount = s->readUint32LE();
@@ -131,7 +135,7 @@ bool Set::open(const Common::String &name) {
void Set::addObjectsToScene(SceneObjects *sceneObjects) const {
for (int i = 0; i < _objectCount; i++) {
- sceneObjects->addObject(i + kSceneObjectOffsetObjects, &_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);
}
}
@@ -209,15 +213,14 @@ int Set::findWalkbox(float x, float z) const {
return result;
}
-int Set::findObject(const char *objectName) const {
- int i;
- for (i = 0; i < (int)_objectCount; i++) {
- if (scumm_stricmp(objectName, _objects[i].name) == 0) {
+int Set::findObject(const Common::String &objectName) const {
+ for (int i = 0; i < _objectCount; ++i) {
+ if (objectName.compareToIgnoreCase(_objects[i].name) == 0) {
return i;
}
}
- debug("Set::findObject didn't find \"%s\"", objectName);
+ debug("Set::findObject didn't find \"%s\"", objectName.c_str());
return -1;
}
@@ -258,7 +261,7 @@ void Set::objectSetIsTarget(int objectId, bool isTarget) {
_objects[objectId].isTarget = isTarget;
}
-const char *Set::objectGetName(int objectId) const {
+const Common::String &Set::objectGetName(int objectId) const {
return _objects[objectId].name;
}
@@ -330,39 +333,73 @@ int Set::getWalkboxSoundRunRight(int walkboxId) const {
return getWalkboxSoundWalkRight(walkboxId);
}
-void Set::save(SaveFile &f) {
- f.write(_loaded);
- f.write(_objectCount);
- f.write(_walkboxCount);
+void Set::save(SaveFileWriteStream &f) {
+ f.writeBool(_loaded);
+ f.writeInt(_objectCount);
+ f.writeInt(_walkboxCount);
+
+ for (int i = 0; i != _objectCount; ++i) {
+ f.writeStringSz(_objects[i].name, 20);
+ f.writeBoundingBox(_objects[i].bbox);
+ f.writeBool(_objects[i].isObstacle);
+ f.writeBool(_objects[i].isClickable);
+ f.writeBool(_objects[i].isHotMouse);
+ f.writeInt(_objects[i].unknown1);
+ f.writeBool(_objects[i].isTarget);
+ }
+
+ for (int i = 0; i != _walkboxCount; ++i) {
+ f.writeStringSz(_walkboxes[i].name, 20);
+ f.writeFloat(_walkboxes[i].altitude);
+ f.writeInt(_walkboxes[i].vertexCount);
+ for (int j = 0; j != 8; ++j) {
+ f.writeVector3(_walkboxes[i].vertices[j]);
+
+ // In BLADE.EXE vertices are a vec5
+ f.writeInt(0);
+ f.writeInt(0);
+ }
+ }
+
+ for (int i = 0; i != 85; ++i) {
+ f.writeInt(_walkboxStepSound[i]);
+ }
+
+ f.writeInt(_footstepSoundOverride);
+}
+
+void Set::load(SaveFileReadStream &f) {
+ _loaded = f.readBool();
+ _objectCount = f.readInt();
+ _walkboxCount = f.readInt();
for (int i = 0; i != _objectCount; ++i) {
- f.write(_objects[i].name, 20);
- f.write(_objects[i].bbox);
- f.write(_objects[i].isObstacle);
- f.write(_objects[i].isClickable);
- f.write(_objects[i].isHotMouse);
- f.write(_objects[i].unknown1);
- f.write(_objects[i].isTarget);
+ _objects[i].name = f.readStringSz(20);
+ _objects[i].bbox = f.readBoundingBox();
+ _objects[i].isObstacle = f.readBool();
+ _objects[i].isClickable = f.readBool();
+ _objects[i].isHotMouse = f.readBool();
+ _objects[i].unknown1 = f.readInt();
+ _objects[i].isTarget = f.readBool();
}
for (int i = 0; i != _walkboxCount; ++i) {
- f.write(_walkboxes[i].name, 20);
- f.write(_walkboxes[i].altitude);
- f.write(_walkboxes[i].vertexCount);
+ _walkboxes[i].name = f.readStringSz(20);
+ _walkboxes[i].altitude = f.readFloat();
+ _walkboxes[i].vertexCount = f.readInt();
for (int j = 0; j != 8; ++j) {
- f.write(_walkboxes[i].vertices[j]);
+ _walkboxes[i].vertices[j] = f.readVector3();
// In BLADE.EXE vertices are a vec5
- f.write(0);
- f.write(0);
+ f.skip(8);
}
}
for (int i = 0; i != 85; ++i) {
- f.write(_walkboxStepSound[i]);
+ _walkboxStepSound[i] = f.readInt();
}
- f.write(_footstepSoundOverride);
+ _footstepSoundOverride = f.readInt();
}
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/set.h b/engines/bladerunner/set.h
index 7989ef1e1a..c6c1081196 100644
--- a/engines/bladerunner/set.h
+++ b/engines/bladerunner/set.h
@@ -32,29 +32,30 @@ namespace BladeRunner {
class BladeRunnerEngine;
-class VQADecoder;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class SetEffects;
class SceneObjects;
+class VQADecoder;
class Set {
friend class Debugger;
struct Object {
- char name[20];
- BoundingBox bbox;
- uint8 isObstacle;
- uint8 isClickable;
- uint8 isHotMouse;
- uint8 isTarget;
- uint8 unknown1;
+ Common::String name;
+ BoundingBox bbox;
+ uint8 isObstacle;
+ uint8 isClickable;
+ uint8 isHotMouse;
+ uint8 isTarget;
+ uint8 unknown1;
};
struct Walkbox {
- char name[20];
- float altitude;
- int vertexCount;
- Vector3 vertices[8];
+ Common::String name;
+ float altitude;
+ int vertexCount;
+ Vector3 vertices[8];
};
BladeRunnerEngine *_vm;
@@ -83,14 +84,14 @@ public:
float getAltitudeAtXZ(float x, float z, bool *inWalkbox) const;
int findWalkbox(float x, float z) const;
- int findObject(const char *objectName) const;
+ int findObject(const Common::String &objectName) const;
bool objectSetHotMouse(int objectId) const;
bool objectGetBoundingBox(int objectId, BoundingBox *boundingBox) 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;
+ const Common::String &objectGetName(int objectId) const;
void setWalkboxStepSound(int walkboxId, int soundId);
void setFoodstepSoundOverride(int soundId);
@@ -101,7 +102,8 @@ public:
int getWalkboxSoundRunLeft(int walkboxId) const;
int getWalkboxSoundRunRight(int walkboxId) const;
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
private:
static bool isXZInWalkbox(float x, float z, const Walkbox &walkbox);
diff --git a/engines/bladerunner/set_effects.cpp b/engines/bladerunner/set_effects.cpp
index 5c7b2487a8..3d46e41e7b 100644
--- a/engines/bladerunner/set_effects.cpp
+++ b/engines/bladerunner/set_effects.cpp
@@ -104,7 +104,7 @@ void SetEffects::setFadeDensity(float density) {
_fadeDensity = density;
}
-void SetEffects::setFogColor(const char *fogName, float r, float g, float b) {
+void SetEffects::setFogColor(const Common::String &fogName, float r, float g, float b) {
Fog *fog = findFog(fogName);
if (fog == nullptr) {
return;
@@ -115,7 +115,7 @@ void SetEffects::setFogColor(const char *fogName, float r, float g, float b) {
fog->_fogColor.b = b;
}
-void SetEffects::setFogDensity(const char *fogName, float density) {
+void SetEffects::setFogDensity(const Common::String &fogName, float density) {
Fog *fog = findFog(fogName);
if (fog == nullptr) {
return;
@@ -151,7 +151,7 @@ void SetEffects::calculateColor(Vector3 viewPosition, Vector3 position, float *o
outColor->b = outColor->b * (1.0f - _fadeDensity) + _fadeColor.b * _fadeDensity;
}
-Fog *SetEffects::findFog(const char *fogName) const {
+Fog *SetEffects::findFog(const Common::String &fogName) const {
if (!_fogs) {
return nullptr;
}
@@ -159,7 +159,7 @@ Fog *SetEffects::findFog(const char *fogName) const {
Fog *fog = _fogs;
while (fog != nullptr) {
- if (strcmp(fogName, fog->_name) == 0) {
+ if (fogName.compareTo(fog->_name) == 0) {
break;
}
fog = fog->_next;
diff --git a/engines/bladerunner/set_effects.h b/engines/bladerunner/set_effects.h
index 81d7b93149..6bd139c4d6 100644
--- a/engines/bladerunner/set_effects.h
+++ b/engines/bladerunner/set_effects.h
@@ -53,13 +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 Common::String &fogName, float r, float g, float b);
+ void setFogDensity(const Common::String &fogName, float density);
void calculateColor(Vector3 viewPosition, Vector3 position, float *outCoeficient, Color *outColor) const;
private:
- Fog *findFog(const char *fogName) const;
+ Fog *findFog(const Common::String &fogName) const;
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/settings.cpp b/engines/bladerunner/settings.cpp
index e4db0b81ea..071adf6dd5 100644
--- a/engines/bladerunner/settings.cpp
+++ b/engines/bladerunner/settings.cpp
@@ -22,9 +22,12 @@
#include "bladerunner/settings.h"
+#include "bladerunner/actor.h"
#include "bladerunner/ambient_sounds.h"
#include "bladerunner/bladerunner.h"
#include "bladerunner/chapters.h"
+#include "bladerunner/game_constants.h"
+#include "bladerunner/game_info.h"
#include "bladerunner/music.h"
#include "bladerunner/savefile.h"
#include "bladerunner/scene.h"
@@ -118,7 +121,19 @@ bool Settings::openNewScene() {
_scene = newScene;
if (!_loadingGame && currentSet != newSet) {
- // TODO: Reset actors for new set
+ for (int i = 0; i < (int)_vm->_gameInfo->getActorCount(); ++i) {
+ Actor *actor = _vm->_actors[i];
+ if (i != kActorMcCoy && actor->getSetId() == currentSet) {
+ if (!actor->isRetired()) {
+ actor->stopWalking(false);
+ actor->movementTrackWaypointReached();
+ }
+ if (actor->inCombat()) {
+ actor->setSetId(kSetFreeSlotG);
+ actor->combatModeOff();
+ }
+ }
+ }
}
_loadingGame = false;
@@ -185,16 +200,29 @@ void Settings::setLearyMode(bool learyMode) {
_learyMode = learyMode;
}
-void Settings::save(SaveFile &f) {
- f.write(_scene);
- f.write(_set);
- f.write(_chapter);
- f.write(_playerAgenda);
- f.write(_unk0);
- f.write(_difficulty);
- f.write(_ammoType);
+void Settings::save(SaveFileWriteStream &f) {
+ f.writeInt(_scene);
+ f.writeInt(_set);
+ f.writeInt(_chapter);
+ f.writeInt(_playerAgenda);
+ f.writeInt(_unk0);
+ f.writeInt(_difficulty);
+ f.writeInt(_ammoType);
+ for (int i = 0; i != 3; ++i) {
+ f.writeInt(_ammoAmounts[i]);
+ }
+}
+
+void Settings::load(SaveFileReadStream &f) {
+ _scene = f.readInt();
+ _set = f.readInt();
+ _chapter = f.readInt();
+ _playerAgenda = f.readInt();
+ _unk0 = f.readInt();
+ _difficulty = f.readInt();
+ _ammoType = f.readInt();
for (int i = 0; i != 3; ++i) {
- f.write(_ammoAmounts[i]);
+ _ammoAmounts[i] = f.readInt();
}
}
diff --git a/engines/bladerunner/settings.h b/engines/bladerunner/settings.h
index bc1c25553c..413786e2e5 100644
--- a/engines/bladerunner/settings.h
+++ b/engines/bladerunner/settings.h
@@ -26,7 +26,8 @@
namespace BladeRunner {
class BladeRunnerEngine;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
enum PlayerAgenda {
kPlayerAgendaPolite = 0,
@@ -53,7 +54,7 @@ class Settings {
bool _startingGame;
bool _loadingGame;
- int _unk1;
+ // int _unk1;
int _fullHDFrames;
int _mst3k;
@@ -91,6 +92,18 @@ public:
return _newSet;
}
+ int getScene() const {
+ return _scene;
+ }
+
+ int getSet() const {
+ return _set;
+ }
+
+ int getChapter() const {
+ return _chapter;
+ }
+
void setChapter(int newChapter) {
_chapterChanged = true;
_newChapter = newChapter;
@@ -124,7 +137,8 @@ public:
bool getLearyMode() const;
void setLearyMode(bool learyMode);
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/text_resource.cpp b/engines/bladerunner/text_resource.cpp
index 2a4840c833..8f54f8a976 100644
--- a/engines/bladerunner/text_resource.cpp
+++ b/engines/bladerunner/text_resource.cpp
@@ -46,11 +46,11 @@ TextResource::~TextResource() {
bool TextResource::open(const Common::String &name) {
assert(name.size() <= 8);
- char resName[13];
- sprintf(resName, "%s.TR%s", name.c_str(), _vm->_languageCode);
+ Common::String resName = Common::String::format("%s.TR%s", name.c_str(), _vm->_languageCode.c_str());
Common::ScopedPtr<Common::SeekableReadStream> s(_vm->getResourceStream(resName));
- if (!s)
+ if (!s) {
return false;
+ }
_count = s->readUint32LE();
diff --git a/engines/bladerunner/ui/elevator.cpp b/engines/bladerunner/ui/elevator.cpp
index 3f668efd75..7a6ab3ca35 100644
--- a/engines/bladerunner/ui/elevator.cpp
+++ b/engines/bladerunner/ui/elevator.cpp
@@ -315,8 +315,7 @@ void Elevator::mouseOutCallback(int, void *self) {
void Elevator::mouseDownCallback(int, void *self) {
Elevator *elevator = ((Elevator *)self);
- const char *name = elevator->_vm->_gameInfo->getSfxTrack(515);
- elevator->_vm->_audioPlayer->playAud(name, 100, 0, 0, 50, 0);
+ elevator->_vm->_audioPlayer->playAud(elevator->_vm->_gameInfo->getSfxTrack(515), 100, 0, 0, 50, 0);
}
void Elevator::mouseUpCallback(int buttonId, void *self) {
diff --git a/engines/bladerunner/ui/kia.cpp b/engines/bladerunner/ui/kia.cpp
index 86fdc9254a..756f1bd2cd 100644
--- a/engines/bladerunner/ui/kia.cpp
+++ b/engines/bladerunner/ui/kia.cpp
@@ -350,7 +350,7 @@ void KIA::tick() {
_shapes->get(47)->draw(_vm->_surfaceFront, 182, 446);
}
}
- _vm->_mainFont->drawColor("1.00", _vm->_surfaceFront, 438, 471, 0x1CE7);
+ _vm->_mainFont->drawColor("1.00", _vm->_surfaceFront, 438, 471, 0x1CE7); // TODO: 1.01 for DVD version
if (!_transitionId) {
_buttons->drawTooltip(_vm->_surfaceFront, mouse.x, mouse.y);
}
diff --git a/engines/bladerunner/ui/kia_log.cpp b/engines/bladerunner/ui/kia_log.cpp
index 51b922a8f7..7f75f2e944 100644
--- a/engines/bladerunner/ui/kia_log.cpp
+++ b/engines/bladerunner/ui/kia_log.cpp
@@ -55,7 +55,7 @@ void KIALog::add(int type, int dataSize, const void *data) {
_entries[_currentIndex].dataSize = dataSize;
if (dataSize > 0) {
- char *dataCopy = new char[dataSize];
+ unsigned char *dataCopy = new unsigned char[dataSize];
memcpy(dataCopy, data, dataSize);
_entries[_currentIndex].data = dataCopy;
} else {
diff --git a/engines/bladerunner/ui/kia_log.h b/engines/bladerunner/ui/kia_log.h
index 4a89492817..99c834e3f0 100644
--- a/engines/bladerunner/ui/kia_log.h
+++ b/engines/bladerunner/ui/kia_log.h
@@ -33,7 +33,7 @@ class KIALog {
struct Entry {
int type;
int dataSize;
- const char *data;
+ const unsigned char *data;
};
BladeRunnerEngine *_vm;
diff --git a/engines/bladerunner/ui/spinner.cpp b/engines/bladerunner/ui/spinner.cpp
index 1f8f197926..9e491f719c 100644
--- a/engines/bladerunner/ui/spinner.cpp
+++ b/engines/bladerunner/ui/spinner.cpp
@@ -263,11 +263,17 @@ void Spinner::resume() {
_vqaPlayer->setLoop(1, -1, kLoopSetModeJustStart, nullptr, nullptr);
}
-void Spinner::save(SaveFile &f) {
+void Spinner::save(SaveFileWriteStream &f) {
assert(!_isOpen);
for (int i = 0; i != kSpinnerDestinations; ++i) {
- f.write(_isDestinationSelectable[i]);
+ f.writeBool(_isDestinationSelectable[i]);
+ }
+}
+
+void Spinner::load(SaveFileReadStream &f) {
+ for (int i = 0; i != kSpinnerDestinations; ++i) {
+ _isDestinationSelectable[i] = f.readBool();
}
}
diff --git a/engines/bladerunner/ui/spinner.h b/engines/bladerunner/ui/spinner.h
index 24f66ed4db..d2d666e8e1 100644
--- a/engines/bladerunner/ui/spinner.h
+++ b/engines/bladerunner/ui/spinner.h
@@ -29,7 +29,8 @@
namespace BladeRunner {
class BladeRunnerEngine;
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class Shape;
class UIImagePicker;
class VQAPlayer;
@@ -71,7 +72,8 @@ public:
void reset();
void resume();
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
private:
static void mouseUpCallback(int, void *);
diff --git a/engines/bladerunner/ui/ui_scroll_box.cpp b/engines/bladerunner/ui/ui_scroll_box.cpp
index 6bd4dabdd4..8621039dd6 100644
--- a/engines/bladerunner/ui/ui_scroll_box.cpp
+++ b/engines/bladerunner/ui/ui_scroll_box.cpp
@@ -481,7 +481,7 @@ void UIScrollBox::draw(Graphics::Surface &surface) {
}
if (_center) {
- x = (_rect.width() - _vm->_mainFont->getTextWidth(_lines[i]->text)) / 2;
+ x = _rect.left + (_rect.width() - _vm->_mainFont->getTextWidth(_lines[i]->text)) / 2;
}
_vm->_mainFont->drawColor(_lines[i]->text, surface, x, y, color);
diff --git a/engines/bladerunner/waypoints.cpp b/engines/bladerunner/waypoints.cpp
index 0783af8e07..bf2f09b8a6 100644
--- a/engines/bladerunner/waypoints.cpp
+++ b/engines/bladerunner/waypoints.cpp
@@ -91,13 +91,23 @@ float Waypoints::getZ(int waypointId) const {
return _waypoints[waypointId].position.z;
}
-void Waypoints::save(SaveFile &f) {
- f.write(_count);
+void Waypoints::save(SaveFileWriteStream &f) {
+ f.writeInt(_count);
for (int i = 0; i < _count; ++i) {
Waypoint &w = _waypoints[i];
- f.write(w.setId);
- f.write(w.position);
- f.write(w.present);
+ f.writeInt(w.setId);
+ f.writeVector3(w.position);
+ f.writeInt(w.present);
+ }
+}
+
+void Waypoints::load(SaveFileReadStream &f) {
+ _count = f.readInt();
+ for (int i = 0; i < _count; ++i) {
+ Waypoint &w = _waypoints[i];
+ w.setId = f.readInt();
+ w.position = f.readVector3();
+ w.present = f.readInt();
}
}
diff --git a/engines/bladerunner/waypoints.h b/engines/bladerunner/waypoints.h
index 9159301cfe..6bbe8d3db4 100644
--- a/engines/bladerunner/waypoints.h
+++ b/engines/bladerunner/waypoints.h
@@ -30,7 +30,8 @@
namespace BladeRunner {
-class SaveFile;
+class SaveFileReadStream;
+class SaveFileWriteStream;
class Waypoints {
friend class Debugger;
@@ -58,7 +59,8 @@ public:
bool set(int waypointId, int setId, Vector3 position);
bool reset(int waypointId);
- void save(SaveFile &f);
+ void save(SaveFileWriteStream &f);
+ void load(SaveFileReadStream &f);
};
} // End of namespace BladeRunner