From cfb46da90cb045e029153848652bbd166a5c95b6 Mon Sep 17 00:00:00 2001 From: Peter Kohaut Date: Sun, 25 Nov 2018 21:47:00 +0100 Subject: BLADERUNNER: Add in-game loading screen It is also possible to start new game from it. --- engines/bladerunner/ui/kia.cpp | 35 +++--- engines/bladerunner/ui/kia.h | 31 +++--- engines/bladerunner/ui/kia_section_load.cpp | 163 ++++++++++++++++++++++++++++ engines/bladerunner/ui/kia_section_load.h | 38 ++++++- engines/bladerunner/ui/ui_container.cpp | 8 +- 5 files changed, 238 insertions(+), 37 deletions(-) create mode 100644 engines/bladerunner/ui/kia_section_load.cpp (limited to 'engines/bladerunner/ui') 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::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::iterator component = _components.begin(); component != _components.end(); component++) { + for (Common::Array::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::iterator component = _components.begin(); component != _components.end(); component++) { + for (Common::Array::iterator component = _components.begin(); component != _components.end(); component++) { (*component)->handleMouseDown(alternateButton); } } void UIContainer::handleMouseUp(bool alternateButton) { -for (Common::Array::iterator component = _components.begin(); component != _components.end(); component++) { + for (Common::Array::iterator component = _components.begin(); component != _components.end(); component++) { (*component)->handleMouseUp(alternateButton); } } void UIContainer::handleKeyUp(const Common::KeyState &kbd) { -for (Common::Array::iterator component = _components.begin(); component != _components.end(); component++) { + for (Common::Array::iterator component = _components.begin(); component != _components.end(); component++) { (*component)->handleKeyUp(kbd); } } -- cgit v1.2.3