BLADERUNNER: Add in-game loading screen

It is also possible to start new game from it.
This commit is contained in:
Peter Kohaut 2018-11-25 21:47:00 +01:00
parent 0d8834b561
commit cfb46da90c
13 changed files with 347 additions and 117 deletions

View File

@ -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 < 480; y += 8) {
for (int x = 0; x < 640; x += 8) {
*dstPixels = *(const uint16 *)_surfaceFront.getBasePtr(x, y);
++dstPixels;
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);
*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);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 {
public:
KIASectionLoad(BladeRunnerEngine *vm): KIASectionBase(vm){}
struct Save {
Common::String name;
int slotNum;
};
UIContainer *_uiContainer;
UIScrollBox *_scrollBox;
uint32 _timeLast;
uint32 _timeLeft;
int _hoveredSaveSlot;
int _saveSlotMax;
public:
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

View File

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