aboutsummaryrefslogtreecommitdiff
path: root/engines/bladerunner
diff options
context:
space:
mode:
authorThomas Fach-Pedersen2018-03-17 16:14:48 +0100
committerPeter Kohaut2018-03-24 17:07:06 +0100
commit2a646f8cc287a98f90e561ce8072c2af4322fd22 (patch)
tree8511469fd92c125a91c71b246bf122c45b425030 /engines/bladerunner
parenta70c59f90d43ce31c548c68416bf0ab5385f15a9 (diff)
downloadscummvm-rg350-2a646f8cc287a98f90e561ce8072c2af4322fd22.tar.gz
scummvm-rg350-2a646f8cc287a98f90e561ce8072c2af4322fd22.tar.bz2
scummvm-rg350-2a646f8cc287a98f90e561ce8072c2af4322fd22.zip
BLADERUNNER: Save game methods
Diffstat (limited to 'engines/bladerunner')
-rw-r--r--engines/bladerunner/actor.cpp77
-rw-r--r--engines/bladerunner/actor.h4
-rw-r--r--engines/bladerunner/actor_clues.cpp19
-rw-r--r--engines/bladerunner/actor_clues.h3
-rw-r--r--engines/bladerunner/actor_combat.cpp26
-rw-r--r--engines/bladerunner/actor_combat.h3
-rw-r--r--engines/bladerunner/actor_dialogue_queue.cpp26
-rw-r--r--engines/bladerunner/actor_dialogue_queue.h4
-rw-r--r--engines/bladerunner/actor_walk.cpp22
-rw-r--r--engines/bladerunner/actor_walk.h2
-rw-r--r--engines/bladerunner/ambient_sounds.cpp37
-rw-r--r--engines/bladerunner/ambient_sounds.h3
-rw-r--r--engines/bladerunner/bladerunner.cpp94
-rw-r--r--engines/bladerunner/bladerunner.h5
-rw-r--r--engines/bladerunner/boundingbox.cpp14
-rw-r--r--engines/bladerunner/boundingbox.h4
-rw-r--r--engines/bladerunner/combat.cpp12
-rw-r--r--engines/bladerunner/combat.h12
-rw-r--r--engines/bladerunner/crimes_database.cpp8
-rw-r--r--engines/bladerunner/crimes_database.h3
-rw-r--r--engines/bladerunner/dialogue_menu.cpp25
-rw-r--r--engines/bladerunner/dialogue_menu.h5
-rw-r--r--engines/bladerunner/game_flags.cpp10
-rw-r--r--engines/bladerunner/game_flags.h4
-rw-r--r--engines/bladerunner/item.cpp23
-rw-r--r--engines/bladerunner/item.h3
-rw-r--r--engines/bladerunner/items.cpp16
-rw-r--r--engines/bladerunner/items.h3
-rw-r--r--engines/bladerunner/module.mk3
-rw-r--r--engines/bladerunner/movement_track.cpp16
-rw-r--r--engines/bladerunner/movement_track.h4
-rw-r--r--engines/bladerunner/obstacles.cpp32
-rw-r--r--engines/bladerunner/obstacles.h15
-rw-r--r--engines/bladerunner/overlays.cpp22
-rw-r--r--engines/bladerunner/overlays.h18
-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.cpp11
-rw-r--r--engines/bladerunner/regions.h4
-rw-r--r--engines/bladerunner/savefile.cpp120
-rw-r--r--engines/bladerunner/savefile.h67
-rw-r--r--engines/bladerunner/scene.cpp18
-rw-r--r--engines/bladerunner/scene.h3
-rw-r--r--engines/bladerunner/scene_objects.cpp22
-rw-r--r--engines/bladerunner/scene_objects.h3
-rw-r--r--engines/bladerunner/script/ai_script.cpp27
-rw-r--r--engines/bladerunner/script/ai_script.h2
-rw-r--r--engines/bladerunner/set.cpp38
-rw-r--r--engines/bladerunner/set.h4
-rw-r--r--engines/bladerunner/settings.cpp31
-rw-r--r--engines/bladerunner/settings.h8
-rw-r--r--engines/bladerunner/ui/spinner.cpp9
-rw-r--r--engines/bladerunner/ui/spinner.h5
-rw-r--r--engines/bladerunner/waypoints.cpp12
-rw-r--r--engines/bladerunner/waypoints.h4
57 files changed, 1197 insertions, 31 deletions
diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp
index b45e6e2114..aae1085834 100644
--- a/engines/bladerunner/actor.cpp
+++ b/engines/bladerunner/actor.cpp
@@ -32,6 +32,7 @@
#include "bladerunner/items.h"
#include "bladerunner/mouse.h"
#include "bladerunner/movement_track.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/scene.h"
#include "bladerunner/scene_objects.h"
#include "bladerunner/script/scene_script.h"
@@ -1225,4 +1226,80 @@ 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);
+
+ for (int i = 0; i < 7; ++i) {
+ f.write(_timersLeft[i]);
+ }
+
+ uint32 now = _vm->getTotalPlayTime(); // TODO: should be last lock time
+ for (int i = 0; i < 7; ++i) {
+ f.write(_timersLast[i] - now);
+ }
+
+ int actorCount = _vm->_gameInfo->getActorCount();
+ for (int i = 0; i != actorCount; ++i) {
+ f.write(_friendlinessToOther[i]);
+ }
+
+ _clues->save(f);
+
+ _movementTrack->save(f);
+
+ _walkInfo->save(f);
+
+ _bbox->save(f);
+
+ _combatInfo->save(f);
+ f.write(_animationModeCombatIdle);
+ f.write(_animationModeCombatWalk);
+ f.write(_animationModeCombatRun);
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/actor.h b/engines/bladerunner/actor.h
index e381f6818e..55ffc4f30e 100644
--- a/engines/bladerunner/actor.h
+++ b/engines/bladerunner/actor.h
@@ -36,6 +36,7 @@ class ActorWalk;
class BladeRunnerEngine;
class BoundingBox;
class MovementTrack;
+class SaveFile;
class View;
class Actor {
@@ -256,6 +257,9 @@ 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 39fbc77d4e..89db6feb47 100644
--- a/engines/bladerunner/actor_clues.cpp
+++ b/engines/bladerunner/actor_clues.cpp
@@ -25,6 +25,7 @@
#include "bladerunner/bladerunner.h"
#include "bladerunner/game_info.h"
#include "bladerunner/crimes_database.h"
+#include "bladerunner/savefile.h"
#include "common/debug.h"
@@ -216,6 +217,24 @@ void ActorClues::remove(int index) {
_clues[index].field8 = 0;
}
+void ActorClues::save(SaveFile &f) {
+ f.write(_count);
+ f.write(_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);
+ }
+}
+
bool ActorClues::exists(int clueId) const {
return findClueIndex(clueId) != -1;
}
diff --git a/engines/bladerunner/actor_clues.h b/engines/bladerunner/actor_clues.h
index b2b39d8b89..03ccff20fd 100644
--- a/engines/bladerunner/actor_clues.h
+++ b/engines/bladerunner/actor_clues.h
@@ -28,6 +28,7 @@
namespace BladeRunner {
class BladeRunnerEngine;
+class SaveFile;
class ActorClues {
struct Clue {
@@ -74,7 +75,7 @@ public:
void removeAll();
- //savegame
+ void save(SaveFile &f);
//loadgame
private:
diff --git a/engines/bladerunner/actor_combat.cpp b/engines/bladerunner/actor_combat.cpp
index aa8e55b28c..7a60d6d85a 100644
--- a/engines/bladerunner/actor_combat.cpp
+++ b/engines/bladerunner/actor_combat.cpp
@@ -29,6 +29,7 @@
#include "bladerunner/game_constants.h"
#include "bladerunner/game_info.h"
#include "bladerunner/movement_track.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/scene.h"
#include "bladerunner/scene_objects.h"
#include "bladerunner/script/ai_script.h"
@@ -49,6 +50,31 @@ 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;
diff --git a/engines/bladerunner/actor_combat.h b/engines/bladerunner/actor_combat.h
index 42ef7de9a6..a621c3d6ff 100644
--- a/engines/bladerunner/actor_combat.h
+++ b/engines/bladerunner/actor_combat.h
@@ -28,6 +28,7 @@
namespace BladeRunner {
class BladeRunnerEngine;
+class SaveFile;
class ActorCombat {
BladeRunnerEngine *_vm;
@@ -64,6 +65,8 @@ public:
void combatOff();
void tick();
+
+ void save(SaveFile &f);
void hitAttempt();
diff --git a/engines/bladerunner/actor_dialogue_queue.cpp b/engines/bladerunner/actor_dialogue_queue.cpp
index dbf5598a52..5f0ad60426 100644
--- a/engines/bladerunner/actor_dialogue_queue.cpp
+++ b/engines/bladerunner/actor_dialogue_queue.cpp
@@ -26,6 +26,7 @@
#include "bladerunner/actor.h"
#include "bladerunner/audio_speech.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/scene.h"
#include "bladerunner/script/scene_script.h"
@@ -159,6 +160,30 @@ void ActorDialogueQueue::tick() {
}
}
+void ActorDialogueQueue::save(SaveFile &f) {
+ int count = (int)_entries.size();
+ f.write(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.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.write(_timeLast);
+}
+
void ActorDialogueQueue::clear() {
_entries.clear();
_isNotPause = false;
@@ -170,4 +195,5 @@ void ActorDialogueQueue::clear() {
_delay = 0;
_timeLast = 0;
}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/actor_dialogue_queue.h b/engines/bladerunner/actor_dialogue_queue.h
index 841ca8a48e..e26b6cf1a1 100644
--- a/engines/bladerunner/actor_dialogue_queue.h
+++ b/engines/bladerunner/actor_dialogue_queue.h
@@ -22,11 +22,13 @@
#ifndef BLADERUNNER_ACTOR_DIALOGUE_QUEUE_H
#define BLADERUNNER_ACTOR_DIALOGUE_QUEUE_H
+
#include "common/array.h"
namespace BladeRunner {
class BladeRunnerEngine;
+class SaveFile;
class ActorDialogueQueue {
struct Entry {
@@ -61,6 +63,8 @@ public:
void flush(int a1, bool callScript);
void tick();
+ void save(SaveFile &f);
+
private:
void clear();
};
diff --git a/engines/bladerunner/actor_walk.cpp b/engines/bladerunner/actor_walk.cpp
index 16009aa65b..d376e36785 100644
--- a/engines/bladerunner/actor_walk.cpp
+++ b/engines/bladerunner/actor_walk.cpp
@@ -28,6 +28,7 @@
#include "bladerunner/game_constants.h"
#include "bladerunner/game_info.h"
#include "bladerunner/obstacles.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/scene.h"
#include "bladerunner/scene_objects.h"
#include "bladerunner/set.h"
@@ -238,6 +239,27 @@ 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);
+ // _originalDestination is not saved
+ f.write(_current);
+ f.write(_next);
+ f.write(_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.padBytes(8 * (20 - _nearActors.size()));
+ f.write((int)_nearActors.size());
+
+ f.write(0); // _notUsed
+ f.write(_status);
+}
+
bool ActorWalk::isXYZEmpty(float x, float y, float z, int actorId) const {
if (_vm->_scene->_set->findWalkbox(x, z) == -1) {
return true;
diff --git a/engines/bladerunner/actor_walk.h b/engines/bladerunner/actor_walk.h
index f4caa65453..265421458f 100644
--- a/engines/bladerunner/actor_walk.h
+++ b/engines/bladerunner/actor_walk.h
@@ -29,6 +29,7 @@
namespace BladeRunner {
class BladeRunnerEngine;
+class SaveFile;
class ActorWalk {
BladeRunnerEngine *_vm;
@@ -60,6 +61,7 @@ public:
void stop(int actorId, bool immediately, int combatAnimationMode, int animationMode);
void run(int actorId);
+ void save(SaveFile &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 64a85bc46c..6477f27c8e 100644
--- a/engines/bladerunner/ambient_sounds.cpp
+++ b/engines/bladerunner/ambient_sounds.cpp
@@ -25,6 +25,7 @@
#include "bladerunner/audio_player.h"
#include "bladerunner/bladerunner.h"
#include "bladerunner/game_info.h"
+#include "bladerunner/savefile.h"
#include "common/debug.h"
#include "common/system.h"
@@ -362,4 +363,40 @@ void AmbientSounds::removeLoopingSoundByIndex(int index, int delay) {
track.pan = 0;
}
+void AmbientSounds::save(SaveFile &f) {
+ f.write(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.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);
+ }
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/ambient_sounds.h b/engines/bladerunner/ambient_sounds.h
index e06726b183..6e14c56cec 100644
--- a/engines/bladerunner/ambient_sounds.h
+++ b/engines/bladerunner/ambient_sounds.h
@@ -28,6 +28,7 @@
namespace BladeRunner {
class BladeRunnerEngine;
+class SaveFile;
class AmbientSounds {
static const int kNonLoopingSounds = 25;
@@ -103,6 +104,8 @@ public:
int getVolume() const;
void playSample();
+ void save(SaveFile &f);
+
private:
int findAvailableNonLoopingTrack() const;
int findNonLoopingTrackByHash(int32 hash) const;
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index 0fd7663271..805461ce3c 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -45,7 +45,9 @@
#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"
#include "bladerunner/scene_objects.h"
#include "bladerunner/screen_effects.h"
@@ -74,6 +76,7 @@
#include "common/array.h"
#include "common/error.h"
#include "common/events.h"
+#include "common/savefile.h"
#include "common/system.h"
#include "engines/util.h"
@@ -290,7 +293,7 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
// TODO: Flee waypoints
- _gameVars = new int[_gameInfo->getGlobalVarCount()];
+ _gameVars = new int[_gameInfo->getGlobalVarCount()]();
// TODO: Actor AI DLL init
@@ -352,7 +355,9 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
// TODO: Set actor ids (redundant?)
- // TODO: Police Maze
+ _policeMaze = new PoliceMaze(this);
+ if (!_policeMaze->init())
+ return false;
_textActorNames = new TextResource(this);
if (!_textActorNames->open("ACTORS"))
@@ -1580,6 +1585,91 @@ void BladeRunnerEngine::playerGainsControl() {
}
}
+bool BladeRunnerEngine::saveGame(const Common::String &filename, byte *thumbnail) {
+ warning("BladeRunnerEngine::saveGame not finished");
+
+ if (!playerHasControl() || _sceneScript->isInsideScript() || _aiScripts->isInsideScript()) {
+ return false;
+ }
+
+ Common::OutSaveFile *commonSaveFile = getSaveFileManager()->openForSaving(filename, false);
+ if (commonSaveFile->err()) {
+ return false;
+ }
+
+ SaveFile s(commonSaveFile);
+
+ s.padBytes(9600); // TODO: thumbnail
+ s.write(-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]);
+ }
+
+ // TODO
+ // _music->save(s);
+ // s.debug(" - MUSIC - ");
+ s.padBytes(0x56);
+
+ // _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);
+
+ _dialogueMenu->save(s);
+ _obstacles->save(s);
+ _actorDialogueQueue->save(s);
+ _waypoints->save(s);
+
+ 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);
+ }
+ _actors[kActorVoiceOver]->save(s);
+
+ _policeMaze->save(s);
+ _crimesDatabase->save(s);
+
+ s.finalize();
+ assert(0 && "ok");
+
+ return !commonSaveFile->err();
+}
+
void BladeRunnerEngine::ISez(const char *str) {
debug("\t%s", str);
}
diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h
index 2c3b7c6a39..7561db2acf 100644
--- a/engines/bladerunner/bladerunner.h
+++ b/engines/bladerunner/bladerunner.h
@@ -260,6 +260,11 @@ public:
void playerLosesControl();
void playerGainsControl();
+ bool saveGame(const Common::String &filename, byte *thumbnail);
+ void loadGame();
+ void newGame();
+ void autoSaveGame();
+
void ISez(const char *str);
void blitToScreen(const Graphics::Surface &src);
diff --git a/engines/bladerunner/boundingbox.cpp b/engines/bladerunner/boundingbox.cpp
index a1c79a17e7..aea2dc0a24 100644
--- a/engines/bladerunner/boundingbox.cpp
+++ b/engines/bladerunner/boundingbox.cpp
@@ -22,6 +22,8 @@
#include "bladerunner/boundingbox.h"
+#include "bladerunner/savefile.h"
+
namespace BladeRunner {
BoundingBox::BoundingBox(float x0, float y0, float z0, float x1, float y1, float z1) {
@@ -82,4 +84,16 @@ 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 11922cbd14..0397a86266 100644
--- a/engines/bladerunner/boundingbox.h
+++ b/engines/bladerunner/boundingbox.h
@@ -27,6 +27,8 @@
namespace BladeRunner {
+class SaveFile;
+
class BoundingBox {
Vector3 _vertices[2];
@@ -43,6 +45,8 @@ 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 ef7a589456..eefcebccba 100644
--- a/engines/bladerunner/combat.cpp
+++ b/engines/bladerunner/combat.cpp
@@ -28,6 +28,7 @@
#include "bladerunner/game_constants.h"
#include "bladerunner/game_info.h"
#include "bladerunner/movement_track.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/scene_objects.h"
#include "bladerunner/settings.h"
@@ -204,4 +205,15 @@ 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]);
+ }
+ for (int i = 0; i != 9; ++i) {
+ f.write(_missSoundId[i]);
+ }
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/combat.h b/engines/bladerunner/combat.h
index ab289cca5c..670f580011 100644
--- a/engines/bladerunner/combat.h
+++ b/engines/bladerunner/combat.h
@@ -30,6 +30,8 @@
namespace BladeRunner {
class BladeRunnerEngine;
+class SaveFile;
+class Vector3;
class Combat {
static const int kSoundCount = 9;
@@ -38,10 +40,10 @@ class Combat {
bool _active;
bool _enabled;
- int _hitSoundId[kSoundCount];
- int _missSoundId[kSoundCount];
-// int _random1;
-// int _random2;
+ int _hitSoundId[kSoundCount];
+ int _missSoundId[kSoundCount];
+ // int _random1;
+ // int _random2;
public:
int _ammoDamage[3];
@@ -87,6 +89,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);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/crimes_database.cpp b/engines/bladerunner/crimes_database.cpp
index febe408cd9..131c871654 100644
--- a/engines/bladerunner/crimes_database.cpp
+++ b/engines/bladerunner/crimes_database.cpp
@@ -24,6 +24,7 @@
#include "bladerunner/bladerunner.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/text_resource.h"
namespace BladeRunner {
@@ -70,4 +71,11 @@ const char *CrimesDatabase::getClueText(int clueId) const {
return _cluesText->getText(clueId);
}
+void CrimesDatabase::save(SaveFile &f) {
+ for (int i = 0; i < _crimeCount; ++i) {
+ uint8 c = _crimes[i];
+ f.write(c);
+ }
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/crimes_database.h b/engines/bladerunner/crimes_database.h
index 40e46cb356..1374d52424 100644
--- a/engines/bladerunner/crimes_database.h
+++ b/engines/bladerunner/crimes_database.h
@@ -28,6 +28,7 @@
namespace BladeRunner {
class BladeRunnerEngine;
+class SaveFile;
class TextResource;
class CrimesDatabase {
@@ -47,6 +48,8 @@ public:
int getAssetType(int clueId) const;
const char *getClueText(int clueId) const;
+
+ void save(SaveFile &f);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/dialogue_menu.cpp b/engines/bladerunner/dialogue_menu.cpp
index 685c8459e0..7b7223fe94 100644
--- a/engines/bladerunner/dialogue_menu.cpp
+++ b/engines/bladerunner/dialogue_menu.cpp
@@ -25,6 +25,7 @@
#include "bladerunner/bladerunner.h"
#include "bladerunner/font.h"
#include "bladerunner/mouse.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/settings.h"
#include "bladerunner/shape.h"
#include "bladerunner/text_resource.h"
@@ -364,6 +365,30 @@ bool DialogueMenu::waitingForInput() const {
return _waitingForInput;
}
+void DialogueMenu::save(SaveFile &f) {
+ f.write(_isVisible);
+ f.write(_waitingForInput);
+ f.write(_selectedItemIndex);
+ f.write(_listSize);
+
+ f.write(_neverRepeatListSize);
+ for (int i = 0; i < 100; ++i) {
+ f.write(_neverRepeatValues[i]);
+ }
+ for (int i = 0; i < 100; ++i) {
+ f.write(_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);
+ }
+}
+
void DialogueMenu::clear() {
_isVisible = false;
_waitingForInput = false;
diff --git a/engines/bladerunner/dialogue_menu.h b/engines/bladerunner/dialogue_menu.h
index 63e23d8ada..b06cf9dfb6 100644
--- a/engines/bladerunner/dialogue_menu.h
+++ b/engines/bladerunner/dialogue_menu.h
@@ -33,6 +33,7 @@
namespace BladeRunner {
class BladeRunnerEngine;
+class SaveFile;
class TextResource;
class DialogueMenu {
@@ -102,6 +103,10 @@ private:
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/game_flags.cpp b/engines/bladerunner/game_flags.cpp
index 81fe6a0a4f..1e0b58378e 100644
--- a/engines/bladerunner/game_flags.cpp
+++ b/engines/bladerunner/game_flags.cpp
@@ -22,6 +22,8 @@
#include "bladerunner/game_flags.h"
+#include "bladerunner/savefile.h"
+
#include "common/debug.h"
namespace BladeRunner {
@@ -38,7 +40,7 @@ void GameFlags::setFlagCount(int count) {
assert(count > 0);
_flagCount = count;
- _flags = new uint32[count / 32 + 1];
+ _flags = new uint32[count / 32 + 1]();
for (int i = 0; i <= _flagCount; ++i)
reset(i);
@@ -71,4 +73,10 @@ bool GameFlags::query(int flag) const {
return !!(_flags[flag / 32] & (1 << (flag % 32)));
}
+void GameFlags::save(SaveFile &f) {
+ for (int i = 0; i != _flagCount / 32 + 1; ++i) {
+ f.write(_flags[i]);
+ }
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/game_flags.h b/engines/bladerunner/game_flags.h
index 83cbdbc086..b409e858b0 100644
--- a/engines/bladerunner/game_flags.h
+++ b/engines/bladerunner/game_flags.h
@@ -27,6 +27,8 @@
namespace BladeRunner {
+class SaveFile;
+
class GameFlags {
uint32 *_flags;
int _flagCount;
@@ -40,6 +42,8 @@ public:
void set(int flag);
void reset(int flag);
bool query(int flag) const;
+
+ void save(SaveFile &f);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/item.cpp b/engines/bladerunner/item.cpp
index 7fca4d108c..bf09efb0e6 100644
--- a/engines/bladerunner/item.cpp
+++ b/engines/bladerunner/item.cpp
@@ -24,6 +24,7 @@
#include "bladerunner/bladerunner.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/slice_renderer.h"
#include "bladerunner/zbuffer.h"
@@ -173,4 +174,26 @@ 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);
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/item.h b/engines/bladerunner/item.h
index 3beca15dd9..bf07a118bd 100644
--- a/engines/bladerunner/item.h
+++ b/engines/bladerunner/item.h
@@ -32,6 +32,7 @@ namespace BladeRunner {
class BladeRunnerEngine;
class Items;
+class SaveFile;
class Item {
friend class Items;
@@ -84,6 +85,8 @@ public:
void setup(int itemId, int setId, int animationId, Vector3 position, int facing, int height, int width, bool isTargetFlag, bool isVisible, bool isPoliceMazeEnemy);
bool isUnderMouse(int mouseX, int mouseY) const;
+
+ void save(SaveFile &f);
};
}
diff --git a/engines/bladerunner/items.cpp b/engines/bladerunner/items.cpp
index 0348efc4fe..7fe769cb93 100644
--- a/engines/bladerunner/items.cpp
+++ b/engines/bladerunner/items.cpp
@@ -23,6 +23,7 @@
#include "bladerunner/items.h"
#include "bladerunner/game_constants.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/scene.h"
#include "bladerunner/scene_objects.h"
#include "bladerunner/zbuffer.h"
@@ -242,4 +243,19 @@ int Items::findItem(int itemId) const {
return -1;
}
+void Items::save(SaveFile &f) {
+ int size = (int)_items.size();
+
+ f.write(size);
+ int i;
+ for (i = 0; i != size; ++i) {
+ _items[i]->save(f);
+ }
+
+ // Always write out 100 items
+ for (; i != 100; ++i) {
+ f.padBytes(0x174); // bbox + rect + 18 float fields
+ }
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/items.h b/engines/bladerunner/items.h
index 6bbc99c59b..cc9af734b2 100644
--- a/engines/bladerunner/items.h
+++ b/engines/bladerunner/items.h
@@ -30,6 +30,8 @@
namespace BladeRunner {
+class SaveFile;
+
class Items {
BladeRunnerEngine *_vm;
@@ -64,6 +66,7 @@ public:
void spinInWorld(int itemId);
+ void save(SaveFile &f);
private:
int findItem(int itemId) const;
};
diff --git a/engines/bladerunner/module.mk b/engines/bladerunner/module.mk
index bf90922ebf..f4bf926aa0 100644
--- a/engines/bladerunner/module.mk
+++ b/engines/bladerunner/module.mk
@@ -40,7 +40,10 @@ MODULE_OBJS = \
obstacles.o \
outtake.o \
overlays.o \
+ police_maze.o \
+ police_maze_track.o \
regions.o \
+ savefile.o \
scene.o \
scene_objects.o \
screen_effects.o \
diff --git a/engines/bladerunner/movement_track.cpp b/engines/bladerunner/movement_track.cpp
index 47eb56a098..5a6407ed3a 100644
--- a/engines/bladerunner/movement_track.cpp
+++ b/engines/bladerunner/movement_track.cpp
@@ -22,6 +22,8 @@
#include "bladerunner/movement_track.h"
+#include "bladerunner/savefile.h"
+
namespace BladeRunner {
MovementTrack::MovementTrack() {
@@ -107,4 +109,18 @@ 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) {
+ Entry &e = _entries[i];
+ f.write(e.waypointId);
+ f.write(e.delay);
+ f.write(e.angle);
+ f.write(e.run);
+ }
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/movement_track.h b/engines/bladerunner/movement_track.h
index cba9b690ff..2d59fd98c7 100644
--- a/engines/bladerunner/movement_track.h
+++ b/engines/bladerunner/movement_track.h
@@ -29,6 +29,7 @@ namespace BladeRunner {
class BladeRunnerEngine;
class BoundingBox;
+class SaveFile;
class MovementTrack {
static const int kSize = 100;
@@ -59,8 +60,7 @@ public:
bool hasNext() const;
bool next(int *waypointId, int *delay, int *angle, bool *run);
- //int saveGame();
-
+ void save(SaveFile &f);
private:
void reset();
};
diff --git a/engines/bladerunner/obstacles.cpp b/engines/bladerunner/obstacles.cpp
index 8061e782f2..603d514513 100644
--- a/engines/bladerunner/obstacles.cpp
+++ b/engines/bladerunner/obstacles.cpp
@@ -24,11 +24,15 @@
#include "bladerunner/bladerunner.h"
+#include "bladerunner/savefile.h"
+
namespace BladeRunner {
Obstacles::Obstacles(BladeRunnerEngine *vm) {
_vm = vm;
- _vertices = new Vector2[150];
+ _polygons = new Polygon[kPolygonCount];
+ _polygonsBackup = new Polygon[kPolygonCount];
+ _vertices = new Vector2[kVertexCount];
clear();
}
@@ -40,7 +44,7 @@ void Obstacles::clear() {
for (int i = 0; i < kPolygonCount; i++) {
_polygons[i].isPresent = false;
_polygons[i].verticeCount = 0;
- for (int j = 0; j < kVertexCount; j++) {
+ for (int j = 0; j < kPolygonVertexCount; j++) {
_polygons[i].vertices[j].x = 0.0f;
_polygons[i].vertices[j].y = 0.0f;
}
@@ -64,5 +68,29 @@ void Obstacles::backup() {
void Obstacles::restore() {}
+void Obstacles::save(SaveFile &f) {
+ f.write(_backup);
+ f.write(_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);
+ for (int j = 0; j < kPolygonVertexCount; ++j) {
+ f.write(p.vertices[j]);
+ }
+ for (int j = 0; j < kPolygonVertexCount; ++j) {
+ f.write(p.vertexType[j]);
+ }
+ }
+ for (int i = 0; i < kVertexCount; ++i) {
+ f.write(_vertices[i]);
+ }
+ f.write(_verticeCount);
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/obstacles.h b/engines/bladerunner/obstacles.h
index c2c84c3bfa..fc06fe6920 100644
--- a/engines/bladerunner/obstacles.h
+++ b/engines/bladerunner/obstacles.h
@@ -28,10 +28,12 @@
namespace BladeRunner {
class BladeRunnerEngine;
+class SaveFile;
class Obstacles {
- static const int kPolygonCount = 50;
- static const int kVertexCount = 160;
+ static const int kVertexCount = 150;
+ static const int kPolygonCount = 50;
+ static const int kPolygonVertexCount = 160;
struct Polygon {
bool isPresent;
@@ -40,14 +42,14 @@ class Obstacles {
float bottom;
float right;
float top;
- Vector2 vertices[kVertexCount];
- int vertexType[kVertexCount];
+ Vector2 vertices[kPolygonVertexCount];
+ int vertexType[kPolygonVertexCount];
};
BladeRunnerEngine *_vm;
- Polygon _polygons[kPolygonCount];
- Polygon _polygonsBackup[kPolygonCount];
+ Polygon *_polygons;
+ Polygon *_polygonsBackup;
Vector2 *_vertices;
int _verticeCount;
int _count;
@@ -62,6 +64,7 @@ public:
bool find(const Vector3 &from, const Vector3 &to, Vector3 *next) const;
void backup();
void restore();
+ void save(SaveFile &f);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/overlays.cpp b/engines/bladerunner/overlays.cpp
index b5cb130678..0f011ad4d1 100644
--- a/engines/bladerunner/overlays.cpp
+++ b/engines/bladerunner/overlays.cpp
@@ -25,6 +25,7 @@
#include "bladerunner/bladerunner.h"
#include "bladerunner/archive.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/vqa_player.h"
#include "graphics/surface.h"
@@ -56,6 +57,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);
if (index < 0) {
@@ -63,12 +66,13 @@ int Overlays::play(const Common::String &name, int loopId, bool loopForever, boo
if (index < 0) {
return index;
}
+ _videos[index].loaded = true;
+ _videos[index].name = name;
_videos[index].id = id;
_videos[index].vqaPlayer = new VQAPlayer(_vm, &_vm->_surfaceFront);
// repeat forever
_videos[index].vqaPlayer->setBeginAndEndFrame(0, 0, -1, kLoopSetModeJustStart, nullptr, nullptr);
- _videos[index].loaded = true;
}
Common::String resourceName = Common::String::format("%s.VQA", name.c_str());
@@ -136,10 +140,26 @@ void Overlays::resetSingle(int i) {
_videos[i].loaded = false;
_videos[i].id = 0;
_videos[i].field2 = -1;
+ _videos[i].name.clear();
}
void Overlays::reset() {
_videos.clear();
}
+void Overlays::save(SaveFile &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);
+ }
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/overlays.h b/engines/bladerunner/overlays.h
index 38edf7459b..fc8dfa11d4 100644
--- a/engines/bladerunner/overlays.h
+++ b/engines/bladerunner/overlays.h
@@ -33,20 +33,20 @@ struct Surface;
namespace BladeRunner {
class BladeRunnerEngine;
+class SaveFile;
class VQAPlayer;
-
class Overlays {
static const int kOverlayVideos = 5;
struct Video {
- bool loaded;
- VQAPlayer *vqaPlayer;
- // char name[13];
- int32 id;
- int field0;
- int field1;
- int field2;
+ bool loaded;
+ VQAPlayer *vqaPlayer;
+ Common::String name;
+ int32 id;
+ int field0;
+ int field1;
+ int field2;
};
BladeRunnerEngine *_vm;
@@ -62,6 +62,8 @@ public:
void removeAll();
void tick();
+ void save(SaveFile &f);
+
private:
int findById(int32 id) const;
int findEmpty() const;
diff --git a/engines/bladerunner/police_maze.cpp b/engines/bladerunner/police_maze.cpp
new file mode 100644
index 0000000000..223171d0be
--- /dev/null
+++ b/engines/bladerunner/police_maze.cpp
@@ -0,0 +1,64 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#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
new file mode 100644
index 0000000000..4bd06bb868
--- /dev/null
+++ b/engines/bladerunner/police_maze.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BLADERUNNER_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
new file mode 100644
index 0000000000..988f90499c
--- /dev/null
+++ b/engines/bladerunner/police_maze_track.cpp
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#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
new file mode 100644
index 0000000000..9de7a1b624
--- /dev/null
+++ b/engines/bladerunner/police_maze_track.h
@@ -0,0 +1,65 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BLADERUNNER_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 80dabf2989..51b2bae2d7 100644
--- a/engines/bladerunner/regions.cpp
+++ b/engines/bladerunner/regions.cpp
@@ -22,6 +22,8 @@
#include "bladerunner/regions.h"
+#include "bladerunner/savefile.h"
+
namespace BladeRunner {
Regions::Regions() {
@@ -99,4 +101,13 @@ void Regions::enable() {
_enabled = true;
}
+void Regions::save(SaveFile &f) {
+ f.write(_enabled);
+ for (int i = 0; i != 10; ++i) {
+ f.write(_regions[i].rectangle);
+ f.write(_regions[i].type);
+ f.write(_regions[i].present);
+ }
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/regions.h b/engines/bladerunner/regions.h
index 9868f46ac0..ed4dcba1dc 100644
--- a/engines/bladerunner/regions.h
+++ b/engines/bladerunner/regions.h
@@ -30,6 +30,8 @@
namespace BladeRunner {
+class SaveFile;
+
class Regions {
friend class Debugger;
@@ -54,6 +56,8 @@ public:
void setEnabled(bool enabled);
void enable();
+
+ void save(SaveFile &f);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/savefile.cpp b/engines/bladerunner/savefile.cpp
new file mode 100644
index 0000000000..ff1ff75165
--- /dev/null
+++ b/engines/bladerunner/savefile.cpp
@@ -0,0 +1,120 @@
+/* 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/savefile.h"
+
+#include "bladerunner/boundingbox.h"
+#include "bladerunner/vector.h"
+
+#include "common/rect.h"
+#include "common/savefile.h"
+
+namespace BladeRunner {
+
+SaveFile::SaveFile(Common::OutSaveFile *saveFile)
+ : _saveFile(saveFile),
+ _stream(DisposeAfterUse::YES)
+{
+}
+
+void SaveFile::finalize() {
+ _saveFile->writeUint32LE(_stream.size() + 4);
+ _saveFile->write(_stream.getData(), _stream.size());
+ _saveFile->finalize();
+}
+
+void SaveFile::padBytes(int count) {
+ for (int i = 0; i < count; ++i) {
+ _stream.writeByte(0);
+ }
+}
+
+void SaveFile::write(bool v) {
+ _stream.writeUint32LE(v);
+}
+
+void SaveFile::write(int v) {
+ _stream.writeUint32LE(v);
+}
+
+void SaveFile::write(uint32 v) {
+ _stream.writeUint32LE(v);
+}
+
+void SaveFile::write(byte v) {
+ _stream.writeByte(v);
+}
+
+void SaveFile::write(float v) {
+ _stream.writeFloatLE(v);
+}
+
+void SaveFile::debug(char *p) {
+ _stream.write(p, strlen(p) + 1);
+}
+
+void SaveFile::write(char *p, int sz) {
+ _stream.write(p, sz);
+}
+
+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 SaveFile::write(const Vector2 &v) {
+ _stream.writeFloatLE(v.x);
+ _stream.writeFloatLE(v.y);
+}
+
+void SaveFile::write(const Vector3 &v) {
+ _stream.writeFloatLE(v.x);
+ _stream.writeFloatLE(v.y);
+ _stream.writeFloatLE(v.z);
+}
+
+void SaveFile::write(const Common::Rect &v) {
+ _stream.writeUint32LE(v.left);
+ _stream.writeUint32LE(v.top);
+ _stream.writeUint32LE(v.right);
+ _stream.writeUint32LE(v.bottom);
+}
+
+void SaveFile::write(const BoundingBox &v) {
+ 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);
+
+ // Bounding boxes have a lot of extra data that's never actually used
+ for (int i = 0; i != 96; ++i) {
+ _stream.writeFloatLE(0.0f);
+ }
+}
+
+} // End of namespace BladeRunner
diff --git a/engines/bladerunner/savefile.h b/engines/bladerunner/savefile.h
new file mode 100644
index 0000000000..8c5dc0aa80
--- /dev/null
+++ b/engines/bladerunner/savefile.h
@@ -0,0 +1,67 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BLADERUNNER_SAVEFILE_H
+#define BLADERUNNER_SAVEFILE_H
+
+#include "common/memstream.h"
+#include "common/types.h"
+
+namespace Common {
+ class OutSaveFile;
+ class String;
+ struct Rect;
+}
+
+namespace BladeRunner {
+
+class Vector2;
+class Vector3;
+class BoundingBox;
+
+class SaveFile {
+ Common::OutSaveFile *_saveFile;
+ Common::MemoryWriteStreamDynamic _stream;
+public:
+ SaveFile(Common::OutSaveFile *saveFile);
+
+ // bool err();
+ void finalize();
+
+ 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);
+};
+
+} // End of namespace BladeRunner
+
+#endif
diff --git a/engines/bladerunner/scene.cpp b/engines/bladerunner/scene.cpp
index 84d0dd4bd6..d12c85e56b 100644
--- a/engines/bladerunner/scene.cpp
+++ b/engines/bladerunner/scene.cpp
@@ -30,6 +30,7 @@
#include "bladerunner/items.h"
#include "bladerunner/overlays.h"
#include "bladerunner/regions.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/scene_objects.h"
#include "bladerunner/screen_effects.h"
#include "bladerunner/set.h"
@@ -412,4 +413,21 @@ void Scene::loopEnded(int frame, int loopId) {
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);
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/scene.h b/engines/bladerunner/scene.h
index 91cd2ed604..b1963e8c15 100644
--- a/engines/bladerunner/scene.h
+++ b/engines/bladerunner/scene.h
@@ -30,6 +30,7 @@ namespace BladeRunner {
class BladeRunnerEngine;
class BoundingBox;
class Regions;
+class SaveFile;
class Set;
class VQAPlayer;
@@ -89,6 +90,8 @@ public:
void objectSetIsTarget(int objectId, bool isTarget, bool sceneLoaded);
const char *objectGetName(int objectId);
+ void save(SaveFile &f);
+
private:
void loopEnded(int frame, int loopId);
static void loopEndedStatic(void *data, int frame, int loopId);
diff --git a/engines/bladerunner/scene_objects.cpp b/engines/bladerunner/scene_objects.cpp
index 148cde827c..f68dccc0dd 100644
--- a/engines/bladerunner/scene_objects.cpp
+++ b/engines/bladerunner/scene_objects.cpp
@@ -25,6 +25,7 @@
#include "bladerunner/bladerunner.h"
#include "bladerunner/obstacles.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/view.h"
namespace BladeRunner {
@@ -327,4 +328,25 @@ void SceneObjects::updateObstacles() {
_vm->_obstacles->backup();
}
+void SceneObjects::save(SaveFile &f) {
+ f.write(_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);
+ }
+ for (int i = 0; i < kSceneObjectCount; ++i) {
+ f.write(_sceneObjectsSortedByDistance[i]);
+ }
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/scene_objects.h b/engines/bladerunner/scene_objects.h
index de31eae88d..2f154db754 100644
--- a/engines/bladerunner/scene_objects.h
+++ b/engines/bladerunner/scene_objects.h
@@ -30,6 +30,7 @@
namespace BladeRunner {
class BladeRunnerEngine;
+class SaveFile;
class View;
enum SceneObjectType {
@@ -86,7 +87,7 @@ public:
void setIsTarget(int sceneObjectId, bool isTarget);
void updateObstacles();
-
+ void save(SaveFile &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);
diff --git a/engines/bladerunner/script/ai_script.cpp b/engines/bladerunner/script/ai_script.cpp
index c960ff180f..257e323c5b 100644
--- a/engines/bladerunner/script/ai_script.cpp
+++ b/engines/bladerunner/script/ai_script.cpp
@@ -345,4 +345,31 @@ void AIScripts::fledCombat(int actor) {
_inScriptCounter--;
}
+void AIScripts::setAnimationState(int actor, int animationState, int animationFrame, int animationStateNext, int animationNext) {
+ if (actor >= _actorCount) {
+ return;
+ }
+
+ _inScriptCounter++;
+ if (_AIScripts[actor]) {
+ _AIScripts[actor]->SetAnimationState(animationState, animationFrame, animationStateNext, animationNext);
+ }
+ _inScriptCounter--;
+}
+
+
+void AIScripts::queryAnimationState(int actor, int *animationState, int *animationFrame, int *animationStateNext, int *nextAnimation) {
+ if (actor >= _actorCount) {
+ return;
+ }
+
+ _inScriptCounter++;
+ if (_AIScripts[actor]) {
+ _AIScripts[actor]->FledCombat();
+ _AIScripts[actor]->QueryAnimationState(animationState, animationFrame, animationStateNext, nextAnimation);
+ }
+ _inScriptCounter--;
+}
+
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/script/ai_script.h b/engines/bladerunner/script/ai_script.h
index cfd3fe5e1a..5e782d0820 100644
--- a/engines/bladerunner/script/ai_script.h
+++ b/engines/bladerunner/script/ai_script.h
@@ -566,6 +566,8 @@ 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 setAnimationState(int actor, int animationState, int animationFrame, int animationStateNext, int animationNext);
void fledCombat(int actor);
bool isInsideScript() const { return _inScriptCounter > 0; }
diff --git a/engines/bladerunner/set.cpp b/engines/bladerunner/set.cpp
index fe10c189b6..6a83294c4c 100644
--- a/engines/bladerunner/set.cpp
+++ b/engines/bladerunner/set.cpp
@@ -25,6 +25,7 @@
#include "bladerunner/bladerunner.h"
#include "bladerunner/game_constants.h"
#include "bladerunner/lights.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/scene_objects.h"
#include "bladerunner/set_effects.h"
#include "bladerunner/slice_renderer.h"
@@ -82,6 +83,7 @@ bool Set::open(const Common::String &name) {
_objects[i].isObstacle = s->readByte();
_objects[i].isClickable = s->readByte();
_objects[i].isHotMouse = 0;
+ _objects[i].unknown1 = 0;
_objects[i].isTarget = 0;
s->skip(4);
@@ -327,4 +329,40 @@ int Set::getWalkboxSoundRunLeft(int walkboxId) const {
int Set::getWalkboxSoundRunRight(int walkboxId) const {
return getWalkboxSoundWalkRight(walkboxId);
}
+
+void Set::save(SaveFile &f) {
+ f.write(_loaded);
+ f.write(_objectCount);
+ f.write(_walkboxCount);
+
+ 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);
+ }
+
+ for (int i = 0; i != _walkboxCount; ++i) {
+ f.write(_walkboxes[i].name, 20);
+ f.write(_walkboxes[i].altitude);
+ f.write(_walkboxes[i].vertexCount);
+ for (int j = 0; j != 8; ++j) {
+ f.write(_walkboxes[i].vertices[j]);
+
+ // In BLADE.EXE vertices are a vec5
+ f.write(0);
+ f.write(0);
+ }
+ }
+
+ for (int i = 0; i != 85; ++i) {
+ f.write(_walkboxStepSound[i]);
+ }
+
+ f.write(_footstepSoundOverride);
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/set.h b/engines/bladerunner/set.h
index a6e7e9f3df..7989ef1e1a 100644
--- a/engines/bladerunner/set.h
+++ b/engines/bladerunner/set.h
@@ -33,6 +33,7 @@ namespace BladeRunner {
class BladeRunnerEngine;
class VQADecoder;
+class SaveFile;
class SetEffects;
class SceneObjects;
@@ -94,11 +95,14 @@ public:
void setWalkboxStepSound(int walkboxId, int soundId);
void setFoodstepSoundOverride(int soundId);
void resetFoodstepSoundOverride();
+
int getWalkboxSoundWalkLeft(int walkboxId) const;
int getWalkboxSoundWalkRight(int walkboxId) const;
int getWalkboxSoundRunLeft(int walkboxId) const;
int getWalkboxSoundRunRight(int walkboxId) const;
+ void save(SaveFile &f);
+
private:
static bool isXZInWalkbox(float x, float z, const Walkbox &walkbox);
};
diff --git a/engines/bladerunner/settings.cpp b/engines/bladerunner/settings.cpp
index a5540fcb04..e4db0b81ea 100644
--- a/engines/bladerunner/settings.cpp
+++ b/engines/bladerunner/settings.cpp
@@ -26,6 +26,7 @@
#include "bladerunner/bladerunner.h"
#include "bladerunner/chapters.h"
#include "bladerunner/music.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/scene.h"
#include "common/debug.h"
@@ -39,14 +40,23 @@ Settings::Settings(BladeRunnerEngine *vm) {
_playerAgenda = 1;
_chapter = 1;
+ _scene = -1;
+ _set = -1;
+ _unk0 = 0;
_gamma = 1.0f;
+ _ammoType = 0;
+ _ammoAmounts[0] = 1;
+ _ammoAmounts[1] = 0;
+ _ammoAmounts[2] = 0;
+
+ // The remaining fields are not reset in BLADE.EXE
_chapterChanged = false;
_newChapter = -1;
_newScene = -1;
_newSet = -1;
- _startingGame = true;
+ _startingGame = false;
_loadingGame = false;
_fullHDFrames = true;
@@ -83,8 +93,9 @@ bool Settings::openNewScene() {
_vm->_scene->close(!_loadingGame && !_startingGame);
}
if (_chapterChanged) {
- if (_vm->_chapters->hasOpenResources())
+ if (_vm->_chapters->hasOpenResources()) {
_vm->_chapters->closeResources();
+ }
int newChapter = _newChapter;
_chapterChanged = false;
@@ -103,6 +114,9 @@ bool Settings::openNewScene() {
return false;
}
+ _set = newSet;
+ _scene = newScene;
+
if (!_loadingGame && currentSet != newSet) {
// TODO: Reset actors for new set
}
@@ -171,4 +185,17 @@ 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);
+ for (int i = 0; i != 3; ++i) {
+ f.write(_ammoAmounts[i]);
+ }
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/settings.h b/engines/bladerunner/settings.h
index bf2d2d3162..bc1c25553c 100644
--- a/engines/bladerunner/settings.h
+++ b/engines/bladerunner/settings.h
@@ -26,6 +26,7 @@
namespace BladeRunner {
class BladeRunnerEngine;
+class SaveFile;
enum PlayerAgenda {
kPlayerAgendaPolite = 0,
@@ -39,6 +40,9 @@ class Settings {
BladeRunnerEngine *_vm;
int _chapter;
+ int _scene;
+ int _set;
+ int _unk0;
float _gamma;
bool _chapterChanged;
@@ -49,6 +53,8 @@ class Settings {
bool _startingGame;
bool _loadingGame;
+ int _unk1;
+
int _fullHDFrames;
int _mst3k;
@@ -117,6 +123,8 @@ public:
bool getLearyMode() const;
void setLearyMode(bool learyMode);
+
+ void save(SaveFile &f);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/ui/spinner.cpp b/engines/bladerunner/ui/spinner.cpp
index 0740715fc4..1f8f197926 100644
--- a/engines/bladerunner/ui/spinner.cpp
+++ b/engines/bladerunner/ui/spinner.cpp
@@ -25,6 +25,7 @@
#include "bladerunner/bladerunner.h"
#include "bladerunner/game_constants.h"
#include "bladerunner/mouse.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/scene.h"
#include "bladerunner/shape.h"
#include "bladerunner/text_resource.h"
@@ -262,6 +263,14 @@ void Spinner::resume() {
_vqaPlayer->setLoop(1, -1, kLoopSetModeJustStart, nullptr, nullptr);
}
+void Spinner::save(SaveFile &f) {
+ assert(!_isOpen);
+
+ for (int i = 0; i != kSpinnerDestinations; ++i) {
+ f.write(_isDestinationSelectable[i]);
+ }
+}
+
const Spinner::Destination *Spinner::getDestinationsFar() {
static const Destination destinations[] = {
{ 0, Common::Rect(220, 227, 246, 262) },
diff --git a/engines/bladerunner/ui/spinner.h b/engines/bladerunner/ui/spinner.h
index b1785a57eb..24f66ed4db 100644
--- a/engines/bladerunner/ui/spinner.h
+++ b/engines/bladerunner/ui/spinner.h
@@ -29,9 +29,10 @@
namespace BladeRunner {
class BladeRunnerEngine;
+class SaveFile;
class Shape;
-class VQAPlayer;
class UIImagePicker;
+class VQAPlayer;
class Spinner {
static const int kSpinnerDestinations = 10;
@@ -70,6 +71,8 @@ public:
void reset();
void resume();
+ void save(SaveFile &f);
+
private:
static void mouseUpCallback(int, void *);
static const Destination *getDestinationsFar();
diff --git a/engines/bladerunner/waypoints.cpp b/engines/bladerunner/waypoints.cpp
index 4d80841e50..0783af8e07 100644
--- a/engines/bladerunner/waypoints.cpp
+++ b/engines/bladerunner/waypoints.cpp
@@ -22,6 +22,8 @@
#include "bladerunner/waypoints.h"
+#include "bladerunner/savefile.h"
+
namespace BladeRunner {
Waypoints::Waypoints(BladeRunnerEngine *vm, int count) {
@@ -89,4 +91,14 @@ float Waypoints::getZ(int waypointId) const {
return _waypoints[waypointId].position.z;
}
+void Waypoints::save(SaveFile &f) {
+ f.write(_count);
+ for (int i = 0; i < _count; ++i) {
+ Waypoint &w = _waypoints[i];
+ f.write(w.setId);
+ f.write(w.position);
+ f.write(w.present);
+ }
+}
+
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/waypoints.h b/engines/bladerunner/waypoints.h
index 826f8f5a94..9159301cfe 100644
--- a/engines/bladerunner/waypoints.h
+++ b/engines/bladerunner/waypoints.h
@@ -30,6 +30,8 @@
namespace BladeRunner {
+class SaveFile;
+
class Waypoints {
friend class Debugger;
@@ -55,6 +57,8 @@ public:
bool set(int waypointId, int setId, Vector3 position);
bool reset(int waypointId);
+
+ void save(SaveFile &f);
};
} // End of namespace BladeRunner