aboutsummaryrefslogtreecommitdiff
path: root/engines/bladerunner
diff options
context:
space:
mode:
authorPeter Kohaut2018-11-25 21:47:00 +0100
committerPeter Kohaut2018-11-25 22:22:25 +0100
commitcfb46da90cb045e029153848652bbd166a5c95b6 (patch)
tree468120f7e0c5eef52efcaafd9f4fec5ebd5981ef /engines/bladerunner
parent0d8834b5616aa8fc936c750ed92ef4423610d641 (diff)
downloadscummvm-rg350-cfb46da90cb045e029153848652bbd166a5c95b6.tar.gz
scummvm-rg350-cfb46da90cb045e029153848652bbd166a5c95b6.tar.bz2
scummvm-rg350-cfb46da90cb045e029153848652bbd166a5c95b6.zip
BLADERUNNER: Add in-game loading screen
It is also possible to start new game from it.
Diffstat (limited to 'engines/bladerunner')
-rw-r--r--engines/bladerunner/bladerunner.cpp71
-rw-r--r--engines/bladerunner/bladerunner.h7
-rw-r--r--engines/bladerunner/debugger.cpp6
-rw-r--r--engines/bladerunner/detection.cpp42
-rw-r--r--engines/bladerunner/module.mk1
-rw-r--r--engines/bladerunner/savefile.cpp49
-rw-r--r--engines/bladerunner/savefile.h9
-rw-r--r--engines/bladerunner/script/ai/steele.cpp2
-rw-r--r--engines/bladerunner/ui/kia.cpp35
-rw-r--r--engines/bladerunner/ui/kia.h31
-rw-r--r--engines/bladerunner/ui/kia_section_load.cpp163
-rw-r--r--engines/bladerunner/ui/kia_section_load.h38
-rw-r--r--engines/bladerunner/ui/ui_container.cpp8
13 files changed, 346 insertions, 116 deletions
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index 41299fc7d1..3d9ba34cb1 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -230,7 +230,7 @@ Common::Error BladeRunnerEngine::loadGameState(int slot) {
}
BladeRunner::SaveFileHeader header;
- if (!BladeRunner::SaveFile::readHeader(*saveFile, header)) {
+ if (!BladeRunner::SaveFileManager::readHeader(*saveFile, header)) {
error("Invalid savegame");
}
@@ -261,18 +261,18 @@ Common::Error BladeRunnerEngine::saveGameState(int slot, const Common::String &d
return Common::kReadingFailed;
}
- byte *thumbnail = new byte[SaveFile::kThumbnailSize];
- generateThumbnail(thumbnail);
+ Graphics::Surface thumbnail = generateThumbnail();
BladeRunner::SaveFileHeader header;
header._name = desc;
- BladeRunner::SaveFile::writeHeader(*saveFile, header);
+
+ BladeRunner::SaveFileManager::writeHeader(*saveFile, header);
saveGame(*saveFile, thumbnail);
saveFile->finalize();
- delete[] thumbnail;
+ thumbnail.free();
delete saveFile;
@@ -285,19 +285,29 @@ Common::Error BladeRunnerEngine::run() {
_system->showMouse(true);
- if (!startup()) {
+ bool hasSavegames = !SaveFileManager::list(_targetName).empty();
+
+ if (!startup(hasSavegames)) {
shutdown();
return Common::Error(Common::kUnknownError, "Failed to initialize resources");
}
+
+
#if BLADERUNNER_DEBUG_GAME
{
#else
if (warnUserAboutUnsupportedGame()) {
#endif
- init2();
+ if (hasSavegames) {
+ _kia->_forceOpen = true;
+ _kia->open(kKIASectionLoad);
+ }
+ // TODO: why is game starting new game here when everything is done in startup?
+ // else {
+ // newGame(1);
+ // }
- /* TODO: Check for save games and enter KIA */
gameLoop();
_mouse->disable();
@@ -361,7 +371,6 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
return false;
}
- _combat = new Combat(this);
// TODO: Create datetime - not used
@@ -377,13 +386,11 @@ bool BladeRunnerEngine::startup(bool hasSavegames) {
_waypoints = new Waypoints(this, _gameInfo->getWaypointCount());
- // TODO: Cover waypoints
-
- // TODO: Flee waypoints
+ _combat = new Combat(this);
_gameVars = new int[_gameInfo->getGlobalVarCount()]();
- // TODO: Actor AI DLL init
+ // TODO: Init Actor AI Update counter
// Seed rand
@@ -789,10 +796,6 @@ bool BladeRunnerEngine::loadSplash() {
return true;
}
-bool BladeRunnerEngine::init2() {
- return true;
-}
-
Common::Point BladeRunnerEngine::getMousePos() const {
Common::Point p = _eventMan->getMousePos();
p.x = CLIP(p.x, int16(0), int16(639));
@@ -816,8 +819,7 @@ void BladeRunnerEngine::gameTick() {
handleEvents();
if (_gameIsRunning && _windowIsActive) {
- // TODO: Only run if not in Kia, script, nor AI
- if (!_sceneScript->isInsideScript() && !_aiScripts->isInsideScript()) {
+ if (!_kia->isOpen() && !_sceneScript->isInsideScript() && !_aiScripts->isInsideScript()) {
_settings->openNewScene();
}
@@ -1713,7 +1715,7 @@ void BladeRunnerEngine::playerGainsControl() {
}
}
-bool BladeRunnerEngine::saveGame(Common::WriteStream &stream, const void *thumbnail) {
+bool BladeRunnerEngine::saveGame(Common::WriteStream &stream, const Graphics::Surface &thumbnail) {
if (!playerHasControl() || _sceneScript->isInsideScript() || _aiScripts->isInsideScript()) {
return false;
}
@@ -1721,7 +1723,7 @@ bool BladeRunnerEngine::saveGame(Common::WriteStream &stream, const void *thumbn
Common::MemoryWriteStreamDynamic memoryStream(DisposeAfterUse::YES);
SaveFileWriteStream s(memoryStream);
- s.write(thumbnail, SaveFile::kThumbnailSize);
+ s.write(thumbnail.getPixels(), SaveFileManager::kThumbnailSize);
s.writeFloat(1.0f);
_settings->save(s);
_scene->save(s);
@@ -1793,7 +1795,7 @@ bool BladeRunnerEngine::loadGame(Common::SeekableReadStream &stream) {
_gameIsLoading = true;
_settings->setLoadingGame();
- s.skip(SaveFile::kThumbnailSize); // skip the thumbnail
+ s.skip(SaveFileManager::kThumbnailSize); // skip the thumbnail
s.skip(4);// always float 1.0, but never used
_settings->load(s);
_scene->load(s);
@@ -1870,6 +1872,10 @@ void BladeRunnerEngine::newGame(int difficulty) {
_settings->setDifficulty(difficulty);
}
+ InitScript initScript(this);
+ initScript.SCRIPT_Initialize_Game();
+ initChapterAndScene();
+
_settings->setStartingGame();
}
@@ -1882,21 +1888,30 @@ void BladeRunnerEngine::blitToScreen(const Graphics::Surface &src) const {
_system->updateScreen();
}
-void BladeRunnerEngine::generateThumbnail(void *thumbnail) const {
- uint16 *dstPixels = (uint16*)thumbnail;
+Graphics::Surface BladeRunnerEngine::generateThumbnail() const {
+ Graphics::Surface thumbnail;
+ thumbnail.create(640 / 8, 480 / 8, createRGB555());
+
+ for (int y = 0; y < thumbnail.h; ++y) {
+ for (int x = 0; x < thumbnail.w; ++x) {
+ uint16 *dstPixel = (uint16 *)thumbnail.getBasePtr(x, y);
+ const uint16 *srcPixel = (const uint16 *)_surfaceFront.getBasePtr(x * 8, y * 8);
- for (int y = 0; y < 480; y += 8) {
- for (int x = 0; x < 640; x += 8) {
- *dstPixels = *(const uint16 *)_surfaceFront.getBasePtr(x, y);
- ++dstPixels;
+ *dstPixel = *srcPixel;
}
}
+
+ return thumbnail;
}
GUI::Debugger *BladeRunnerEngine::getDebugger() {
return _debugger;
}
+Common::String BladeRunnerEngine::getTargetName() const {
+ return _targetName;
+}
+
void blit(const Graphics::Surface &src, Graphics::Surface &dst) {
dst.copyRectToSurface(src.getPixels(), src.pitch, 0, 0, src.w, src.h);
}
diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h
index 29015a36c4..a377b89aa9 100644
--- a/engines/bladerunner/bladerunner.h
+++ b/engines/bladerunner/bladerunner.h
@@ -24,7 +24,6 @@
#define BLADERUNNER_BLADERUNNER_H
#include "bladerunner/archive.h"
-#include "bladerunner/savefile.h"
#include "common/array.h"
#include "common/cosinetables.h"
@@ -238,7 +237,6 @@ public:
void shutdown();
bool loadSplash();
- bool init2();
Common::Point getMousePos() const;
bool isMouseButtonDown() const;
@@ -276,7 +274,7 @@ public:
void playerLosesControl();
void playerGainsControl();
- bool saveGame(Common::WriteStream &stream, const void *thumbnail);
+ bool saveGame(Common::WriteStream &stream, const Graphics::Surface &thumbnail);
bool loadGame(Common::SeekableReadStream &stream);
void newGame(int difficulty);
void autoSaveGame();
@@ -284,9 +282,10 @@ public:
void ISez(const Common::String &str);
void blitToScreen(const Graphics::Surface &src) const;
- void generateThumbnail(void *thumbnail) const;
+ Graphics::Surface generateThumbnail() const;
GUI::Debugger *getDebugger();
+ Common::String getTargetName() const;
};
static inline const Graphics::PixelFormat createRGB555() {
diff --git a/engines/bladerunner/debugger.cpp b/engines/bladerunner/debugger.cpp
index 6f7e5d14a2..f0137c4376 100644
--- a/engines/bladerunner/debugger.cpp
+++ b/engines/bladerunner/debugger.cpp
@@ -33,6 +33,7 @@
#include "bladerunner/light.h"
#include "bladerunner/lights.h"
#include "bladerunner/regions.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/scene.h"
#include "bladerunner/scene_objects.h"
#include "bladerunner/settings.h"
@@ -399,14 +400,13 @@ bool Debugger::cmdSave(int argc, const char **argv) {
Common::WriteStream *saveFile = fs.createWriteStream();
- uint16 *thumbnail = new uint16[SaveFile::kThumbnailSize];
- _vm->generateThumbnail(thumbnail);
+ Graphics::Surface thumbnail = _vm->generateThumbnail();
_vm->saveGame(*saveFile, thumbnail);
saveFile->finalize();
- delete[] thumbnail;
+ thumbnail.free();
delete saveFile;
diff --git a/engines/bladerunner/detection.cpp b/engines/bladerunner/detection.cpp
index 8cd4288a0d..46285e57bc 100644
--- a/engines/bladerunner/detection.cpp
+++ b/engines/bladerunner/detection.cpp
@@ -87,27 +87,7 @@ bool BladeRunnerMetaEngine::hasFeature(MetaEngineFeature f) const {
}
SaveStateList BladeRunnerMetaEngine::listSaves(const char *target) const {
- Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
- Common::StringArray files = saveFileMan->listSavefiles(Common::String::format("%s.###", target));
-
- SaveStateList saveList;
- for (Common::StringArray::const_iterator fileName = files.begin(); fileName != files.end(); ++fileName) {
- Common::InSaveFile *saveFile = saveFileMan->openForLoading(*fileName);
- if (saveFile == nullptr || saveFile->err()) {
- warning("Cannot open save file '%s'", fileName->c_str());
- continue;
- }
-
- BladeRunner::SaveFileHeader header;
- BladeRunner::SaveFile::readHeader(*saveFile, header);
-
- int slotNum = atoi(fileName->c_str() + fileName->size() - 3);
- saveList.push_back(SaveStateDescriptor(slotNum, header._name));
- }
-
- // Sort saves based on slot number.
- Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator());
- return saveList;
+ return BladeRunner::SaveFileManager::list(target);
}
int BladeRunnerMetaEngine::getMaximumSaveSlot() const {
@@ -120,25 +100,7 @@ void BladeRunnerMetaEngine::removeSaveState(const char *target, int slot) const
}
SaveStateDescriptor BladeRunnerMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
- Common::String filename = Common::String::format("%s.%03d", target, slot);
- Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(filename);
-
- if (saveFile == nullptr || saveFile->err()) {
- return SaveStateDescriptor();
- }
-
- BladeRunner::SaveFileHeader header;
- if (!BladeRunner::SaveFile::readHeader(*saveFile, header, false)) {
- delete saveFile;
- return SaveStateDescriptor();
- }
- delete saveFile;
-
- SaveStateDescriptor desc(slot, header._name);
- desc.setThumbnail(header._thumbnail);
- desc.setSaveDate(header._year, header._month, header._day);
- desc.setSaveTime(header._hour, header._minute);
- return desc;
+ return BladeRunner::SaveFileManager::queryMetaInfos(target, slot);
}
#if PLUGIN_ENABLED_DYNAMIC(BLADERUNNER)
diff --git a/engines/bladerunner/module.mk b/engines/bladerunner/module.mk
index b0bae4f7bd..29b6fd2c3a 100644
--- a/engines/bladerunner/module.mk
+++ b/engines/bladerunner/module.mk
@@ -257,6 +257,7 @@ MODULE_OBJS = \
ui/kia_section_crimes.o \
ui/kia_section_diagnostic.o \
ui/kia_section_help.o \
+ ui/kia_section_load.o \
ui/kia_section_pogo.o \
ui/kia_section_settings.o \
ui/kia_section_suspects.o \
diff --git a/engines/bladerunner/savefile.cpp b/engines/bladerunner/savefile.cpp
index 143d947646..fc0073c3ee 100644
--- a/engines/bladerunner/savefile.cpp
+++ b/engines/bladerunner/savefile.cpp
@@ -33,7 +33,52 @@
namespace BladeRunner {
-bool SaveFile::readHeader(Common::SeekableReadStream &in, SaveFileHeader &header, bool skipThumbnail) {
+SaveStateList SaveFileManager::list(const Common::String &target) {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringArray files = saveFileMan->listSavefiles(target + ".###");
+
+ SaveStateList saveList;
+ for (Common::StringArray::const_iterator fileName = files.begin(); fileName != files.end(); ++fileName) {
+ Common::InSaveFile *saveFile = saveFileMan->openForLoading(*fileName);
+ if (saveFile == nullptr || saveFile->err()) {
+ continue;
+ }
+
+ BladeRunner::SaveFileHeader header;
+ readHeader(*saveFile, header);
+
+ int slotNum = atoi(fileName->c_str() + fileName->size() - 3);
+ saveList.push_back(SaveStateDescriptor(slotNum, header._name));
+ }
+
+ Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator());
+
+ return saveList;
+}
+
+SaveStateDescriptor SaveFileManager::queryMetaInfos(const Common::String &target, int slot) {
+ Common::String filename = Common::String::format("%s.%03d", target.c_str(), slot);
+ Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(filename);
+
+ if (saveFile == nullptr || saveFile->err()) {
+ return SaveStateDescriptor();
+ }
+
+ BladeRunner::SaveFileHeader header;
+ if (!BladeRunner::SaveFileManager::readHeader(*saveFile, header, false)) {
+ delete saveFile;
+ return SaveStateDescriptor();
+ }
+ delete saveFile;
+
+ SaveStateDescriptor desc(slot, header._name);
+ desc.setThumbnail(header._thumbnail);
+ desc.setSaveDate(header._year, header._month, header._day);
+ desc.setSaveTime(header._hour, header._minute);
+ return desc;
+}
+
+bool SaveFileManager::readHeader(Common::SeekableReadStream &in, SaveFileHeader &header, bool skipThumbnail) {
SaveFileReadStream s(in);
if (s.readUint32BE() != kTag) {
@@ -76,7 +121,7 @@ bool SaveFile::readHeader(Common::SeekableReadStream &in, SaveFileHeader &header
return true;
}
-bool SaveFile::writeHeader(Common::WriteStream &out, SaveFileHeader &header) {
+bool SaveFileManager::writeHeader(Common::WriteStream &out, SaveFileHeader &header) {
SaveFileWriteStream s(out);
s.writeUint32BE(kTag);
diff --git a/engines/bladerunner/savefile.h b/engines/bladerunner/savefile.h
index bcd1619496..64fb0b4999 100644
--- a/engines/bladerunner/savefile.h
+++ b/engines/bladerunner/savefile.h
@@ -23,11 +23,14 @@
#ifndef BLADERUNNER_SAVEFILE_H
#define BLADERUNNER_SAVEFILE_H
+#include "common/array.h"
#include "common/memstream.h"
#include "common/types.h"
#include "graphics/surface.h"
+#include "engines/savestate.h"
+
namespace Common {
class OutSaveFile;
class String;
@@ -40,6 +43,7 @@ class Vector2;
class Vector3;
class BoundingBox;
+
struct SaveFileHeader {
uint8 _version;
Common::String _name;
@@ -51,7 +55,7 @@ struct SaveFileHeader {
Graphics::Surface *_thumbnail;
};
-class SaveFile {
+class SaveFileManager {
private:
static const uint32 kTag = MKTAG('B', 'R', 'S', 'V');
static const uint32 kVersion = 1;
@@ -60,6 +64,9 @@ private:
public:
static const uint32 kThumbnailSize = 9600; // 80x60x16bpp
+ static SaveStateList list(const Common::String &target);
+ static SaveStateDescriptor queryMetaInfos(const Common::String &target, int slot);
+
static bool readHeader(Common::SeekableReadStream &in, SaveFileHeader &header, bool skipThumbnail = true);
static bool writeHeader(Common::WriteStream &out, SaveFileHeader &header);
};
diff --git a/engines/bladerunner/script/ai/steele.cpp b/engines/bladerunner/script/ai/steele.cpp
index ff2afa1ec3..830a9aaa73 100644
--- a/engines/bladerunner/script/ai/steele.cpp
+++ b/engines/bladerunner/script/ai/steele.cpp
@@ -43,7 +43,7 @@ void AIScriptSteele::Initialize() {
Actor_Put_In_Set(kActorSteele, kSetFreeSlotG);
Actor_Set_At_Waypoint(kActorSteele, 39, 0);
Actor_Set_Goal_Number(kActorSteele, 0);
- Actor_Clue_Acquire(kActorSteele, 178, 1, -1);
+ Actor_Clue_Acquire(kActorSteele, kClueCrimeSceneNotes, 1, -1);
}
bool AIScriptSteele::Update() {
diff --git a/engines/bladerunner/ui/kia.cpp b/engines/bladerunner/ui/kia.cpp
index 4b95607541..6bea198b7c 100644
--- a/engines/bladerunner/ui/kia.cpp
+++ b/engines/bladerunner/ui/kia.cpp
@@ -31,6 +31,7 @@
#include "bladerunner/game_flags.h"
#include "bladerunner/game_info.h"
#include "bladerunner/mouse.h"
+#include "bladerunner/savefile.h"
#include "bladerunner/scene.h"
#include "bladerunner/shape.h"
#include "bladerunner/script/kia_script.h"
@@ -66,7 +67,7 @@ KIA::KIA(BladeRunnerEngine *vm) {
_log = new KIALog(_vm);
_shapes = new KIAShapes(_vm);
- _forceOpen = 0;
+ _forceOpen = false;
_currentSectionId = kKIASectionNone;
_lastSectionIdKIA = kKIASectionCrimes;
_lastSectionIdOptions = kKIASectionSettings;
@@ -88,8 +89,6 @@ KIA::KIA(BladeRunnerEngine *vm) {
_pogoPos = 0;
- _thumbnail = nullptr;
-
_buttons = new UIImagePicker(_vm, 22);
_crimesSection = new KIASectionCrimes(_vm, _vm->_playerActor->_clues);
@@ -109,6 +108,7 @@ KIA::KIA(BladeRunnerEngine *vm) {
}
KIA::~KIA() {
+ _thumbnail.free();
delete _crimesSection;
delete _suspectsSection;
delete _cluesSection;
@@ -118,7 +118,7 @@ KIA::~KIA() {
delete _loadSection;
delete _diagnosticSection;
delete _pogoSection;
-
+ _playerImage.free();
delete _playerPhotograph;
delete _buttons;
delete _shapes;
@@ -129,6 +129,7 @@ KIA::~KIA() {
void KIA::reset() {
_lastSectionIdKIA = kKIASectionCrimes;
_lastSectionIdOptions = kKIASectionSettings;
+ _playerImage.free();
_playerVqaFrame = 0;
_playerVisualizerState = 0;
_playerSliceModelAngle = 0.0f;
@@ -226,7 +227,7 @@ void KIA::tick() {
if (_playerActorDialogueQueueSize == _playerActorDialogueQueuePosition) {
_playerActorDialogueState = 0;
} else if (_playerActorDialogueState == 0) {
- if (_playerSliceModelId == -1 && _playerPhotographId == -1) { //&& !this->_playerImage
+ if (_playerSliceModelId == -1 && _playerPhotographId == -1 && _playerImage.getPixels() == nullptr) {
_vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(495), 70, 0, 0, 50, 0);
}
_playerActorDialogueState = 1;
@@ -251,18 +252,17 @@ void KIA::tick() {
int timeDiffDiv48 = (timeNow - _playerVqaTimeLast) / 48;
if (timeDiffDiv48 > 0) {
_playerVqaTimeLast = timeNow;
- if (_playerActorDialogueQueueSize == _playerActorDialogueQueuePosition || _playerSliceModelId != -1 || _playerPhotographId != -1) { // || this->_viewerImage
+ if (_playerActorDialogueQueueSize == _playerActorDialogueQueuePosition || _playerSliceModelId != -1 || _playerPhotographId != -1 || _playerImage.getPixels() != nullptr) {
if (_playerVisualizerState > 0) {
_playerVisualizerState = MAX(_playerVisualizerState - timeDiffDiv48, 0);
}
} else {
if (_playerVisualizerState < 2) {
_playerVisualizerState = MIN(_playerVisualizerState + timeDiffDiv48, 2);
-
}
}
- if ( _playerSliceModelId != -1 || _playerPhotographId != -1 ) { // || _playerImage
+ if ( _playerSliceModelId != -1 || _playerPhotographId != -1 || _playerImage.getPixels() != nullptr) {
if (_playerVqaFrame < 8) {
int newVqaFrame = MIN(timeDiffDiv48 + _playerVqaFrame, 8);
if (_playerVqaFrame <= 0 && newVqaFrame > 0) {
@@ -325,10 +325,10 @@ void KIA::tick() {
int width = _playerPhotograph->getWidth();
int height = _playerPhotograph->getHeight();
_playerPhotograph->draw(_vm->_surfaceFront, 590 - width / 2, 80 - height / 2);
+ } else if (_playerImage.getPixels() != nullptr) {
+ _vm->_surfaceFront.fillRect(Common::Rect(549, 49, 631, 111), 0x7FFF);
+ _vm->_surfaceFront.copyRectToSurface(_playerImage.getPixels(), _playerImage.pitch, 550, 50, _playerImage.w, _playerImage.h);
}
- // else if (_playerImage) {
- // ...
- // }
}
if (_playerVisualizerState == 1) {
@@ -530,8 +530,7 @@ void KIA::playerReset() {
_playerPhotograph = nullptr;
}
_playerPhotographId = -1;
- // delete _playerImage;
- // _playerImage = nullptr;
+ _playerImage.free();
_playerActorDialogueState = 0;
}
@@ -564,6 +563,10 @@ void KIA::playPhotograph(int photographId) {
_playerPhotograph->open("photos.shp", photographId);
}
+void KIA::playImage(const Graphics::Surface &image) {
+ _playerImage.copyFrom(image);
+}
+
void KIA::mouseDownCallback(int buttonId, void *callbackData) {
KIA *self = (KIA *)callbackData;
switch (buttonId) {
@@ -635,8 +638,7 @@ void KIA::loopEnded(void *callbackData, int frame, int loopId) {
}
void KIA::init() {
- _thumbnail = new byte[SaveFile::kThumbnailSize];
- _vm->generateThumbnail(_thumbnail);
+ _thumbnail = _vm->generateThumbnail();
if (!_vm->openArchive("MODE.MIX")) {
return;
@@ -667,8 +669,7 @@ void KIA::init() {
}
void KIA::unload() {
- delete[] _thumbnail;
- _thumbnail = nullptr;
+ _thumbnail.free();
if (!isOpen()) {
return;
diff --git a/engines/bladerunner/ui/kia.h b/engines/bladerunner/ui/kia.h
index 0612234db1..b5be9a7e08 100644
--- a/engines/bladerunner/ui/kia.h
+++ b/engines/bladerunner/ui/kia.h
@@ -25,14 +25,12 @@
#include "common/str.h"
+#include "graphics/surface.h"
+
namespace Common {
struct KeyState;
}
-namespace Graphics {
-struct Surface;
-}
-
namespace BladeRunner {
class BladeRunnerEngine;
@@ -78,18 +76,18 @@ class KIA {
BladeRunnerEngine *_vm;
- int _forceOpen;
int _transitionId;
- int _playerVqaTimeLast;
- VQAPlayer *_playerVqaPlayer;
- int _playerVqaFrame;
- int _playerVisualizerState;
- int _playerPhotographId;
- Shape *_playerPhotograph;
- int _playerSliceModelId;
- float _playerSliceModelAngle;
- int _timeLast;
+ int _playerVqaTimeLast;
+ VQAPlayer *_playerVqaPlayer;
+ int _playerVqaFrame;
+ int _playerVisualizerState;
+ int _playerPhotographId;
+ Shape *_playerPhotograph;
+ int _playerSliceModelId;
+ float _playerSliceModelAngle;
+ Graphics::Surface _playerImage;
+ int _timeLast;
ActorDialogueQueueEntry _playerActorDialogueQueue[kPlayerActorDialogueQueueCapacity];
int _playerActorDialogueQueuePosition;
@@ -117,9 +115,11 @@ class KIA {
int _pogoPos;
- byte *_thumbnail;
+ Graphics::Surface _thumbnail;
public:
+ bool _forceOpen;
+
KIALog *_log;
KIAScript *_script;
KIAShapes *_shapes;
@@ -147,6 +147,7 @@ public:
void playActorDialogue(int actorId, int sentenceId);
void playSliceModel(int sliceModelId);
void playPhotograph(int photographId);
+ void playImage(const Graphics::Surface &image);
private:
static void mouseDownCallback(int buttonId, void *callbackData);
diff --git a/engines/bladerunner/ui/kia_section_load.cpp b/engines/bladerunner/ui/kia_section_load.cpp
new file mode 100644
index 0000000000..ba746cab3b
--- /dev/null
+++ b/engines/bladerunner/ui/kia_section_load.cpp
@@ -0,0 +1,163 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "bladerunner/ui/kia_section_load.h"
+
+#include "bladerunner/audio_player.h"
+#include "bladerunner/bladerunner.h"
+#include "bladerunner/game_info.h"
+#include "bladerunner/savefile.h"
+#include "bladerunner/text_resource.h"
+#include "bladerunner/ui/kia.h"
+#include "bladerunner/ui/kia_shapes.h"
+#include "bladerunner/ui/ui_container.h"
+#include "bladerunner/ui/ui_scroll_box.h"
+
+#include "common/error.h"
+#include "common/system.h"
+
+#include "engines/savestate.h"
+
+namespace BladeRunner {
+
+KIASectionLoad::KIASectionLoad(BladeRunnerEngine *vm) : KIASectionBase(vm) {
+ _uiContainer = new UIContainer(_vm);
+ _scrollBox = new UIScrollBox(_vm, scrollBoxCallback, this, 1025, 0, true, Common::Rect(155, 158, 461, 346), Common::Rect(506, 160, 506, 350));
+ _uiContainer->add(_scrollBox);
+}
+
+KIASectionLoad::~KIASectionLoad() {
+ _uiContainer->clear();
+ delete _scrollBox;
+ delete _uiContainer;
+}
+
+void KIASectionLoad::open() {
+ _scheduledSwitch = false;
+ _scrollBox->show();
+ _scrollBox->clearLines();
+
+ SaveStateList saveList = SaveFileManager::list(_vm->getTargetName());
+
+ _saveSlotMax = -1;
+
+ if (!saveList.empty()) {
+ _scrollBox->addLine(_vm->_textOptions->getText(36), -1, 4); // Load game:
+ for (Common::Array<SaveStateDescriptor>::iterator save = saveList.begin(); save != saveList.end(); save++) {
+ _scrollBox->addLine(save->getDescription(), save->getSaveSlot(), 0);
+ _saveSlotMax = MAX(_saveSlotMax, save->getSaveSlot());
+ }
+ _scrollBox->addLine("", -1, 4);
+ }
+
+
+ _scrollBox->addLine(_vm->_textOptions->getText(37), -1, 4); // New game:
+ _scrollBox->addLine(_vm->_textOptions->getText(20), _saveSlotMax + 1, 0); // Easy
+ _scrollBox->addLine(_vm->_textOptions->getText(28), _saveSlotMax + 2, 0); // Medium
+ _scrollBox->addLine(_vm->_textOptions->getText(29), _saveSlotMax + 3, 0); // Hard
+
+ _hoveredSaveSlot = -1;
+ _timeLast = _vm->getTotalPlayTime();
+ _timeLeft = 800;
+}
+
+void KIASectionLoad::close() {
+ _scrollBox->hide();
+
+ _vm->_kia->playerReset();
+}
+
+void KIASectionLoad::draw(Graphics::Surface &surface){
+ _vm->_kia->_shapes->get(69)->draw(surface, 501, 123);
+
+ _uiContainer->draw(surface);
+
+ int selectedSaveSlot = _scrollBox->getSelectedLineData();
+
+ if (_hoveredSaveSlot != selectedSaveSlot) {
+ if (selectedSaveSlot >= 0) {
+ if (_timeLeft == 0) {
+ SaveStateDescriptor desc = SaveFileManager::queryMetaInfos(_vm->getTargetName(), selectedSaveSlot);
+ const Graphics::Surface *thumbnail = desc.getThumbnail();
+ if (thumbnail != nullptr) {
+ _vm->_kia->playImage(*thumbnail);
+ }
+ }
+ } else {
+ _vm->_kia->playerReset();
+ _timeLeft = 800;
+ }
+ _hoveredSaveSlot = selectedSaveSlot;
+ }
+
+ uint32 now = _vm->getTotalPlayTime();
+ if (selectedSaveSlot >= 0) {
+ if (_timeLeft) {
+ uint32 timeDiff = now - _timeLast;
+ if (timeDiff >= _timeLeft) {
+ SaveStateDescriptor desc = SaveFileManager::queryMetaInfos(_vm->getTargetName(), selectedSaveSlot);
+ const Graphics::Surface *thumbnail = desc.getThumbnail();
+ if (thumbnail != nullptr) {
+ _vm->_kia->playImage(*thumbnail);
+ }
+ } else {
+ _timeLeft -= timeDiff;
+ }
+ }
+ }
+
+ _timeLast = now;
+}
+
+void KIASectionLoad::handleMouseMove(int mouseX, int mouseY) {
+ _uiContainer->handleMouseMove(mouseX, mouseY);
+}
+
+void KIASectionLoad::handleMouseDown(bool mainButton) {
+ _uiContainer->handleMouseDown(!mainButton);
+}
+
+void KIASectionLoad::handleMouseUp(bool mainButton) {
+ _uiContainer->handleMouseUp(!mainButton);
+}
+
+void KIASectionLoad::scrollBoxCallback(void *callbackData, void *source, int lineData, int mouseButton) {
+ KIASectionLoad *self = (KIASectionLoad *)callbackData;
+
+ if (mouseButton == 0 && source == self->_scrollBox && lineData >= 0) {
+ if (lineData == self->_saveSlotMax + 1) {
+ self->_vm->newGame(0);
+ } else if (lineData == self->_saveSlotMax + 2) {
+ self->_vm->newGame(1);
+ } else if (lineData == self->_saveSlotMax + 3) {
+ self->_vm->newGame(2);
+ } else {
+ self->_vm->loadGameState(lineData);
+ }
+
+ self->_vm->_audioPlayer->playAud(self->_vm->_gameInfo->getSfxTrack(513), 90, 0, 0, 50, 0);
+ self->_vm->_kia->resume();
+ self->_scheduledSwitch = true;
+ }
+}
+
+} // End of namespace BladeRunner
diff --git a/engines/bladerunner/ui/kia_section_load.h b/engines/bladerunner/ui/kia_section_load.h
index 4cff04d2c4..040fc090cc 100644
--- a/engines/bladerunner/ui/kia_section_load.h
+++ b/engines/bladerunner/ui/kia_section_load.h
@@ -25,13 +25,49 @@
#include "bladerunner/ui/kia_section_base.h"
+#include "common/scummsys.h"
+#include "common/str.h"
+
+namespace Graphics {
+struct Surface;
+}
+
namespace BladeRunner {
+class UIContainer;
+class UIScrollBox;
+
class KIASectionLoad : public KIASectionBase {
+ struct Save {
+ Common::String name;
+ int slotNum;
+ };
+
+ UIContainer *_uiContainer;
+ UIScrollBox *_scrollBox;
+
+ uint32 _timeLast;
+ uint32 _timeLeft;
+
+ int _hoveredSaveSlot;
+ int _saveSlotMax;
+
public:
- KIASectionLoad(BladeRunnerEngine *vm): KIASectionBase(vm){}
+ KIASectionLoad(BladeRunnerEngine *vm);
+ ~KIASectionLoad();
+
+ void open();
+ void close();
+
+ void draw(Graphics::Surface &surface);
+
+ void handleMouseMove(int mouseX, int mouseY);
+ void handleMouseDown(bool mainButton);
+ void handleMouseUp(bool mainButton);
+private:
+ static void scrollBoxCallback(void *callbackData, void *source, int lineData, int mouseButton);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/ui/ui_container.cpp b/engines/bladerunner/ui/ui_container.cpp
index 78097a9d3d..e84809d379 100644
--- a/engines/bladerunner/ui/ui_container.cpp
+++ b/engines/bladerunner/ui/ui_container.cpp
@@ -27,7 +27,7 @@
namespace BladeRunner {
void UIContainer::draw(Graphics::Surface &surface) {
-for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); component++) {
+ for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); component++) {
(*component)->draw(surface);
}
}
@@ -39,19 +39,19 @@ void UIContainer::handleMouseMove(int mouseX, int mouseY) {
}
void UIContainer::handleMouseDown(bool alternateButton) {
-for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); component++) {
+ for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); component++) {
(*component)->handleMouseDown(alternateButton);
}
}
void UIContainer::handleMouseUp(bool alternateButton) {
-for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); component++) {
+ for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); component++) {
(*component)->handleMouseUp(alternateButton);
}
}
void UIContainer::handleKeyUp(const Common::KeyState &kbd) {
-for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); component++) {
+ for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); component++) {
(*component)->handleKeyUp(kbd);
}
}